在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
设置,因此如果 5
和 10
运行 并行,10
最终可能会在 5
已完成,而 5
会失败,因为它看到 10% 的税而不是预期的 5%。
我想为三个价格测试定义一个类别,并说它们不能同时运行。他们可以 运行 与任何其他测试同时进行,但不能与其他价格测试同时进行。有没有办法在 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?;
}
}
可以在此处找到更详细的信息MSTest v2 at meziantou.net
我强烈建议至少快速通读 link,因为这可能会帮助您解决和理解并行或顺序测试 运行 的问题。
我想提供一个我开始但没有追求的潜在解决方案。
首先,我制作了一个 class 可以用作我的测试方法的属性。
[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();
我给了我的测试 class 一个由他们的名字作为键的互斥锁的静态字典。
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();
}
}
我们决定不继续这样做,因为它真的不值得付出努力。最终我们决定将不能 运行 的测试拉到他们自己的测试 class 中,并按照 H.N 的建议用 [DoNotParallelize]
标记它们。
我有一大组测试网站服务器的集成测试。大多数这些测试都可以并行 运行。但是,我有一些更改设置并且在 运行 并行时可能导致彼此失败。
作为一个简化的例子,假设我进行了这些测试:
TestPrice_5PercentTax
TestPrice_10PercentTax
TestPrice_NoTax
TestInventory_Add10Items
TestInventory_Remove10Items
库存测试互不干扰,不受价格测试影响。但是价格测试将更改 Tax
设置,因此如果 5
和 10
运行 并行,10
最终可能会在 5
已完成,而 5
会失败,因为它看到 10% 的税而不是预期的 5%。
我想为三个价格测试定义一个类别,并说它们不能同时运行。他们可以 运行 与任何其他测试同时进行,但不能与其他价格测试同时进行。有没有办法在 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?;
}
}
可以在此处找到更详细的信息MSTest v2 at meziantou.net
我强烈建议至少快速通读 link,因为这可能会帮助您解决和理解并行或顺序测试 运行 的问题。
我想提供一个我开始但没有追求的潜在解决方案。
首先,我制作了一个 class 可以用作我的测试方法的属性。
[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();
我给了我的测试 class 一个由他们的名字作为键的互斥锁的静态字典。
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();
}
}
我们决定不继续这样做,因为它真的不值得付出努力。最终我们决定将不能 运行 的测试拉到他们自己的测试 class 中,并按照 H.N 的建议用 [DoNotParallelize]
标记它们。