繁体   English   中英

在MSTest中,如何指定某些测试方法不能彼此并行运行?

[英]In MSTest, how can I specify that certain test methods cannot be run in parallel with each other?

我有大量的集成测试可以测试网站服务器。 这些测试大多数都可以并行运行。 但是,我有一些更改设置,并且在并行运行时会导致彼此失败。

举一个简化的例子,假设我进行了以下测试:

TestPrice_5PercentTax
TestPrice_10PercentTax
TestPrice_NoTax
TestInventory_Add10Items
TestInventory_Remove10Items

库存测试不会互相影响,也不会受到价格测试的影响。 但价格测试将改变Tax设置,因此,如果同时510并行运行, 10最终可能会改变之前的设置5完成后,和5 ,因为它看到的5%,预计10%的税,而不是将失败。

我想为这三种价格测试定义一个类别,并说它们可能不会同时运行。 它们可以与任何其他测试同时运行,但不能与其他价格测试同时运行。 有没有办法在MSTest中做到这一点?

MsTest v2具有以下功能

[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)]
// Notice the assembly bracket, this can be compatible or incompatible with how your code is built

namespace UnitTestProject1
{
    [TestClass]
    public class TestClass1
    {
        [TestMethod]
        [DoNotParallelize] // This test will not be run in parallel
        public void TestPrice_5PercentTax() => //YourTestHere?;

        [TestMethod]
        [DoNotParallelize] // This test will not be run in parallel
        public void TestPrice_10PercentTax() => //YourTestHere?;            

        [TestMethod]
        [DoNotParallelize] // This test will not be run in parallel
        public void TestPrice_NoTax() => //YourTestHere?;

        [TestMethod]
        public void TestInventory_Add10Items() => //YourTestHere?;

        [TestMethod]
        public void TestInventory_Remove10Items() => //YourTestHere?;
    }
}

可以在meziantou.net的MSTest v2上找到更多详细信息

我强烈建议至少快速通读该链接,因为这可能会帮助您解决并理解并行或顺序运行测试的问题。

我想提供一个我开始但未追求的潜在解决方案。

首先,我创建了一个可以用作测试方法属性的类。

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple =true)]
public class NoParallel : Attribute
{
    public NoParallel(string nonParallelGroupName)
    {
        SetName = nonParallelGroupName;
    }

    public string SetName { get; }
}

然后,我将其添加到将要冲突的测试方法中。

[NoParallel("Tax")]
public void TestPrice_5PercentTax();

[NoParallel("Tax")]
public void TestPrice_10PercentTax();

[NoParallel("Tax")]
public void TestPrice_NoTax();

// This test doesn't care
public void TestInventory_Add10Items();

// This test doesn't care
public void TestInventory_Remove10Items();

我给我的测试班一个静态的互斥锁字典,该互斥锁以它们的名称作为键。

private static Dictionary<string, Mutex> exclusiveCategories = new Dictionary<string, Mutex>();

最后,使用助手来获取测试方法具有的所有“ NoParallel”字符串。

public static List<string> NonparallelSets(this TestContext context, ContextHandler testInstance)
{
    var result = new List<string>();

    var testName = context.TestName;
    var testClassType = testInstance.GetType();
    var testMethod = testClassType.GetMethod(testName);

    if (testMethod != null)
    {
        var nonParallelGroup = testMethod.GetCustomAttribute<NoParallel>(true);

        if (nonParallelGroup != null)
        {
            result = nonParallelGroups.Select(x => x.SetName).ToList();
        }
    }

    result.Sort();
    return result;
}

...我设置了TestInitialize和TestCleanup来使具有匹配NoParallel字符串的测试按顺序执行。

[TestInitialize]
public void PerformSetup()
{
    // Get all "NoParallel" strings on the test method currently being run
    var nonParallelSets = testContext.NonparallelSets(this);

    // A test can have multiple "NoParallel" attributes so do this for all of them
    foreach (var setName in nonParallelSets)
    {
        // If this NoParallel set doesn't have a mutex yet, make one
        Mutex mutex;
        if (exclusiveCategories.ContainsKey(setName))
        {
            mutex = exclusiveCategories[setName];
        }
        else
        {
            mutex = new System.Threading.Mutex();
            exclusiveCategories[setName] = mutex;
        }

        // Wait for the mutex before you can run the test
        mutex.WaitOne();
    }
}

[TestCleanup]
public void PerformTeardown()
{
    // Get the "NoParallel" strings on the test method again
    var nonParallelSets = testContext.NonparallelSets(this);

    // Release the mutex held for each one
    foreach (var setName in nonParallelSets)
    {
        var mutex = exclusiveCategories[setName];
        mutex.ReleaseMutex();
    }
}

我们决定不执行此操作,因为这样做确实不值得。 最终,我们决定将无法一起运行的测试放入自己的测试类中,并按照HN的建议将其标记为[DoNotParallelize]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM