38

我正在尋找並行運行測試套件的方法。如何並行運行單元測試(MSTest)?

我知道.testrunconfig設置。這可以讓你多路複用的CPU數量。

我想並行運行1000個測試。這是有道理的,因爲我正在測試一個Web服務,所以在測試中花費的時間有90%等待服務響應。

關於如何解決這個問題的任何想法?測試是爲VS編寫的,但我願意在VS之外運行它們。

稍後編輯:Visual Studio測試團隊在VS 2015 Update 1中添加了此項。請參閱Mark Sowul的答案。

+0

您在這裏談論1000個主題。 – 2010-10-12 16:53:46

+0

對,我想知道是否有一個預生成框架來管理這個。或者如果有人構建自己的框架。 – 2010-10-12 17:13:10

+2

你需要一個負載模擬器。 MSTest並不意味着用作負載測試。 1000線程瘋狂的方式,你需要做的是看看不同的測試技術,這是超出單元測試的界限。 – Aren 2010-10-12 17:47:49

回答

20

Visual Studio 2015 Update 1增加了這一點。 https://www.visualstudio.com/en-us/news/releasenotes/vs2015-update1-vs#a-idmisc-a-miscellaneous

對於更新2,在測試資源管理器窗格頂部的工具欄中(在「分組」和「搜索」框之間)有一個UI切換按鈕。

對於更新1,設置在.runsettings

<?xml version="1.0" encoding="utf-8"?> 
<RunSettings> 
    <RunConfiguration> 
    <MaxCpuCount>0</MaxCpuCount> 
    </RunConfiguration> 
</RunSettings> 

爲MaxCpuCount的值具有以下語義如下:

• 'n' 個(其中1 < = N < =數):將啓動up to'n'進程。

•任何其他值的「n」:啓動的進程數將與機器上的可用內核數一樣多。

+2

我們有數百個測試的測試DLL,有些可以並行運行,有些則不能。有沒有一種方法來歸因安全和不安全的測試類/方法?我通常希望選擇一個或多個這些巨大的DLL並讓它翻轉。 – GilesDMiddleton 2016-04-05 14:23:50

+2

要記住的一件事是,並行性是在課堂上而不是在測試水平上。我沒有看到內置的方式去做你想做的事,但你可以自己做,例如並在'ClassInitialize' /'ClassCleanup'中命名爲Mutexes。不幸的是,最終可能會有那些暫時阻止並行的測試(例如,所有四個'並行測試'都是使用互斥鎖的測試),但是我認爲你可以得到這個結果。 – 2016-04-05 14:58:52

+4

測試在容器級別進行並行化(在C#的情況下,這是Assembly),所以它將並行運行來自不同程序集的測試。新模型中依次執行相同裝配中的測試。 – jessehouwing 2016-05-09 11:59:07

27

你可以得到高達5使用方法from the Visual Studio Team Test Blog

請記住,有可能是使用這種併發問題,如MSTest的不完全隔離每個測試(靜結轉,例如,使事情代碼有意運行一次)。

(不知道爲什麼限制爲5,但如果parallelTestCount設置爲5個以上。按照下面的評論MSTest的不平行運行它們,這條規則顯然與Visual Studio 2013的變化)

+0

是的,剛剛發現,困難的方式:) - 我跑我的套件在8核心和所有測試被中止... – 2010-11-04 15:23:01

+0

