web-dev-qa-db-ja.com

単体テスト(MSTest)を並行して実行する方法は?

テストスイートを並行して実行する方法を探しています。

気がついた .testrunconfig設定。これにより、CPUの数で多重化が可能になります。

1000個のテストを並行して実行したい。これは理にかなっています。Webサービスをテストしているので、テストに費やした時間の90%がサービスの応答を待っているからです。

これをどのように引き出すかについてのアイデアはありますか?テストはVS用に作成されていますが、VSの外部でテストを実行することはできます。

後の編集:Visual Studioテストチームは、VS 2015 Update 1でこれを追加しました。MarkSowulの回答をご覧ください。

55

このページの回答のほとんどは、MSTestがテストを並列化することを言及することを忘れています個別のアセンブリ。ユニットテストを並列化するには、ユニットテストを複数の.dllに分割する必要があります。

しかし!最新バージョン-MSTest V2-now [〜#〜] can [〜#〜] parallelize "in-Assembly"(はい!)テストプロジェクトにいくつかのnugetパッケージをインストールするだけです-TestFrameworkおよびTestAdapter-ここで説明されているように https://blogs.msdn.Microsoft.com/devops/2018/01/30/mstest-v2-in-Assembly-parallel-test-execution/

そして、これをテストプロジェクトに追加するだけです

[Assembly: Parallelize(Workers = 4, Scope = ExecutionScope.ClassLevel)]

編集:テストメソッドで[DoNotParallelize]を使用して、特定のテストの並列実行を無効にすることもできます。

25
Alex

メソッド Visual Studio Team Test Blogから を使用すると、最大5つ取得できます。

MSTestは各テストを完全には分離しないため、これを使用すると同時実行の問題が発生する可能性があることに注意してください(たとえば、一度実行するコードを面白くするなどの静的な影響があります)。

(制限が5である理由はわかりませんが、parallelTestCountが5を超える値に設定されている場合、MSTestはそれらを並行して実行しません。以下のコメントによると、このルールはVisual Studio 2013で明らかに変更されます)

29
Rangoric

Visual Studio 2015 Update 1はこれを追加します。 https://docs.Microsoft.com/visualstudio/releasenotes/vs2015-update1-vs#misc

更新2の場合、テストエクスプローラーペインの上部のツールバーに(「グループ化」ボックスと「検索」ボックスの間に)UIトグルボタンがあります。

Update 1の場合、.runsettingsで次を設定します

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

MaxCpuCountの値のセマンティクスは次のとおりです。

•「n」(1 <= n <=コアの数):最大「n」個のプロセスが起動されます。

•その他の値の「n」:起動されるプロセスの数は、マシンで使用可能なコアと同じ数になります。

21
Mark Sowul

私が見つけたのは、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

8
Igor

上記の答えは間違いなく私にとって物事を明確にするのに役立ちましたが、ジョン・ケルナーのブログからのこの点: https://johnkoerner.com/vs2015/parallel-test-execution-in-visual-studio-2015-update-1 -might-not-be-what-you-expect / は、欠落していたビットでした。

「並列テストの実行は、マシンで利用可能なコアを活用し、利用可能な各コアでテスト実行エンジンを個別のプロセスとして起動し、コンテナ(アセンブリ、DLL、または実行するテストを含む関連アーティファクト)を渡すことで実現されます。実行するテストの価値。」

->「個別のコンテナビットは欠けていた部分です。テストを並行して実行するには、テストを個別のテストアセンブリに分割する必要がありました。その後、異なるアセンブリのテストを確認しました並行して実行されていました。」

そのため、VSTSで便利な「並行実行」フラグを使用してテストを並行して実行しましたが、それだけでは不十分で、テストを個別のテストプロジェクトに分割する必要がありました。もちろん、論理的にグループ化された、とんでもないプロジェクトごとのプロジェクトではありません

5
JPThorne
  1. DataTableの最初の列が一意のIDであることを確認してください。
  2. DataRowを受け入れ、何も返さないAsyncExecutionTaskデリゲートを作成します。
  3. DataRowおよびAsyncExecutionTaskデリゲートを受け入れるAsyncExecutionContextメソッドを使用して、静的クラス(ParallelTesting)を作成します。
  4. 静的クラスで、静的BatchStartedプロパティを追加します。
  5. 静的クラスで、静的AsyncExecutionTests辞書プロパティを追加します。
  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クラスをクリーンアップすることもできます。

仕組み:テストロジックはラムダでラップされ、最初に呼び出された(最初の行が実行された)ときにテストデータの各行に対して一度ロジックを実行する静的クラスに渡されます。静的クラスへの連続した呼び出しは、事前に開始されたテストタスクが完了するのを待つだけです。

このようにして、TestMethodに対して行われたテストフレームワークの各呼び出しは、既に実行された対応するテストのテスト結果を単に収集します。

可能な改善:

  • AsyncExecutionContextがmaxSynchronousTasksパラメーターを取るようにします。
  • フレームワークがアンマネージコード全体で完全なスタックトレースを移動する方法を調べて、スタックトレースを再スローおよび破棄せずにTask.ExceptionをVisual Studioテストフレームワークに渡すことができるかどうかを確認します。
1
N-ate