このチュートリアルでは、単体テスト プロジェクトとソース コード プロジェクトを含むソリューションを構築する方法について説明します。 事前構築済みのソリューションを使用してチュートリアルに従う場合は、 サンプル コードを表示またはダウンロードします。 ダウンロード手順については、サンプルとチュートリアルを参照してください。
ソリューションを作成する
このセクションでは、ソース プロジェクトとテスト プロジェクトを含むソリューションを作成します。 完成したソリューションのディレクトリ構造は次のとおりです。
/unit-testing-using-dotnet-test
unit-testing-using-dotnet-test.sln
/PrimeService
PrimeService.cs
PrimeService.csproj
/PrimeService.Tests
PrimeService_IsPrimeShould.cs
PrimeServiceTests.csproj
次の手順では、テスト ソリューションを作成する手順を示します。 1 つの手順で テスト ソリューションを作成 する手順については、「テスト ソリューションを作成するコマンド」を参照してください。
シェル ウィンドウを開きます。
次のコマンドを実行します。
dotnet new sln -o unit-testing-using-dotnet-testdotnet new slnコマンドは、unit-testing-using-dotnet-test ディレクトリに新しいソリューションを作成します。ディレクトリを unit-testing-using-dotnet-test フォルダーに変更します。
次のコマンドを実行します。
dotnet new classlib -o PrimeServicedotnet new classlibコマンドは、PrimeService フォルダーに新しいクラス ライブラリ プロジェクトを作成します。 新しいクラス ライブラリには、テストするコードが含まれます。Class1.cs の名前を PrimeService.cs に変更します。
PrimeService.csのコードを次のコードに置き換えます。
using System; namespace Prime.Services { public class PrimeService { public bool IsPrime(int candidate) { throw new NotImplementedException("Not implemented."); } } }現在、このコードでは NotImplementedException がスローされますが、このチュートリアルでは、後でこのメソッドを実装します。
unit-testing-using-dotnet-test ディレクトリで、次のコマンドを実行して、クラス ライブラリ プロジェクトをソリューションに追加します。
dotnet sln add ./PrimeService/PrimeService.csproj次のコマンドを実行して 、PrimeService.Tests プロジェクトを作成します。
dotnet new xunit -o PrimeService.Tests上記のコマンドは、 PrimeService.Tests ディレクトリに PrimeService.Tests プロジェクトを作成します。 テスト プロジェクトでは、テスト ライブラリとして xUnit が使用されます。 また、次の
<PackageReference />要素をプロジェクト ファイルに追加して、テスト ランナーを構成します。Microsoft.NET.Test.Sdkxunitxunit.runner.visualstudiocoverlet.collector
次のコマンドを実行して、ソリューション ファイルにテスト プロジェクトを追加します。
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csprojPrimeServiceクラス ライブラリを依存関係として PrimeService.Tests プロジェクトに追加します。dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
ソリューションを作成するコマンド
このセクションでは、前のセクションのすべてのコマンドの概要を示します。 前のセクションの手順を完了した場合は、このセクションをスキップします。
次のコマンドは、Windows マシン上にテスト ソリューションを作成します。 macOS および Unix の場合は、 ren コマンドを OS バージョンの ren に更新して、ファイルの名前を変更します。
dotnet new sln -o unit-testing-using-dotnet-test
cd unit-testing-using-dotnet-test
dotnet new classlib -o PrimeService
ren .\PrimeService\Class1.cs PrimeService.cs
dotnet sln add ./PrimeService/PrimeService.csproj
dotnet new xunit -o PrimeService.Tests
dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
前のセクションの「 PrimeService.cs のコードを次のコードに置き換える」の手順に従います。
テストの作成
テスト 駆動開発 (TDD) の一般的なアプローチは、ターゲット コードを実装する前に (失敗した) テストを記述することです。 このチュートリアルでは、TDD アプローチを使用します。
IsPrime メソッドは呼び出し可能ですが、実装されていません。
IsPrimeのテスト呼び出しが失敗します。 TDD では、失敗することがわかっているテストを記述します。 次に、テストに合格するようにターゲット コードを更新します。 このアプローチを繰り返し、失敗したテストを記述してから、合格するようにターゲット コードを更新します。
PrimeService.Tests プロジェクトを更新します。
PrimeService.Tests/UnitTest1.cs を削除します。
PrimeService.Tests/PrimeService_IsPrimeShould.cs ファイルを作成します。
PrimeService_IsPrimeShould.csのコードを次のコードに置き換えます。
using Xunit; using Prime.Services; namespace Prime.UnitTests.Services { public class PrimeService_IsPrimeShould { [Fact] public void IsPrime_InputIs1_ReturnFalse() { var primeService = new PrimeService(); bool result = primeService.IsPrime(1); Assert.False(result, "1 shouldn't be prime"); } } }
[Fact]属性は、テスト ランナーによって実行されるテスト メソッドを宣言します。
PrimeService.Tests フォルダーから、dotnet test実行します。
dotnet テスト コマンドは、両方のプロジェクトをビルドし、テストを実行します。 xUnit テスト ランナーには、テストを実行するためのプログラム エントリ ポイントが含まれています。
dotnet test は、単体テスト プロジェクトを使用してテスト ランナーを開始します。
IsPrimeが実装されていないため、テストは失敗します。 TDD アプローチを使用して、このテストに合格するように十分なコードのみを記述します。 次のコードを使用して IsPrime を更新します。
public bool IsPrime(int candidate)
{
if (candidate == 1)
{
return false;
}
throw new NotImplementedException("Not fully implemented.");
}
dotnet test を実行します。 テストは成功します。
さらにテストを追加する
0 と -1 の素数テストを追加します。 前の手順で作成したテスト をコピーし 、次のコードのコピーを作成して 0 と -1 をテストできます。 しかし、より良い方法があるので、それをしないでください。
var primeService = new PrimeService();
bool result = primeService.IsPrime(1);
Assert.False(result, "1 shouldn't be prime");
パラメーターのみが変更されたときにテスト コードをコピーすると、コードの重複とテストの肥大化が発生します。 次の xUnit 属性を使用すると、同様のテストのスイートを記述できます。
-
[Theory]は、同じコードを実行するが、入力引数が異なる一連のテストを表します。 -
[InlineData]属性は、これらの入力の値を指定します。
新しいテストを作成するのではなく、上記の xUnit 属性を適用して、単一の理論を作成します。 次のコードを置き換えます...
[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
var primeService = new PrimeService();
bool result = primeService.IsPrime(1);
Assert.False(result, "1 shouldn't be prime");
}
...次のコードを使用します。
[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
var result = _primeService.IsPrime(value);
Assert.False(result, $"{value} should not be prime");
}
前のコードでは、 [Theory] と [InlineData] 、2 未満の複数の値のテストを有効にします。 2 は最小の素数です。
クラス宣言の後、および [Theory] 属性の前に次のコードを追加します。
private readonly PrimeService _primeService;
public PrimeService_IsPrimeShould()
{
_primeService = new PrimeService();
}
dotnet testを実行すると、2 つのテストが失敗します。 すべてのテストに合格するには、次のコードを使用して IsPrime メソッドを更新します。
public bool IsPrime(int candidate)
{
if (candidate < 2)
{
return false;
}
throw new NotImplementedException("Not fully implemented.");
}
TDD アプローチに従って、失敗したテストをさらに追加してから、ターゲット コードを更新します。 完成したバージョンのテストとライブラリの完全な実装を参照してください。
完成した IsPrime メソッドは、原始性をテストするための効率的なアルゴリズムではありません。
その他のリソース
.NET