このチュートリアルでは、単体テスト プロジェクトとソース コード プロジェクトを含むソリューションを構築する方法について説明します。 事前構築済みのソリューションを使用してチュートリアルに従う場合は、 サンプル コードを表示またはダウンロードします。 ダウンロード手順については、サンプルとチュートリアルを参照してください。
ソリューションを作成する
このセクションでは、ソース プロジェクトとテスト プロジェクトを含むソリューションを作成します。 完成したソリューションのディレクトリ構造は次のとおりです。
/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-test
dotnet new sln
コマンドは、unit-testing-using-dotnet-test ディレクトリに新しいソリューションを作成します。ディレクトリを unit-testing-using-dotnet-test フォルダーに変更します。
次のコマンドを実行します。
dotnet new classlib -o PrimeService
dotnet 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.Sdk
xunit
xunit.runner.visualstudio
coverlet.collector
次のコマンドを実行して、ソリューション ファイルにテスト プロジェクトを追加します。
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
PrimeService
クラス ライブラリを依存関係として 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 should not 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 should not 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 should not 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