簡體   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