[英]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.