Visual Studio テスト タスクを使用して並列でテストを実行する
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
コードに対する変更を検証するテストの実行は、品質を維持するために重要です。 継続的インテグレーションのプラクティスを成功させるには、すべてのビルドで実行される優良なテスト スイートが不可欠です。 ただし、コードベースが大きくなるにつれて、回帰テスト スイートも同様に増大する傾向があり、完全な回帰テストの実行には時間がかかることがあります。 場合によっては、テスト自体の実行時間が長くなることがあります。通常、これはエンドツーエンドのテストを記述する場合に該当します。 このため、パイプラインではビルドを十分な速さで処理できなくなり、顧客価値を提供までに時間がかかるようになります。
テストを並列で実行することは、CI/CD パイプラインの効率を高めるための優れた方法です。 これは、クラウドによって提供される追加のキャパシティを使用することで簡単に実施できます。 この記事では、複数のエージェントを使用することで、テストを並列で実行するように Visual Studio テスト タスクを構成する方法について説明します。
前提条件
エージェントとジョブの概念について詳しく理解します。 複数のジョブを並列で実行するために、複数のエージェントを構成する必要があります。 また、十分な数の並列ジョブも必要です。
テストのスライス
Visual Studio テスト タスク (バージョン 2) は、並列ジョブの設定とシームレスに連携するように設計されています。 Visual Studio テスト タスク (「VSTest タスク」と省略表記します) を含むパイプライン ジョブが複数のエージェントで並列に実行されるように構成されていると、複数のエージェントが関与していることが自動的に検出され、それらのエージェント間で並列に実行できるテスト スライスが作成されます。
このタスクは、テストとエージェントの数、以前のテストの実行時間、アセンブリ内のテストの場所に基づいたバッチ処理など、さまざまな要件に応じたテスト スライスを作成するように構成できます。
これらのオプションについては、次のセクションで説明します。
テスト数とエージェント数に基づいた単純なスライス
この設定では、テスト数「T」をエージェント数「N」で分割する単純なアルゴリズムを使用して、各エージェントが T/N のテストを実行するようにします。 たとえば、テスト スイートに 1000 個のテストが含まれていて、並列ジョブ用に 2 つのエージェントを使用する場合、各エージェントは 500 個のテストを実行するようになります。 また、8 つのエージェントを使用すると、テストの実行にかかる時間をさらに短縮できます。この場合、各エージェントは 125 個のテストを並列で実行します。
通常、このオプションは、すべてのテストの実行時間に大きな差がない場合に使用されます。 テストの実行時間に大きな差があると、一部のエージェントが実行時間が長いテストのスライスを受け取り、別のエージェントは実行時間が短いテストのスライスを受け取る可能性があり、残りのエージェントよりもはるかに早く終了することがあるため、エージェントを効果的に利用できない場合があります。
テストの以前の実行時間に基づいたスライス
この設定では、以前の実行時間を考慮してテストのスライスを作成し、各スライスの実行時間がほぼ同じになるようにします。 実行時間の短いテストはバッチ処理されるようにまとめられ、実行時間の長いテストは個別のスライスに割り当てられます。
このオプションは、アセンブリ内のテストに依存関係がなく、それらを同じエージェントで実行する必要がない場合に使用する必要があります。 このオプションを選択すると、すべてのエージェントが受け取る「作業」の量が同じになり、すべてがほぼ同時に完了するため、エージェントの使用効率が最も高くなります。
テスト アセンブリに基づいたスライス
この設定では、テスト アセンブリ (またはファイル) の数「A」をエージェント数「N」で分割する単純なアルゴリズムを使用して、各エージェントが A/N 個のアセンブリからテストを実行するようにします。 このオプションを使用するときには、アセンブリ内のテストの数は考慮されません。 たとえば、テスト スイートに 10 個のテスト アセンブリが含まれていて、並列ジョブ用に 2 つのエージェントを使用する場合、各エージェントは 5 つのテスト アセンブリを受け取って実行するようになります。 テストにかかる時間は、5 つのエージェントを使用することで、さらに短縮できます。この場合、各エージェントは 2 個のテスト アセンブリを実行します。
このオプションは、アセンブリ内のテストに依存関係がある場合や、テスト コードの状態を管理するためのメソッド AssemblyInitialize
と AssemblyCleanup
、または ClassInitialize
と ClassCleanup
を利用している場合に使用する必要があります。
クラシック ビルド パイプラインで並列でテストを実行する
クラシック ビルド パイプラインで実行する大規模なテスト スイートや実行時間の長い統合テストがある場合は、次の手順を使用します。
注意
オンプレミスの TFS サーバーでビルド パイプラインのマルチエージェント機能を使用するには、TFS 2018 Update 2 以降のバージョンを使用する必要があります。
単一のエージェントを使用してジョブをビルドします。 次の図に示すタスクを使用して、Visual Studio プロジェクトをビルドし、ビルド成果物を発行します。 これは、既定のジョブ設定 (単一エージェント、並列ジョブなし) を使用します。
複数のエージェントを使用して並列でテストを実行します。
エージェント ジョブを追加します
並列で複数のエージェントを使用するように、ジョブを構成します。 この例では、3 つのエージェントを使用します。
ヒント
超並列テストのために、99 個のエージェントを指定できます。
ジョブに [Download Build Artifacts] (ビルド成果物のダウンロード) タスクを追加します。 この手順は、ビルド ジョブとテスト ジョブの間のリンクであり、テスト ジョブで生成されたバイナリが、テスト ジョブによって使用されるエージェントでテストの実行に使用できるようにするために必要です。 タスクが '現在のビルド' によって生成された成果物をダウンロードするように設定されていることと、成果物名がビルド ジョブの [Publish Build Artifacts] (ビルド成果物の発行) タスクで使用される成果物名と同じであることを確認します。
[Visual Studio Test] (Visual Studio テスト) タスクを追加して、そのタスクが必要なスライス戦略を使用するように構成します。
YAML パイプラインでの並列テスト用のジョブの設定
job
で parallel
戦略を指定して、ディスパッチする必要があるジョブの数を示します。 大規模なテスト スイートに向けてテストをスケールアップするために、最大 99 個のエージェントを指定できます。
jobs:
- job: ParallelTesting
strategy:
parallel: 2
詳細については、YAML スキーマ - Job を参照してください。
クラシック ビルド パイプラインでのテストの並列実行
アプリケーションのデプロイ後に実行する大規模なテスト スイートや実行時間の長い機能テストがある場合は、次の手順を使用します。 たとえば、アプリの機能を検証するために、Web アプリケーションをデプロイして、ブラウザーで Selenium テストを実行できます。
注意
オンプレミスの TFS サーバーでリリース パイプラインのマルチエージェント機能を使用するには、TFS 2017 Update 1 以降のバージョンを使用する必要があります。
単一のエージェントを使用してアプリをデプロイします。 「Azure デプロイ: リソース グループの作成または更新」または「Azure App Service Deploy」タスクを使用して、Web アプリを Azure App Services にデプロイします。 これは、既定のジョブ設定 (単一エージェント、並列ジョブなし) を使用します。
複数のエージェントを使用して並列でテストを実行します。
エージェント ジョブを追加します
並列で複数のエージェントを使用するように、ジョブを構成します。 この例では、3 つのエージェントを使用します。
ヒント
超並列テストのために、99 個のエージェントを指定できます。
Visual Studio テスト タスクを実行する前に実行する必要があるその他のタスクを追加します。 たとえば、テストに必要なデータを設定する PowerShell スクリプトを実行します。
ヒント
リリース パイプライン内のジョブは、そのリリース パイプラインにリンクされているすべての成果物を既定でダウンロードします。 時間節約のために、ジョブに必要なテスト成果物のみをダウンロードするようにジョブを構成できます。 たとえば、Web アプリ バイナリは Selenium テストの実行には必要なく、ビルド パイプラインでアプリとテスト成果物が個別に発行される場合、そうしたバイナリのダウンロードはスキップできます。
[Visual Studio Test] (Visual Studio テスト) タスクを追加して、そのタスクが必要なスライス戦略を使用するように構成します。
ヒント
テスト マシンに Visual Studio がインストールされていない場合は、Visual Studio テスト プラットフォーム インストーラー タスクを使用すると、必要なバージョンのテスト プラットフォームを取得できます。
並列パイプライン ジョブと並列テスト実行の組み合わせによる超並列テスト
パイプラインで並列ジョブが使用されていると、各ジョブを並列に実行するために複数のマシン (エージェント) が使用されます。 テスト フレームワークとランナーは、1 台のコンピューターでテストを並列で実行する機能も提供しています。通常は、並列で実行される複数のプロセスまたはスレッドを作成します。 並列処理機能は階層化された方法で組み合わせると、超並列テストを実現できます。 Visual Studio テスト タスクのコンテキストでは、並列処理を次の方法で組み合わせることができます。
テスト フレームワークによって提供される並列処理。 最新のすべてのテスト フレームワーク (MSTest v2、NUnit、xUnit など) は、並列でテストを実行する機能を提供しています。 一般に、アセンブリ内のテストは並列で実行されます。 このようなテスト フレームワークは、テスト アダプターとテスト フレームワークを対応するアダプターと共に使用することで Visual Studio テスト プラットフォームとインターフェイスし、テストの実行時に Visual Studio テスト プラットフォームが作成するテスト ホスト プロセス内で動作します。 そのため、このレイヤーでの並列化は、すべてのフレームワークとアダプターのプロセス内になります。
Visual Studio テスト プラットフォーム (vstest.console.exe) によって提供される並列処理。 Visual Studio テスト プラットフォームでは、テスト アセンブリを並列で実行できます。 vstest.console.exe のユーザーは、これを /parallel スイッチとして認識します。 これは使用可能な各コアでテスト ホスト プロセスを起動し、実行するためにアセンブリ内のテストに渡すことで行われます。 並列化の単位がテスト アセンブリまたはテスト ファイルであるため、これは Visual Studio テスト プラットフォーム用のテスト アダプターを持つフレームワークに対して機能します。 これは、テスト フレームワークによって提供される並列処理 (前述) と組み合わせると、パイプライン内の 1 つのエージェントでテストを実行するときの最大レベルの並列処理を提供します。
Visual Studio テスト (VSTest) タスクによって提供される並列処理。 VSTest タスクは、複数のエージェント (またはマシン) でのテストの並列実行をサポートしています。 テスト スライスが作成され、各エージェントは一度に 1 つのスライスを実行します。 3 つの異なるスライス戦略は、(前述のように) テスト プラットフォームとテスト フレームワークによって提供される並列処理と組み合わせると、次の結果が得られます。
テスト数とエージェント数に基づいたスライス。 等しいサイズのスライスにテストがグループ化される単純なスライス。 1 つのスライスに、1 つ以上のアセンブリからのテストが含まれます。 エージェントでのテストの実行は、上記の 1 と 2 で説明した並列処理に準拠します。
以前の実行時間に基づいたスライス。 以前のテスト実行の測定時間と使用可能なエージェント数に基づいて、各スライスが必要とする実行時間がほぼ等しくなるように、テストをスライスにグループ化します。 1 つのスライスに、1 つ以上のアセンブリからのテストが含まれます。 エージェントでのテストの実行は、上記の 1 と 2 で説明した並列処理に準拠します。
アセンブリに基づいたスライス。 スライスはテスト アセンブリであり、すべて同じアセンブリに属するテストが含まれます。 エージェントでの実行は、上記の 1 と 2 で説明した並列処理に準拠します。 ただし、エージェントが実行するアセンブリを 1 つのみ受け取った場合、2 は発生しないことがあります。
ヘルプとサポート
- トラブルシューティング ページを参照してください。
- Stack Overflow に関するアドバイスを受け取り、Developer Community を介してサポートを受ける