它不應該總共被限制爲5次,而是5次掛起測試。 Bruce Taimana的評論是:「如果清理」掛起「或者花太長時間,我們會讓它繼續清理,但我們會同時開始下一個測試,如果達到5次」掛起「測試,我們會中止。閱讀整個評論[這裏](http://blogs.msdn.com/b/vstsqualitytools/archive/2009/12/01/executing-unit-tests-in-parallel-on-a-multi-cpu-core- machine.aspx#10091555)。 – Anttu 2013-03-20 05:59:03

+0

@Anttu我希望看到一個解決方案設置爲一次運行5個以上,並讓它實際運行它們而不是失敗。每次嘗試超過5個設置時,它都會失敗。也許吊死的時間被認爲太小?我不知道。 – Rangoric 2013-03-20 13:24:39

8

什麼我發現C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ Common7 \ IDE \ CommonExtensions \ Microsoft \ TestWindow \ vstest.console.exe 將與.testsettings文件運行並行測試,如下所示:

<?xml version="1.0" encoding="UTF-8"?> 
<TestSettings name="TestSettings1" id="21859d0f-7bdc-4165-b9ad-05fc803c9ee9" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010"> 
    <Description>These are default test settings for a local test run.</Description> 
    <Deployment enabled="false" /> 
    <Execution parallelTestCount="8"> 
    <TestTypeSpecific> 
     <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b"> 
     <AssemblyResolution> 
      <TestDirectory useLoadContext="true" /> 
     </AssemblyResolution> 
     </UnitTestRunConfig> 
    </TestTypeSpecific> 
    <AgentRule name="Execution Agents"> 
    </AgentRule> 
    </Execution> 
</TestSettings> 

參考可以在這裏找到http://msdn.microsoft.com/en-us/library/vstudio/jj155796.aspx

+1

如果在Visual Studio中使用'Test Explorer',它也可以。你只需要選擇''testsettings''配置'parallelTestCount'。更多細節在這裏:http://ardalis.com/run-your-unit-tests-in-parallel-to-maximize-performance順便說一下:選擇'.testsettings',點擊VS 2013中的'TEST'菜單然後「測試設置=>選擇測試設置文件」。 – 2014-07-17 22:47:39

+0

我從來沒有見過這樣的野獸。 2013年,我必須創建自己的測試設置文件(在解決方案級別添加項目),然後按照Igor的說明對其進行修改以獲得並行支持。 – 2014-08-04 18:43:03

4

上面的答案肯定有助於爲我澄清事情,但是,這一點來自John Koerner的博客:https://johnkoerner.com/vs2015/parallel-test-execution-in-visual-studio-2015-update-1-might-not-be-what-you-expect/就是我們錯過的一點。

「並行測試執行利用了機器上可用的內核,並且通過在每個可用內核上啓動測試執行引擎作爲一個獨立的進程並將其交給容器(包含測試的程序集,DLL或相關工件執行),值得執行的測試。「

- >」單獨的容器位是我失蹤的一塊。爲了讓我的測試並行運行,我需要將我的測試分解爲單獨的測試程序集。 「

所以是的,我們通過使用他們方便的'平行運行'標誌使得VSTS在VSTS中並行運行,但它不是夠了,我們不得不分割我們的測試成單獨的測試項目。邏輯分組,當然,不是一個項目,每測試這將是可笑的

0
  1. 確保在您的DataTable中的第一列是一個唯一的ID。
  2. 創建一個接受DataRow的AsyncExecutionTask委託並返回任何內容
  3. 創建一個靜態類(ParallelTestin g)使用接受DataRow和AsyncExecutionTask委託的AsyncExecutionContext方法。
  4. 在靜態類中添加一個靜態BatchStarted屬性。
  5. 在靜態類中添加一個靜態的AsyncExecutionTests Dictionary屬性。
  6. 在AsyncExecutionContext方法添加以下內容:

    public static void AsyncExecutionContext(DataRow currentRow, AsyncExecutionTask test) 
    { 
        if(!BatchStarted) 
        { 
         foreach(DataRow row in currentRow.Table) 
         { 
          Task testTask = new Task(()=> { test.Invoke(row); }); 
          AsyncExecutionTests.Add(row[0].ToString(), testTask); 
          testTask.Start(); 
         } 
         BatchStarted = true; 
        } 
        Task currentTestTask = AsyncExecutionTests[row[0].ToString()]; 
        currentTestTask.Wait(); 
        if(currentTestTask.Exception != null) throw currentTestTask.Exception; 
    } 
    
  7. 現在使用的類,像這樣:

    [TestMethod] 
    public void TestMethod1() 
    { 
        ParallelTesting.AsyncExecutionContext(TestContext.DataRow, (row)=> 
         { 
          //Test Logic goes here. 
         } 
        ); 
    } 
    

注:你將不得不做例外一些修修補補讓他們正確地冒泡(你可能在這裏有一個聚合異常,你需要第一個例外)。顯示每個測試執行所花費的時間將不再準確。最後一行完成後,您還需要清理ParallelTesting類。

工作原理:測試邏輯包裝在一個lambda中,並傳遞給一個靜態類,它將在第一次調用時爲每一行測試數據執行一次邏輯。連續調用靜態類只需等待預啓動的測試任務完成。

這樣每次調用測試框架對TestMethod所做的簡單收集已經運行的相應測試的測試結果。

可能的改進:

  • 製作AsyncExecutionContext採取maxSynchronousTasks參數。
  • 研究框架如何移動跨非託管代碼的完整堆棧跟蹤,以查看是否可以將Task.Exception傳遞給Visual Studio測試框架,而不會重新拋出和銷燬堆棧跟蹤。