この記事では、Visual Studio でユニバーサル Windows プラットフォーム (UWP) アプリを単体テストする方法について説明します。 Visual Studio には、C#、Visual Basic、C++ 用の UWP 単体テスト プロジェクト テンプレートが用意されています。 UWP アプリの開発の詳細については、「UWP アプリ の概要」を参照してください。
この記事では、UWP アプリで C# クラスを作成して単体テストする例について説明します。 この例では 、テスト駆動型開発 を使用して、特定の動作を検証するテストを記述し、テストに合格するコードを記述します。
単体テスト プロジェクトを作成して実行する
次の手順では、UWP アプリの単体テスト プロジェクトを作成して実行する方法について説明します。
UWP 単体テスト プロジェクトを作成する
Visual Studio の [スタート] ウィンドウで、[ 新しいプロジェクトの作成] を選択します。
[ 新しいプロジェクトの作成 ] ページで、[検索] ボックスに 単体テスト を入力します。 テンプレート リストは、単体テスト プロジェクトにフィルターを適用します。
C# または Visual Basic の適切な UWP 単体テスト テンプレートを選択し、[ 次へ] を選択します。
Visual Studio 2022 バージョン 17.14 以降では、C# と .NET 9 の推奨単体テスト テンプレートは UWP 単体テスト アプリ であり、ネイティブ AOT を対象とします。 以前の UWP テンプレートの名前は 、UWP 単体テスト アプリ (.NET ネイティブ) と 単体テスト アプリ (ユニバーサル Windows) です。
必要に応じて、プロジェクトまたはソリューションの名前と場所を変更し、[ 作成] を選択します。
必要に応じて、ターゲットと最小プラットフォームのバージョンを変更し、[ OK] を選択します。
Visual Studio によってテスト プロジェクトが作成され、Visual Studio ソリューション エクスプローラーで開かれます。
Visual Studio の [スタート] ウィンドウで、[ 新しいプロジェクトの作成] を選択します。
[ 新しいプロジェクトの作成 ] ページで、[検索] ボックスに 単体テスト を入力します。 テンプレート リストは、単体テスト プロジェクトにフィルターを適用します。
C# または Visual Basic の 単体テスト アプリ (ユニバーサル Windows) テンプレートを選択し、[ 次へ] を選択します。
必要に応じて、プロジェクトまたはソリューションの名前と場所を変更し、[ 作成] を選択します。
必要に応じて、ターゲットと最小プラットフォームのバージョンを変更し、[ OK] を選択します。
Visual Studio によってテスト プロジェクトが作成され、Visual Studio ソリューション エクスプローラーで開かれます。
プロジェクトのアプリケーション マニフェストを編集する
ソリューション エクスプローラーでPackage.appxmanifest ファイルを右クリックし、[開く] を選択します。
マニフェスト デザイナーで、[ 機能 ] タブを選択します。
機能の一覧で、コードと単体テストに必要な機能を選択します。 たとえば、コードとその単体テストでインターネットにアクセスする必要がある場合は、[ インターネット ] チェック ボックスをオンにします。
単体テストが正しく機能するために必要な機能のみを選択します。
UWP アプリの単体テストにコードを追加する
Visual Studio コード エディターで、単体テスト コード ファイルを編集して、テストに必要なアサートとロジックを追加します。 例については、この記事で後述 する C# クラスの単体テスト を参照してください。
テスト エクスプローラーで単体テストを実行する
ソリューションをビルドし、 テスト エクスプローラーを使用して単体テストを実行します。
Visual Studio の [テスト ] メニューで、[ テスト エクスプローラー] を選択します。 [テスト エクスプローラー] ウィンドウが開きます。
テスト エクスプローラーで、[すべて実行] アイコンを選択します。 UWP プロジェクトでテストを検出するには、[ すべて実行 ] を使用する必要があります。
ソリューションがビルドされ、単体テストが実行されます。 テストの実行後、テストはテスト エクスプローラーの テスト の一覧に表示され、結果と期間に関する情報が表示されます。
テスト エクスプローラーでは、個々のテストを選択し、右クリックしてテストを実行またはデバッグしたり、テストに移動してテスト コードを開いたりすることもできます。 上部のメニューから、テストをグループ化したり、プレイリストにテストを追加したり、テスト オプションを開いたりすることができます。
ソリューションをビルドし、 テスト エクスプローラーを使用して単体テストを実行します。
Visual Studio の [テスト ] メニューで、[ テスト エクスプローラー] を選択します。 [テスト エクスプローラー] ウィンドウが開きます。
テスト エクスプローラーで、[すべて実行] アイコンを選択します。 UWP プロジェクトでテストを検出するには、[ すべて実行 ] を使用する必要があります。
ソリューションがビルドされ、単体テストが実行されます。 テストの実行後、テストはテスト エクスプローラーの テスト の一覧に表示され、結果と期間に関する情報が表示されます。
テスト エクスプローラーでは、個々のテストを選択し、右クリックしてテストを実行またはデバッグしたり、テストに移動してテスト コードを開いたりすることもできます。 上部のメニューから、テストをグループ化したり、プレイリストにテストを追加したり、テスト オプションを開いたりすることができます。
C# クラスの単体テスト
安定した一連の適切な単体テストにより、コードを変更するときにバグを導入していないという確信が高くなります。 次の例では、UWP アプリで C# クラスの単体テストを作成する 1 つの方法について説明します。 この例では 、テスト駆動型開発 を使用して、特定の動作を検証するテストを記述し、テストに合格するコードを記述します。
Maths コード プロジェクトの例では、Rooter クラスは、数値の推定平方根を計算する関数を実装します。 RooterTests プロジェクトの単体テストは、Rooter クラスです。
ソリューションとプロジェクトを作成する
UWP アプリ プロジェクトを作成します。
- Visual Studio の [ ファイル ] メニューで、[ 新しいプロジェクト] を選択します。
- [ 新しいプロジェクトの作成 ] ページで、[検索] ボックスに 空のアプリ を入力し、C# 空のアプリ (ユニバーサル Windows) プロジェクト テンプレートを選択します。
- [ 新しいプロジェクトの構成 ] ページで、プロジェクトに Maths という名前を付け、[ 作成] を選択します。
- 必要に応じて、ターゲットと最小プラットフォームのバージョンを変更し、[ OK] を選択します。 Visual Studio によってプロジェクトが作成され、 ソリューション エクスプローラーで開かれます。
単体テスト プロジェクトを作成します。
- ソリューション エクスプローラーで、Maths ソリューションを右クリックし、[追加>新しいプロジェクト] を選択します。
- [ 新しいプロジェクトの追加 ] ページで、[検索] ボックスに 単体テスト を入力し、C# 単体テスト アプリ (ユニバーサル Windows) プロジェクト テンプレートを選択します。
- テスト プロジェクトに RooterTests という名前を付け、[ 作成] を選択します。
- 必要に応じて、ターゲットと最小プラットフォームのバージョンを変更し、[ OK] を選択します。 RooterTests プロジェクトは、ソリューション エクスプローラーの Maths ソリューションの下に表示されます。
テスト エクスプローラーでテストが実行されていることを確認する
Assert クラスには、テスト メソッドで結果を検証するために使用できる静的メソッドがいくつか用意されています。
ソリューション エクスプローラーで、RooterTests プロジェクトのUnitTest.cs ファイルを選択します。
次のコードを
TestMethod1
に挿入します。[TestMethod] public void TestMethod1() { Assert.AreEqual(0, 0); }
テスト エクスプローラーで、[すべてのテストの実行] を選択します。
テスト プロジェクトがビルドされて実行され、[合格したテスト] の下 にテストが表示されます。 右側の [グループの概要 ] ウィンドウには、テストに関する詳細が表示されます。
クラスをアプリ プロジェクトに追加する
ソリューション エクスプローラーで、Maths プロジェクトを右クリックし、[追加>Class] を選択します。
クラス ファイルに Rooter.cs名前を付け、[ 追加] を選択します。
コード エディターで、
Rooter
クラスに次のコードを追加します。public Rooter() { } // estimate the square root of a number public double SquareRoot(double x) { return 0.0; }
Rooter
クラスは、コンストラクターとSquareRoot
エスティメーター メソッドを宣言します。SquareRoot
メソッドは、基本的なテストセットアップをテストするための最小限の実装です。internal
キーワードを、public
クラス宣言でRooter
するように変更して、テスト コードがそれにアクセスできるようにします。public class Rooter
ソリューション エクスプローラーで、Maths プロジェクトを右クリックし、[追加>Class] を選択します。
クラス ファイルに Rooter.cs名前を付け、[ 追加] を選択します。
コード エディターで、
Rooter
クラスに次のコードを追加します。public Rooter() { } // estimate the square root of a number public double SquareRoot(double x) { return 0.0; }
Rooter
クラスは、コンストラクターとSquareRoot
エスティメーター メソッドを宣言します。SquareRoot
メソッドは、基本的なテストセットアップをテストするための最小限の実装です。public
キーワードをRooter
クラス宣言に追加して、テスト コードがそれにアクセスできるようにします。public class Rooter
テスト プロジェクトからアプリ プロジェクトへの参照の追加
ソリューション エクスプローラーでRooterTests プロジェクトを右クリックし、[追加>参照] を選択します。
[ 参照マネージャー - RooterTests ] ダイアログ ボックスで、[ プロジェクト] を展開し、[ 数学 ] プロジェクトを選択します。
[OK] を選択.
using
行の後に、次のusing Microsoft.VisualStudio.TestTools.UnitTesting;
ステートメントをUnitTest.csに追加します。using Maths;
ソリューション エクスプローラーでRooterTests プロジェクトを右クリックし、[追加>参照] を選択します。
[ 参照マネージャー - RooterTests ] ダイアログ ボックスで、[ プロジェクト] を展開し、[ 数学 ] プロジェクトを選択します。
[OK] を選択.
using
行の後に、次using Microsoft.VisualStudio.TestTools.UnitTesting;
ステートメントをUnitTest.csに追加します。using Maths;
アプリ関数を使用するテストを追加する
次のテスト メソッドを UnitTest.csに追加します。
[TestMethod] public void BasicTest() { Maths.Rooter rooter = new Rooter(); double expected = 0.0; double actual = rooter.SquareRoot(expected * expected); double tolerance = .001; Assert.AreEqual(expected, actual, tolerance); }
新しいテストがソリューション エクスプローラーとテスト エクスプローラーの [テストを実行しない] ノードに表示されます。
"Payload contains two or more files with the same destination path" (ペイロードに同じ宛先パスを持つ複数のファイルが含まれています) エラーを回避するには、ソリューション エクスプローラーで Maths プロジェクトの [プロパティ] ノードを展開し、Default.rd.xml ファイルを削除します。
すべてのファイルを保存します。
テストの実行
テスト エクスプローラーで、[すべてのテストの実行] アイコンを選択します。 ソリューションがビルドされ、テストが実行されて成功します。
テスト エクスプローラーで、[すべてのテストの実行] アイコンを選択します。 ソリューションがビルドされ、テストが実行されて成功します。
テストの実行時にエンティティの重複エラーが発生した場合は、ランタイム ディレクティブ ファイルを削除し、テスト プロジェクトから Properties\Default.rd.xml
して再試行します。
テスト プロジェクトとアプリ プロジェクトを設定し、アプリ プロジェクトで関数を呼び出すテストを実行できることを確認しました。 これで、実際のテストとコードを記述できます。
テストを追加して合格させる
合格したテストは変更しないことをお勧めします。 代わりに新しいテストを追加します。 一度に 1 つずつテストを追加してコードを開発し、各イテレーションの後にすべてのテストが合格することを確認します。
UnitTest.csに
RangeTest
という新しい テストを追加します。[TestMethod] public void RangeTest() { Rooter rooter = new Rooter(); for (double v = 1e-6; v < 1e6; v = v * 3.2) { double expected = v; double actual = rooter.SquareRoot(v*v); double tolerance = expected/1000; Assert.AreEqual(expected, actual, tolerance); } }
RangeTest テストを実行し、失敗したことを確認します。
ヒント
テスト駆動型開発では、テストを記述した直後に実行します。 この方法は、失敗しないテストを簡単に作成する間違いを回避するのに役立ちます。
新しいテストに合格するようにアプリ コードを修正します。 Rooter.csで、
SquareRoot
関数を次のように変更します。public double SquareRoot(double x) { double estimate = x; double diff = x; while (diff > estimate / 1000) { double previousEstimate = estimate; estimate = estimate - (estimate * estimate - x) / (2 * estimate); diff = Math.Abs(previousEstimate - estimate); } return estimate; }
テスト エクスプローラーで、[すべてのテストの実行] アイコンを選択します。 これで、3 つのテストがすべて合格しました。
UnitTest.csに
RangeTest
という新しい テストを追加します。[TestMethod] public void RangeTest() { Rooter rooter = new Rooter(); for (double v = 1e-6; v < 1e6; v = v * 3.2) { double expected = v; double actual = rooter.SquareRoot(v*v); double tolerance = expected/1000; Assert.AreEqual(expected, actual, tolerance); } }
RangeTest テストを実行し、失敗したことを確認します。
ヒント
テスト駆動型開発では、テストを記述した直後に実行します。 この方法は、失敗しないテストを簡単に作成する間違いを回避するのに役立ちます。
新しいテストに合格するようにアプリ コードを修正します。 Rooter.csで、
SquareRoot
関数を次のように変更します。public double SquareRoot(double x) { double estimate = x; double diff = x; while (diff > estimate / 1000) { double previousEstimate = estimate; estimate = estimate - (estimate * estimate - x) / (2 * estimate); diff = Math.Abs(previousEstimate - estimate); } return estimate; }
テスト エクスプローラーで、[すべてのテストの実行] アイコンを選択します。 これで、3 つのテストがすべて合格しました。
コードをリファクタリングする
このセクションでは、アプリとテスト コードの両方をリファクタリングした後、テストを再実行して、引き続き合格することを確認します。
平方根推定を簡略化する
Rooter.csでは、次の行を変更して、
SquareRoot
関数の中央計算を簡略化します。estimate = estimate - (estimate * estimate - x) / (2 * estimate);
終了
estimate = (estimate + x/estimate) / 2.0;
すべてのテストを実行して、回帰が発生していないことを確認します。 テストはすべて合格するはずです。
重複するテスト コードを削除する
RangeTest
メソッドは、tolerance
メソッドに渡されるAssert変数の分母をハード コードします。 同じ許容値の計算を使用するテストをさらに追加する予定がある場合は、ハードコーディングされた値を複数の場所で使用すると、コードの保守が困難になります。 代わりに、 UnitTest1
クラスにプライベート ヘルパー メソッドを追加して許容値を計算し、そのメソッドを RangeTest
から呼び出すことができます。
ヘルパー メソッドを追加するには、UnitTest.csで次の 手順を実行します。
次のメソッドを
UnitTest1
クラスに追加します:private double ToleranceHelper(double expected) { return expected / 1000; }
RangeTest
で、次の行を変更します。double tolerance = expected/1000;
終了
double tolerance = ToleranceHelper(expected);
RangeTest テストを実行して、引き続き合格することを確認します。
ヒント
テスト クラスにヘルパー メソッドを追加し、ヘルパー メソッドを テスト エクスプローラーの一覧に表示しない場合は、 TestMethodAttribute 属性をメソッドに追加しないでください。