Visual Studio ソリューションで Live Unit Testing を有効にすると、テストカバレッジとテストの状態が視覚的に示されます。 また、Live Unit Testing では、コードを変更するたびにテストが動的に実行され、変更によってテストが失敗したときにすぐに通知されます。
Live Unit Testing を使用して、.NET Framework、.NET Core、または .NET 5 以降を対象とするソリューションをテストできます。 このチュートリアルでは、.NET を対象とする単純なクラス ライブラリを作成して Live Unit Testing を使用する方法について説明し、それをテストするために .NET を対象とする MSTest プロジェクトを作成します。
完全な C# ソリューションは、GitHub の MicrosoftDocs/visualstudio-docs リポジトリからダウンロードできます。
[前提条件]
このチュートリアルでは、 .NET デスクトップ開発 ワークロードと共に Visual Studio Enterprise エディションをインストールしている必要があります。
ソリューションとクラス ライブラリ プロジェクトを作成する
まず、単一の .NET クラス ライブラリ プロジェクトである StringLibrary で構成される UtilityLibraries という名前の Visual Studio ソリューションを作成します。
ソリューションは、1 つ以上のプロジェクトのコンテナーにすぎません。 空のソリューションを作成するには、Visual Studio を開き、次の操作を行います。
Visual Studio の最上位メニューから [ファイル>新規作成>Project ] を選択します。
テンプレート検索ボックスに ソリューション を入力し、 空のソリューション テンプレートを選択します。 プロジェクトに UtilityLibraries という名前を付けます。
ソリューションの作成を完了します。
ソリューションを作成したので、文字列を操作するための多数の拡張メソッドを含む StringLibrary という名前のクラス ライブラリを作成します。
ソリューション エクスプローラーで、UtilityLibraries ソリューションを右クリックし、[追加>新しいプロジェクト] を選択します。
テンプレート検索ボックスに クラス ライブラリ を入力し、.NET または .NET Standard を対象とする クラス ライブラリ テンプレートを選択します。 [次へ] をクリックします。
プロジェクトに StringLibrary という名前を付けます。
[ 作成 ] をクリックしてプロジェクトを作成します。
コード エディター内のすべての既存のコードを次のコードに置き換えます。
using System; namespace UtilityLibraries { public static class StringLibrary { public static bool StartsWithUpper(this string s) { if (String.IsNullOrWhiteSpace(s)) return false; return Char.IsUpper(s[0]); } public static bool StartsWithLower(this string s) { if (String.IsNullOrWhiteSpace(s)) return false; return Char.IsLower(s[0]); } public static bool HasEmbeddedSpaces(this string s) { foreach (var ch in s.Trim()) { if (ch == ' ') return true; } return false; } } }StringLibrary には、次の 3 つの静的メソッドがあります。
StartsWithUpperは、文字列が大文字で始まる場合はtrueを返します。それ以外の場合は、falseを返します。StartsWithLowerは、文字列が小文字で始まる場合はtrueを返します。それ以外の場合は、falseを返します。HasEmbeddedSpacesは、文字列に埋め込み空白文字が含まれている場合はtrueを返します。それ以外の場合は、falseを返します。
最上位の Visual Studio メニューから [ Build>Build Solution ] を選択します。 ビルドは成功するはずです。
テスト プロジェクトを作成する
次の手順では、StringLibrary ライブラリをテストする単体テスト プロジェクトを作成します。 次の手順を実行して単体テストを作成します。
ソリューション エクスプローラーで、UtilityLibraries ソリューションを右クリックし、[追加>新しいプロジェクト] を選択します。
テンプレート検索ボックスに 単体テスト を入力し、言語として C# を選択し、.NET テンプレートの MSTest 単体テスト プロジェクト を選択します。 [次へ] をクリックします。
注
Visual Studio 2019 バージョン 16.9 では、MSTest プロジェクト テンプレート名は 単体テスト プロジェクトです。
プロジェクトに StringLibraryTests という名前を付け、[ 次へ] をクリックします。
推奨されるターゲット フレームワークまたは .NET 8 を選択し、次に 、作成を選択します。
注
この入門チュートリアルでは、MSTest テスト フレームワークで Live Unit Testing を使用します。 xUnit テスト フレームワークと NUnit テスト フレームワークを使用することもできます。
単体テスト プロジェクトは、テストしているクラス ライブラリに自動的にアクセスできません。 クラス ライブラリ プロジェクトへの参照を追加して、テスト ライブラリにアクセス権を付与します。 これを行うには、
StringLibraryTestsプロジェクトを右クリックし、[ 追加>プロジェクト参照] を選択します。 [ 参照マネージャー ] ダイアログで、[ ソリューション ] タブが選択されていることを確認し、次の図に示すように StringLibrary プロジェクトを選択します。
テンプレートによって提供される定型単体テスト コードを次のコードに置き換えます。
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using UtilityLibraries; namespace StringLibraryTest { [TestClass] public class UnitTest1 { [TestMethod] public void TestStartsWithUpper() { // Tests that we expect to return true. string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsTrue(result, $"Expected for '{word}': true; Actual: {result}"); } } [TestMethod] public void TestDoesNotStartWithUpper() { // Tests that we expect to return false. string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsFalse(result, $"Expected for '{word}': false; Actual: {result}"); } } [TestMethod] public void DirectCallWithNullOrEmpty() { // Tests that we expect to return false. string[] words = { String.Empty, null }; foreach (var word in words) { bool result = StringLibrary.StartsWithUpper(word); Assert.IsFalse(result, $"Expected for '{(word == null ? "<null>" : word)}': " + $"false; Actual: {result}"); } } } }ツール バーの [保存 ] アイコンを選択して、プロジェクトを保存します。
単体テスト コードには ASCII 以外の文字がいくつか含まれているため、既定の ASCII 形式でファイルを保存すると一部の文字が失われることを警告する次のダイアログが表示されます。
[ その他のエンコードで保存] ボタンを選択します。
[保存オプションの詳細設定] ダイアログの [エンコード] ドロップダウン リストで、次の図に示すように Unicode (UTF-8 (署名なし) - Codepage 65001 を選択します。
最上位の Visual Studio メニューから [Build>Rebuild Solution ] を選択して、単体テスト プロジェクトをコンパイルします。
クラス ライブラリと、それに対するいくつかの単体テストを作成しました。 これで、Live Unit Testing を使用するために必要な前提条件が完了しました。
Live Unit Testing を有効にする
ここまでは、StringLibrary クラス ライブラリのテストを記述しましたが、実行していません。 Live Unit Testing は、有効にすると自動的に実行されます。 これを行うには、次の操作を行います。
必要に応じて、StringLibrary のコードを含むコード エディター ウィンドウを選択します。 これは、C# プロジェクトの Class1.cs か、Visual Basic プロジェクトの Class1.vb です。 (この手順では、Live Unit Testing を有効にした後、テストの結果とコード カバレッジの範囲を視覚的に検査できます)。
最上位の Visual Studio メニューから [ テスト>Live Unit Testing>Start を選択します。
リポジトリ ルートにユーティリティ プロジェクトとテスト プロジェクトの両方のソース ファイルへのパスが含まれていることを確認して、Live Unit Testing の構成を確認します。 [ 次へ ] を選択し、[ 完了] を選択します。
[Live Unit Testing]\(ライブ単体テスト\) ウィンドウで、[ include all tests]\(すべてのテストを含める \) リンクを選択します (または、[ プレイリスト ] ボタン アイコンを選択し、その下にあるすべてのテストを選択する StringLibraryTest を選択します。次に、[ プレイリスト ] ボタンの選択を解除して編集モードを終了します)。
Visual Studio によってプロジェクトがリビルドされ、Live Unit Test が開始され、すべてのテストが自動的に実行されます。
テストの実行が完了すると、 Live Unit Testing によって、全体的な結果と個々のテストの結果の両方が表示されます。 さらに、コード エディター ウィンドウには、テスト コード カバレッジとテストの結果の両方がグラフィカルに表示されます。 次の図に示すように、3 つのテストすべてが正常に実行されています。 また、テストが StartsWithUpper メソッド内のすべてのコード パスをカバーしていること、およびそれらのテストがすべて正常に実行されたことを示しています (これは緑色のチェック マーク "✓" で示されます)。 最後に、StringLibrary の他のどのメソッドもコード カバレッジを持たないことを示しています (青い行 "➖"で示されます)。
また、コード エディター ウィンドウで特定のコード カバレッジ アイコンを選択して、テスト カバレッジとテスト結果に関する詳細情報を取得することもできます。 この詳細を調べるには、次の操作を行います。
if (String.IsNullOrWhiteSpace(s))メソッドのStartsWithUpperを読み取る行の緑色のチェック マークをクリックします。 次の図に示すように、Live Unit Testing は、3 つのテストがそのコード行をカバーし、すべてが正常に実行されたことを示しています。
return Char.IsUpper(s[0])メソッドのStartsWithUpperを読み取る行の緑色のチェック マークをクリックします。 次の図に示すように、Live Unit Testing は、そのコード行をカバーするテストが 2 つだけであり、すべてが正常に実行されたことを示しています。
Live Unit Testing で識別される主な問題は、不完全なコード カバレッジです。 これについては、次のセクションで説明します。
テスト カバレッジを拡張する
このセクションでは、単体テストを StartsWithLower メソッドに拡張します。 その間、Live Unit Testing はコードのテストを動的に続行します。
コード カバレッジを StartsWithLower メソッドに拡張するには、次の操作を行います。
次の
TestStartsWithLowerメソッドとTestDoesNotStartWithLowerメソッドをプロジェクトのテスト ソース コード ファイルに追加します。// Code to add to UnitTest1.cs [TestMethod] public void TestStartsWithLower() { // Tests that we expect to return true. string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство" }; foreach (var word in words) { bool result = word.StartsWithLower(); Assert.IsTrue(result, $"Expected for '{word}': true; Actual: {result}"); } } [TestMethod] public void TestDoesNotStartWithLower() { // Tests that we expect to return false. string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва", "1234", ".", ";", " "}; foreach (var word in words) { bool result = word.StartsWithLower(); Assert.IsFalse(result, $"Expected for '{word}': false; Actual: {result}"); } }DirectCallWithNullOrEmptyメソッドの呼び出しの直後に次のコードを追加して、Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalseメソッドを変更します。// Code to add to UnitTest1.cs result = StringLibrary.StartsWithLower(word); Assert.IsFalse(result, $"Expected for '{(word == null ? "<null>" : word)}': " + $"false; Actual: {result}");Live Unit Testing では、ソース コードを変更すると、新しいテストと変更されたテストが自動的に実行されます。 次の図に示すように、追加した 2 つと変更したテストを含むすべてのテストが成功しています。
StringLibrary クラスのソース コードを含むウィンドウに切り替えます。 Live Unit Testing では、コード カバレッジが
StartsWithLowerメソッドに拡張されていることが示されるようになりました。
場合によっては、 テスト エクスプローラー で成功したテストが淡色表示されることがあります。これは、テストが現在実行中であるか、最後に実行されてからテストに影響を与えるコード変更がないためにテストが再度実行されていないことを示します。
ここまでで、すべてのテストが成功しました。 次のセクションでは、テストエラーを処理する方法について説明します。
テストエラーの処理
このセクションでは、Live Unit Testing を使用してテストの失敗を特定、トラブルシューティング、対処する方法について説明します。 これを行うには、テスト カバレッジを HasEmbeddedSpaces メソッドに拡張します。
テスト ファイルに次のメソッドを追加します。
[TestMethod] public void TestHasEmbeddedSpaces() { // Tests that we expect to return true. string[] phrases = { "one car", "Name\u0009Description", "Line1\nLine2", "Line3\u000ALine4", "Line5\u000BLine6", "Line7\u000CLine8", "Line0009\u000DLine10", "word1\u00A0word2" }; foreach (var phrase in phrases) { bool result = phrase.HasEmbeddedSpaces(); Assert.IsTrue(result, $"Expected for '{phrase}': true; Actual: {result}"); } }次の図に示すように、テストの実行時に、
TestHasEmbeddedSpacesメソッドが失敗したことが Live Unit Testing によって示されます。
ライブラリ コードを表示するウィンドウを選択します。 Live Unit Testing では、コード カバレッジが
HasEmbeddedSpacesメソッドに拡張されました。 また、失敗したテストの対象となる行に赤い "🞩" を追加して、テストの失敗を報告します。HasEmbeddedSpacesメソッド シグネチャを含む行にカーソルを合わせます。 Live Unit Testing では、次の図に示すように、メソッドが 1 つのテストでカバーされていることを報告するツールヒントが表示されます。
失敗した TestHasEmbeddedSpaces テストを 選択します。 Live Unit Testing には、次の図に示すように、すべてのテストの実行やすべてのテストのデバッグなど、いくつかのオプションが用意されています。
[ すべてデバッグ] を選択して、失敗したテストをデバッグします。
Visual Studio は、デバッグ モードでテストを実行します。
このテストでは、配列内の各文字列を
phraseという名前の変数に割り当て、HasEmbeddedSpacesメソッドに渡します。 アサート式が初めてfalseされるときに、プログラムの実行が一時停止し、デバッガーが呼び出されます。Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrueメソッド呼び出しで予期しない値が発生した例外ダイアログを次の図に示します。
さらに、次の図に示すように、失敗したテストのトラブルシューティングに役立つ Visual Studio が提供するすべてのデバッグ ツールを使用できます。
[自動変数] ウィンドウで、
phrase変数の値が配列の 2 番目の要素である "Name\tDescription" であることに注意してください。 テスト メソッドは、この文字列が渡されたときにHasEmbeddedSpacesがtrueを返す必要があります。代わりに、falseを返します。 明らかに、タブ文字である "\t" は埋め込みスペースとして認識されません。[デバッグ>Continue] を選択し、F5 キーを押すか、ツール バーの [続行] ボタンをクリックしてテスト プログラムの実行を続行します。 ハンドルされない例外が発生したため、テストは終了します。 これにより、バグの事前調査に十分な情報が提供されます。
TestHasEmbeddedSpaces(テスト ルーチン) が誤った想定を行ったか、HasEmbeddedSpacesがすべての埋め込みスペースを正しく認識しません。問題を診断して修正するには、
StringLibrary.HasEmbeddedSpacesの方法から始めます。HasEmbeddedSpacesメソッドの比較を見てください。 埋め込みスペースは U+0020 と見なされます。 ただし、Unicode 標準には、その他の空白文字が多数含まれています。 これは、ライブラリ コードで空白文字が正しくテストされていないことを示唆しています。等値比較を、 System.Char.IsWhiteSpace メソッドの呼び出しに置き換えます。
if (Char.IsWhiteSpace(ch))Live Unit Testing では、失敗したテスト メソッドが自動的に再実行されます。
Live Unit Testing では、更新された結果が表示され、コード エディター ウィンドウにも表示されます。