[英]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
设置,因此,如果同时5
和10
并行运行, 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.