.net - 多次重复mstest测试运行

标签 .net mstest

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

有没有一种方法可以配置mstest(最好在“测试列表编辑器”中)多次运行测试?

最佳答案

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

这并不简单,但是一旦一切都设置好,您就可以在项目中重复使用它。我也可以在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));
        }
    }
}

请注意,我们的测试方法接受来自测试循环程序的参数。我还使用数据驱动测试进行了展示,以展示您可以将二者结合在一起以在整个数据集上生成较大的排列。

关于.net - 多次重复mstest测试运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/872669/

相关文章:

C#:为 ListView 项实现 'filter' 机制的最佳方法是什么?

c# - IIS认证中的 "realm"是什么,它和SSL证书参数有什么关系?

exception - 对于 vs2012 中使用 mstest 用 F# 编写的单元测试,如何断言引发异常?

visual-studio-2013 - MStest 中止测试清理

c# - 使用 csla 和 Entity Framework 进行 Visual Studio 2012 测试

c# - 将一个数字加密为另一个相同长度的数字

c# - 避免重新编译表达式树以在生成的委托(delegate)中引用不同的目标(自身)

c# - 创建一个 Web 服务器,用一条简单的消息来响应每个传入的请求

c# - Mstest 测试在测试完成后终止进程

visual-studio-2008 - Visual Studio 2008 测试 View 面板未显示所有测试