Live Unit Testing を構成して使用する
アプリケーションの開発中、Live Unit Testing では、影響を受けた単体テストがバックグラウンドで自動的に実行される一方で、結果とコード カバレッジがリアルタイムに表示されます。 コードを変更すると、Live Unit Testing は、既存のテストへの変更の影響と、新しいコードが 1 つ以上の既存のテストによってカバーされているかどうかに関するフィードバックを提供します。 このフィードバックは、バグ修正や新機能を追加する際に単体テストを記述するよう促します。
テストで Live Unit Testing を使用すると、テストの状態に関するデータが保持されます。 保持されたデータを使用することにより、Live Unit Testing では、コード変更に対応して動的にテストを実行しながら、優れたパフォーマンスが提供されます。
Live Unit Testing は、.NET Core または .NET Framework を対象とするプロジェクトの Visual Studio の Enterprise エディションでのみ使用できます。
サポートされるテスト フレームワーク
Live Unit Testing は、次の表に示されている 3 つの一般的な単体テスト フレームワークで動作します。 アダプターやフレームワークのサポートされる最小バージョンも示されています。 単体テスト フレームワークはすべて NuGet.org から入手できます。
テスト フレームワーク | Visual Studio アダプターの最小バージョン | フレームワークの最小バージョン |
---|---|---|
xUnit.net | xunit.runner.visualstudio バージョン 2.2.0-beta3-build1187 | xunit 1.9.2 |
NUnit | NUnit3TestAdapter バージョン 3.5.1 | NUnit バージョン 3.5.0 |
MSTest | MSTest.TestAdapter 1.1.4-preview | MSTest.TestFramework 1.0.5-preview |
古い MSTest に基づくテスト プロジェクトで Microsoft.VisualStudio.QualityTools.UnitTestFramework が参照されていて、新しい MSTest NuGet パッケージに移行したくない場合は、Visual Studio 2019 または Visual Studio 2017 にアップグレードしてください。
場合によっては、Live Unit Testing を動作させるため、プロジェクトによって参照されている NuGet パッケージの明示的な復元が必要になります。 この場合、2 つの選択肢があります。
- ソリューションの明示的なビルドを実行して復元します。 Visual Studio の最上位メニューで [ビルド] > [ソリューションの再ビルド] の順に選択します。
- ソリューション内のパッケージを復元します。 ソリューションを右クリックし、[NuGet パッケージの管理] を選択します。
構成
ソリューションの Live Unit Testing を初めて開始するときに、セットアップ ウィザードを使用して、Live Unit Testing でテストをビルドして実行する方法を構成できます。
Live Unit Testing が停止したら、[Test] > [Live Unit Testing] > [ソリューション用に Live Unit Testing を構成する] でセットアップ ウィザードを開くこともできます。
Live Unit Testing を実行すると、元のリポジトリのコピーであるワークスペースが作成されます。 その後、Live Unit Testing は、Visual Studio で行った保存されていない変更をワークスペースに適用し、ビルドを実行し、テストの実行を行い、最新のコード カバレッジに関するレポートを行います。
ウィザードを使用して最初に構成する必要があるのは、ファイルのコピー先とコピー先です。
リポジトリ ルート
リポジトリ ルートは、Live Unit Testing ワークスペースを作成するためにコピーするフォルダーを指定します。 リポジトリのルート フォルダーである必要があります。つまり、すべてのソース、バイナリ、およびツールが含まれている必要があります。 ソリューション ファイルがリポジトリ ルートの下に存在しない場合は、リポジトリ ルートを変更する必要があります。
ワークスペース ルート
ワークスペース ルートは、Live Unit Testing がリポジトリの複製を保持するフォルダーを指定します。 パスが長すぎることを示す例外に注意してください。 既定では、ルートはホーム フォルダーの下に作成されます。 ただし、一例として、通常、ドライブ C の下にリポジトリを作成する必要がある場合、ワークスペース ルートは C:\lut\Repo のように調整できます。
除外ファイルを指定する
すべてのファイルを Live Unit Testing ワークスペースにコピーする必要はありません。 通常のビルドが Live Unit Testing ビルドに干渉しないように、ビルド中に生成された成果物はコピーから除外する必要があります。 また、通常 nuget restore
のコマンドが Live Unit Testing nuget restore
コマンドに干渉しないようにする必要があります。
既定では、Live Unit Testing では、次の 2 つのファイル パターンのいずれかが除外されます:
- Git リポジトリの場合、gitignore ファイルで 指定されたファイルは Live Unit Testing ワークスペースにコピーされません。
- Git 以外のリポジトリの場合、bin/ や obj などの基本的なフォルダーの一覧は Live Unit Testing ワークスペースにコピーされません。
より複雑なリポジトリの場合は、独自の無視ファイルを指定する必要があります。 ウィザードから <[カスタム]> オプションを選択します。 [次へ] を選択すると、ウィザードの完了後に Live Unit Testing によって作成されるカスタム無視ファイルの内容が表示されます。 lutignore ファイルです。
メモ
Git リポジトリによっては、gitignoreファイルでも無視される Git リポジトリにファイルをチェックインできるため、カスタムの lutignore ファイルが必要です。 カスタム lutignore ファイルがないと、Live Unit Testing はこれらのファイルをコピーしないため、ビルド エラーが発生する可能性があります。
lutignore ファイル構造
lutignore ファイルは gitignore ファイルと同じ形式を使います。 ワークスペースにコピーされないように、ビルド中に生成されたフォルダーまたはファイルに一致するルールが含まれている必要があります。 既定のプロジェクト テンプレートのほとんどは、次の無視ファイルで十分です:
[BB]IN
[OO]BJ
# WILL NOT COPY ANY BIN AND OBJ FOLDERS TO THE LIVE UNIT TESTING WORKSPACE
リポジトリにビルド フォルダーが 1 つある場合は、無視ファイルに代わりにそのフォルダーが一覧表示されます:
[AA]RTIFACTS/
# WILL NOT COPY THE ARTIFACTS FOLDER TO THE LIVE UNIT TESTING WORKSPACE
リポジトリにビルド フォルダーに他のツールが含まれている場合は、一致するパターンのセットでこれらのツールを除外する必要があります:
[AA]RTIFACTS/
![AA]RTIFACTS/TOOLS/
# WILL NOT COPY THE ARTIFACTS FOLDER TO THE LIVE UNIT TESTING WORKSPACE
# HOWEVER IT WILL COPY THE TOOLS SUBFOLDER THAT MIGHT CONTAIN TOOLS AND UTILITIES
ビルド オプション
ウィザードの構成ページの 2 番目の部分では、ビルド オプションを構成します:
- PDB の生成: ビルドを高速化するために、Live Unit Testing ではビルド中に PDB は生成されません。 これらのシンボル ファイルを使用すると、テスト エラーが発生したときにスタック トレースに移動できます。
- 複数の CPU コアを使用してビルドする: 既定では、Live Unit Testing は複数の CPU コアを使用してビルドを実行し、ビルド時間を短縮します。 コンピューターの速度が低下する場合、または複数のプロセッサを使用してソリューションをビルドできない場合は、このオプションを選択しないでください。
テスト実行オプション
ウィザード構成ページの最後の部分では、テスト実行オプションを設定します:
- テスト ケースのタイムアウト: 一部のテストの実行に時間がかかる場合があります。 いずれかのテストが特定の期間を超えると、このフィールドを設定すると自動的に実行が中止されます。 テストは自動的に取り消すことができます。
- 複数のプロセッサを使用: 既定では、Live Unit Testing は複数のプロセッサを使用して実行パフォーマンスを高速化しようとします。 コンピューターの速度が低下する場合、またはソリューションでテストを並列で実行できない場合は、このオプションを選択しないでください。 たとえば、複数のテストが同じファイル パスから書き込み/読み取りを試みると、これらのシナリオが発生する可能性があります。
その他の構成
上位の Visual Studio メニュー バーで [ツール] > [オプション] を選択して Live Unit Testing を構成します。 [オプション] ダイアログの左側のウィンドウで、[Live Unit Testing] を選択します。
Live Unit Testing を有効にすると (「Live Unit Testing の開始、一時停止、停止」を参照)、[テスト] > [Live Unit Testing] > [オプション] を選択して [オプション] ダイアログを開くこともできます。
次の図では、ダイアログで使用できる Live Unit Testing の構成オプションを示します。
次のオプションを構成できます。
ソリューションをビルドしてデバッグするときに Live Unit Testing を一時停止するかどうか。
システムのバッテリ電源が指定したしきい値を下回ったときに Live Unit Testing を一時停止するかどうか。
保持されたデータをすべて削除できるようにする。 これは、Live Unit Testing で予測不能なまたは予期しない動作が発生している場合に便利です。この状態は、保持されたデータが破損していることを表しています。
Live Unit Testing のプロセスが使用できるメモリの最大容量。
Live Unit Testing の [出力] ウィンドウに書き込まれる情報のレベル。
オプションは、ログなし ([なし])、エラー メッセージのみ ([エラー])、エラーと情報メッセージ ([情報]、既定値)、またはすべての詳細 ([詳細]) です。
VS_UTE_DIAGNOSTICS
という名前のユーザーレベル環境変数に 1 の値を代入することで、[Live Unit Testing Output] ウィンドウに詳細な出力を表示することもできます。 Visual Studio を再起動します。Live Unit Testing からファイルに詳細な MSBuild ログ メッセージをキャプチャするには、
LiveUnitTesting_BuildLog
ユーザー レベル環境変数を、ログを格納するファイルの名前に設定します。
Live Unit Testing 用にビルドをカスタマイズする
より複雑なソリューションの場合は、ビルドをさらにカスタマイズする必要がある場合があります。 たとえば、テストの実行中に翻訳ファイルをビルドする必要がない場合があります。 ビルドを高速化するには、Live Unit Testing を使用して翻訳ファイルのビルドを無効にします。 これを行うには、プロジェクト ファイルを操作します。
Live Unit Testing オーバーライドの追加
"標準の" インストルメント化されていないビルドには必要ないインストルメンテーション (Live Unit Testing) 用にビルドするためのカスタム手順がソリューションに必要な場合は、BuildingForLiveUnitTesting
プロパティを調べてビルド前/後のカスタム手順を行うコードを、プロジェクトまたは .targets ファイルに追加できます。
たとえば、次のサンプルを記述して、Live Unit Testing でのみ実行される別のターゲットを追加できます:
<Target Name="GenerateNuGetPackages" BeforeTargets="AfterBuild" Condition="'$(BuildingForLiveUnitTesting)' == 'true'">
<Exec Command='"$(MSBuildThisFileDirectory)..\tools\GenPac" '/>
</Target>
BuildingForLiveUnitTesting
プロパティを使用すると、テスト ビルドに対して実行すべきではない一部のタスクを無効にすることができます。 たとえば、Live Unit Testing は、<RunAnalyzers>false</RunAnalyzers>
を設定してテストのアナライザーを無効にします。
Live Unit Testing のテスト依存関係
テスト実行に必要なすべてのファイルがコピーされていない可能性があります。 Live Unit Testing では、テストを実行する別のフォルダーが作成されます。 この配置により、テストの実行中にビルドを実行できますが、ビルド フォルダーのすべてのファイルがテスト フォルダーにコピーされるわけではありません。
通常は、次の 2 つの理由のいずれかでテストの依存関係を追加します:
- テストは、ソース ツリーの下のファイルに依存します。 たとえば、テストは resx ファイルの内容を調べたり、構成ファイルを読み取ったりします。
- テストは、参照する一部のライブラリに依存します。 たとえば、依存関係として構築された実行可能ファイルをテストで実行します。
メモ
テストの依存関係は、セットアップ ウィザードでリポジトリ ルートとして指定されたディレクトリ内に存在する必要があります。
どちらの場合も、Live Unit Testing では、テストを実行するためにコピーする必要があるファイルの数を最小限に抑えるために、これらのファイルは既定ではコピーされません。 テストの実行に必要な場合は、LiveUnitTestingTestDependency
プロパティを使用してこれらのファイルを明示的に指定する必要があります。 たとえば、次のようなレイアウトがあるとします:
SRC/
CONSOLE_UTILITY/
TEST_PROJECT/
ARTIFACTS/
CONSOLE_UTILITY/NET472/DEBUG/
TEST_PROJECT/NET472/DEBUG/
既定では、Live Unit Testing を使用してこれらのプロジェクトをビルドすると、Artifacts/Test_Project
をテスト フォルダーにコピーするだけです。 ソースまたは console_utility をテスト フォルダーに追加するには、次のサンプルを test_project.csproj
に追加します:
<LiveUnitTestingTestDependency Include=”$(RepoRoot)/Src/ConsoleUtility” />
<LiveUnitTestingTestDependency Include=”$(RepoRoot)/Artifacts/ConsoleUtility/net472/$(Configuration)/</LiveUnitTestingTestDependency” />
開始、一時停止、停止
Live Unit Testing を有効にするには、Visual Studio の最上位メニューから [テスト] > [Live Unit Testing] > [開始] の順に選択します。 Live Unit Testing を有効にすると、[Live Unit Testing] メニューで使用可能なオプションが、[開始] の 1 項目から、[一時停止] と [停止] に変わります。
[一時停止] では、Live Unit Testing が一時的に中断されます。
Live Unit Testing を一時停止すると、カバレッジの視覚化はエディターに表示されませんが、収集されたすべてのデータは保持されます。 Live Unit Testing を再開するには、Live Unit Testing メニューから [続行] を選びます。 Live Unit Testing で、一時停止中に行われたすべての編集を取得するために必要な作業が実行されて、グリフが適切に更新されます。
[停止] では、Live Unit Testing が完全に停止されます。 Live Unit Testing では、収集したすべてのデータが破棄されます。
単体テスト プロジェクトが含まれていないソリューションで Live Unit Testing を開始する場合、Live Unit Testing メニューには [一時停止] と [停止] の各オプションが表示されますが、Live Unit Testing は開始されません。 [出力] ウィンドウには、"このソリューションではサポートされているテスト アダプターが参照されていません..." という内容で始まるメッセージが表示されます。
いつでも、Live Unit Testing を一時停止または完全に停止できます。 たとえば、リファクタリングの途中で、しばらくテストが中断されることがわかっている場合に、これらのアクションを取る場合があります。
テスト プロジェクトとテスト メソッドを含めるか除外する
Live Unit Testing を開始すると、Live Unit Testing ツール ウィンドウが表示され、Live Unit Testing でテストするテストのセットを選択するように求められます。
単体テストの実行に時間がかかる小規模なソリューションの場合は、[すべてのテストを含める] を選択すると、Live Unit Testing ですべてのテストが実行されます。
多くのテスト プロジェクトが含まれるソリューションでは、Live Unit Testing に参加するプロジェクトおよびプロジェクト内の個別メソッドを制御できます。 たとえば、数百のテスト プロジェクトを含むソリューションがある場合、Live Unit Testing に参加する対象のテスト プロジェクト セットを選ぶことができます。
Live Unit Testing の実行対象を選択するには、Live Unit Testing プレイリストを編集します。これは、テスト エクスプローラーのプレイリストと同じように動作する機能です。
Live Unit Testing プレイリストを編集するには、複数の方法があります:
- Live Unit Testing ツール ウィンドウ
- [コード エディター] ウィンドウ
- ソリューション エクスプローラー
- テスト コードでプログラムを使用する
Live Unit Testing は、包含/除外の状態をユーザー設定として保存し、ソリューションを閉じて再び開くときに記憶しています。
Live Unit Testing ツール ウィンドウ
[Live Unit Testing] タブのプレイリスト エディターを使用して、プロジェクト、名前空間、またはクラスを実行に含めたり、実行から除外したりできます。 ツール ウィンドウで [プレイリストの編集] を選択します。
ツリー ビュー要素を選択またはクリアして、テストを含めたり除外したりできます。 たとえば、1 つのテストを確認した場合、Live Unit Testing は変更時にそれを実行します。 クラスを選択すると、そのクラス内のすべてのテストが実行され、そのクラスに追加された新しいテストも実行されます。
[コード エディター] ウィンドウ
テスト メソッドを個別に追加または除外する場合には、コード エディター ウィンドウを使います。 [コード エディター] ウィンドウでテスト メソッドのシグネチャーまたはボディを右クリックし、以下のオプションのいずれかを選択します:
- [Live Unit Testing]>[Include <selected method>] (<選択したメソッド> を含める)
- [Live Unit Testing]>[Exclude <selected method>] (<選択したメソッド> を除外する)
- [Live Unit Testing]>[Exclude All But <selected method>] (<選択したメソッド> 以外をすべて除外する)
ソリューション エクスプローラー
単体テストで個別のプロジェクトを選ぶには、Live Unit Testing を開始した後で次の手順に従います:
- ソリューション全体を除外するには、ソリューション エクスプローラーでソリューションを右クリックし、[Live Unit Testing] > [除外する] の順に選択します。
- 個別のテスト プロジェクトをテストに含めるには、各テスト プロジェクトを右クリックし、[Live Unit Testing] > [含める] の順に選択します。
テスト コードでプログラムを使用する
Live Unit Testing でのカバレッジのレポートからメソッド、クラス、または構造体をプログラムによって除外する場合には、ExcludeFromCodeCoverageAttribute 属性を適用できます。
Live Unit Testing から個別のメソッドを除外するには、次の属性を使用します。
- xUnit:
[Trait("Category", "SkipWhenLiveUnitTesting")]
- NUnit:
[Category("SkipWhenLiveUnitTesting")]
- MSTest:
[TestCategory("SkipWhenLiveUnitTesting")]
Live Unit Testing からテストのアセンブリ全体を除外するには、次の属性を使用します。
- xUnit:
[assembly: AssemblyTrait("Category", "SkipWhenLiveUnitTesting")]
- NUnit:
[assembly: Category("SkipWhenLiveUnitTesting")]
- MSTest:
[assembly: TestCategory("SkipWhenLiveUnitTesting")]
カバレッジの視覚化を表示する
Live Unit Testing を有効にすると、Visual Studio エディターの各コード行が更新されて、記述しているコードが単体テストによってカバーされているかどうか、およびコードをカバーしているテストが合格かどうかが示されます。
次の図では、テストに合格したコード行と不合格のコード行、およびテストでカバーされていないコード行が示されています。 緑色の "✓" の行は、テストに合格することによってのみカバーされます。 赤い "x" の行は、1 つ以上の失敗したテストでカバーされます。 青い "➖" の行は、どのテストでもカバーされません。
Live Unit Testing のカバレッジの視覚化は、コード エディターでコードを変更するとすぐに更新されます。 次の図のように、編集を処理している間、合格、不合格、未カバーのシンボルの下にラウンド タイマーの画像を追加することで、データが最新でないことを示すように視覚化が変更される。
テストの状態に関する情報を取得する
コード ウィンドウの合格または不合格のシンボルをカーソルでポイントすると、その行にヒットしているテストの数を確認できます。 個々のテストの状態を確認するには、記号を選択します。
テストの名前と結果が示されるのに加えて、ヒントを使用するとテストのセットを再実行またはデバッグできます。 ツールヒントで 1 つ以上のテストを選択して、それらのテストのみを実行またはデバッグすることもできます。 このアクションにより、コード ウィンドウから移動することなくテストをデバッグできます。
デバッグ時には、既に設定してあるブレークポイントを確認するためだけでなく、デバッガーによって実行された Assert メソッドで予期しない結果が返されたときにも、プログラムの実行が一時停止します。
ツールヒントで不合格になったテストをポイントすると、展開されて、次の図に示すような不合格に関してさらなる情報が表示されます。 失敗したテストに直接移動するには、ツールヒントでそのテストをダブルクリックします。
失敗したテストに移動すると、次の状態のテストがメソッドのシグネチャで視覚的に示されます:
- 合格 (中身が半分入ったビーカーと緑の "✓" で示されます)。
- 不合格 (中身が半分入ったビーカーと赤の "🞩" で示されます)。
- Live Unit Testing に含まれない (中身が半分入ったビーカーと青い "➖")。
非テスト メソッドはシンボルで識別されません。 次の図では、メソッドの 4 つの種類がすべて示されています。
不合格になったテストの診断と修正
不合格になったテストからは、簡単に製品のコードをデバッグし、編集して、アプリケーションの開発を続けることができます。 Live Unit Testing はバックグラウンドで実行されるため、デバッグ、編集、続行のサイクルの間、Live Unit Testing を停止して再起動する必要はありません。
例えば、前の画像に示したテストの失敗は、アルファベットでない文字は System.Char.IsLower メソッドに渡すと true
を返すというテストメソッドの誤った仮定が原因である。 テスト メソッドを修正した後は、すべてのテストが合格になるはずです。 Live Unit Testing を一時停止または停止する必要はありません。
Live Unit Testing ウィンドウ
Live Unit Testing で提供されるインターフェイスを使用すると、テスト エクスプローラーと同様に、テストを実行してデバッグし、テストの結果を分析することができます。 Live Unit Testing が有効になっていると、テスト エクスプローラーの単体テストの状態はすぐに更新されます。 単体テストを明示的に実行する必要はありません。
Live Unit Testing が有効になっていないか、停止されていると、Live Unit Testing には最後のテスト実行時の単体テストの状態が表示されます。 Live Unit Testing を再開した後、テストを再実行するにはソース コードを変更する必要があります。
Live Unit Testing を開始するには、Visual Studio の上部にあるメニューで [テスト] > [Live Unit Testing] > [開始] の順に選べます。 また、[表示]>[その他のウィンドウ]>[Live Unit Testing ウィンドウ] を使用して、Live Unit Testing ウィンドウを開くこともできます。
[Live Unit Testing] ウィンドウで、一部のテストがフェード アウトしていることがあります。たとえば、Live Unit Testing を停止して再開すると、次の図に示すように、[Live Unit Testing] ウィンドウのすべてのテストがフェード アウトしています。
フェード アウトされたテスト結果は、テストが最新のライブ単体テストの実行に含まれていなかったことを示します。 テストは、テストまたはテストの依存関係に対する変更が検出された場合にのみ実行されます。 変更がない場合は、不必要なテストの実行が回避されます。 この場合、グレー表示されたテスト結果は最新の実行に含まれていなかったものの、"最新の状態" です。
フェードされているテストはどれも、コードを変更すると再実行できます。
Live Unit Testing で自動的にテストを実行してテスト結果を更新するのと、テスト エクスプローラーからテストを明示的に実行するのには、いくつかの違いがあります。 こうした違いには、次のようなものがあります。
- [テスト エクスプローラー] ウィンドウからテストを実行またはデバッグすると、通常のバイナリが実行されます。 Live Unit Testing では、インストルメント化されたバイナリが実行されます。
- Live Unit Testing では、テストを実行するための新しいアプリケーション ドメインは作成されません。 代わりに、既定のドメインからテストを実行します。 [テスト エクスプローラー] ウィンドウからテストを実行すると、新しいアプリケーション ドメインが作成されます。
- Live Unit Testing では、各テスト アセンブリで順番にテストが実行されます。 [テスト エクスプローラー] ウィンドウでは、複数のテストを並列に実行できます。
Live Unit Testing のテスト実行
Live Unit Testing は、コードを変更するたびにテストを実行し続けます。 実行が進行中で、さらにコードを変更すると、Live Unit Testing は最初の実行が完了するまで待機している間に、別の実行をキューに入れます。
ファイルを保存するたびに、Live Unit Testing は最初の実行を取り消し、代わりにキューに登録された実行をすぐにスケジュールします。 このプロセスは、最初の実行の完了に長い時間がかかるシナリオに役立ちます。