多次重复 mstest 测试运行

Posted

技术标签:

【中文标题】多次重复 mstest 测试运行【英文标题】:Repeat mstest test run multiple times 【发布时间】:2009-05-16 15:50:21 【问题描述】:

我的一些 mstest 单元测试有助于检测多线程竞争条件,因此它们在连续运行多次时最有用,但我只想针对特定的测试运行执行此操作 - 并非一直如此。

有没有办法配置 mstest(最好在测试列表编辑器中)以多次运行测试?

【问题讨论】:

【参考方案1】:

我需要做类似的事情,所以我想出了一个解决方案。

这并不简单,但一旦一切就绪,您就可以跨项目重复使用它。我还在 GitHub (https://github.com/johnkoerner/MSTestLooper) 上下载了这段代码,但如果它在某个时候消失,我就是这样做的。

首先,我们创建一个属性,将其应用于我们的类,告诉它多次运行所有测试。在单独的程序集中执行所有这些操作,因为 DLL 需要位于特殊位置。

[Serializable]
public class TestLooperAttribute :  TestClassExtensionAttribute

    private static readonly Uri thisGuy = new Uri("urn:TestLooperAttribute");

    private string _PropertyName;
    public string PropertyName
    
        get
         return _PropertyName; 
        set
        
            _PropertyName = value;
        
    
    public override Uri ExtensionId
    

        get 
            return thisGuy; 
    


        public override TestExtensionExecution GetExecution()
    

        return new TestLooperExecution(PropertyName);
    

接下来我们要创建一个自定义的测试类执行类:

class TestLooperExecution : TestExtensionExecution

    private string PropertyName;

    public TestLooperExecution(string PropertyName)
    
        this.PropertyName = PropertyName;
    

    public override ITestMethodInvoker CreateTestMethodInvoker(TestMethodInvokerContext InvokerContext)
    
        return new TestLooperInvoker(InvokerContext, PropertyName);
    

    public override void Dispose()
    
        //TODO: Free, release or reset native resources
    

    public override void Initialize(TestExecution Execution)
    
        //TODO: Wire up event handlers for test events if needed

    

最后我们添加一个自定义调用器,我们在其中执行循环:

class TestLooperInvoker : ITestMethodInvoker

    private TestMethodInvokerContext m_invokerContext;
    private string PropertyName;

    public TestLooperInvoker(TestMethodInvokerContext InvokerContext, string PropertyName)
    
        m_invokerContext = InvokerContext;
        this.PropertyName = PropertyName;
    

    public TestMethodInvokerResult Invoke(params object[] args)
    

        // Our helper results class to aggregate our test results
        HelperTestResults results = new HelperTestResults();

        IEnumerable<object> objects = m_invokerContext.TestContext.Properties[PropertyName] as IEnumerable<object>;

        foreach (var d in objects)
            results.AddTestResult(m_invokerContext.InnerInvoker.Invoke(d), new object[1]  d.GetType().ToString());

        var output = results.GetAllResults();
        m_invokerContext.TestContext.WriteLine(output.ExtensionResult.ToString());

        return output;
    

HelperTestResults 类只是为输出构建字符串,您可以按照自己的方式处理,我不想包含该代码,因为它只会使这篇文章变得更长。

把它编译成一个DLL然后你需要把它复制到

C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PublicAssemblies

您还必须为该类创建一个注册表项:

Windows Registry Editor Version 5.00 
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\11.0\EnterpriseTools\QualityTools\TestTypes\13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b\TestTypeExtensions\TestLooperAttribute]
"AttributeProvider"="TestLooper.TestLooperAttribute, TestLooper"

现在你已经完成了所有这些,你终于可以使用这个类了:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestLooper;
using System.Collections.Generic;
namespace UnitTestSamples

    [TestLooper(PropertyName="strings")]
    public class UnitTest1
    
        public static List<String> strings = new List<String>();
        private TestContext testContextInstance;

        public TestContext TestContext
        
            get
            
                return testContextInstance;
            
            set
            
                testContextInstance = value;
            
        
        [ClassInitialize()]
        public static void Init(TestContext x)
        
            strings.Add("A");
            strings.Add("B");
            strings.Add("C");
            strings.Add("D");

        

        [TestInitialize()]
        public void TestInit()
        
            if (!TestContext.Properties.Contains("strings"))
            testContextInstance.Properties.Add("strings", strings);
        

        [TestMethod]
        [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "DataDriven1.csv", "DataDriven1#csv", DataAccessMethod.Sequential)]
        [DeploymentItem("DataDriven1.csv")]
        public void TestMethodStrings(string s)

        
            int value1 = Convert.ToInt32(TestContext.DataRow["Col1"]); ;
            TestContext.WriteLine(String.Format("0:1", s, value1));
        
    

请注意,我们的测试方法接受一个来自测试循环器的参数。我还使用数据驱动测试来展示这一点,以表明您可以将两者结合在一起以在您的数据集中生成大的排列。

【讨论】:

我什至不知道 MSTest 有这样的可扩展性。太好了,谢谢!【参考方案2】:
[TestMethod()]
public void RepetableTest()
   for(int i = 0; i < repeatNumber; i++)

     //test code goes here


   

【讨论】:

看到***.com/questions/25565574/…?为什么这并不总能达到所需的结果。【参考方案3】:

考虑创建一个测试来分离几个线程。测试列表不允许您为同一测试拥有多个条目。但是,您可以将多线程测试分配给它自己的列表,并仅在您想要运行该特定测试时调用它。

【讨论】:

这是一个有趣的方法。谢谢。【参考方案4】:

我猜答案是否定的。

【讨论】:

以上是关于多次重复 mstest 测试运行的主要内容,如果未能解决你的问题,请参考以下文章

如果单独运行 MSTest 测试成功,如果与其他测试一起运行则失败

Visual Studio 2015 MSTest 无法运行负载测试

MSTest 运行忽略的测试 (VS2013)

如何使用 mstest 增加单元测试运行的全局超时

有没有办法使用 MSTests 顺序运行单元测试?

针对 Visual Studio 2012 本机 C++ 测试从命令行运行 mstest