dotnet テストと xUnit を使用した .NET Core での単体テスト C#Unit testing C# in .NET Core using dotnet test and xUnit

このチュートリアルでは、単体テスト プロジェクトとソース コード プロジェクトが含まれるソリューションを構築する方法を示します。This tutorial shows how to build a solution containing a unit test project and source code project. 構築済みのソリューションを使用してチュートリアルに従う場合は、サンプル コードを表示またはダウンロードしてくださいTo follow the tutorial using a pre-built solution, view or download the sample code. ダウンロード方法については、「サンプルおよびチュートリアル」を参照してください。For download instructions, see Samples and Tutorials.

ソリューションを作成するCreate the solution

このセクションでは、ソース プロジェクトとテスト プロジェクトを含むソリューションが作成されます。In this section, a solution is created that contains the source and test projects. 完成したソリューションのディレクトリ構造は次のようになります。The completed solution has the following directory structure:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.sln
    /PrimeService
        PrimeService.cs
        PrimeService.csproj
    /PrimeService.Tests
        PrimeService_IsPrimeShould.cs
        PrimeServiceTests.csproj

テスト ソリューションを作成する手順を次に示します。The following instructions provide the steps to create the test solution. テスト ソリューションをワンステップで作成する手順については、テスト ソリューションを作成するためのコマンドに関する記事を参照してください。See Commands to create test solution for instructions to create the test solution in one step.

  • シェル ウィンドウを開きます。Open a shell window.

  • 次のコマンドを実行します。Run the following command:

    dotnet new sln -o unit-testing-using-dotnet-test
    

    dotnet new sln コマンドによって、新しいソリューションが unit-testing-using-dotnet-test ディレクトリに作成されます。The dotnet new sln command creates a new solution in the unit-testing-using-dotnet-test directory.

  • ディレクトリを unit-testing-using-dotnet-test フォルダーに変更します。Change directory to the unit-testing-using-dotnet-test folder.

  • 次のコマンドを実行します。Run the following command:

    dotnet new classlib -o PrimeService
    

    dotnet new classlib コマンドによって、PrimeService フォルダーに新しいクラス ライブラリ プロジェクトが作成されます。The dotnet new classlib command creates a new class library project in the PrimeService folder. この新しいクラス ライブラリに、テスト対象のコードが含まれることになります。The new class library will contain the code to be tested.

  • Class1.cs の名前を PrimeService.cs に変更します。Rename Class1.cs to PrimeService.cs.

  • PrimeService.cs のコードを、次のコードに置き換えます。Replace the code in PrimeService.cs with the following code:

    using System;
    
    namespace Prime.Services
    {
        public class PrimeService
        {
            public bool IsPrime(int candidate)
            {
                throw new NotImplementedException("Not implemented.");
            }
        }
    }
    
  • 上記のコードでは次の操作が行われます。The preceding code:

    • 実装されていないことを示すメッセージを含む NotImplementedException がスローされます。Throws a NotImplementedException with a message indicating it's not implemented.
    • このチュートリアルの中で、後で更新します。Is updated later in the tutorial.
  • unit-testing-using-dotnet-test ディレクトリで、次のコマンドを実行して、クラス ライブラリ プロジェクトをソリューションに追加します。In the unit-testing-using-dotnet-test directory, run the following command to add the class library project to the solution:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • 次のコマンドを実行して、PrimeService.Tests プロジェクトを作成します。Create the PrimeService.Tests project by running the following command:

    dotnet new xunit -o PrimeService.Tests
    
  • 上記のコマンドにより、次のことが行われます。The preceding command:

    • PrimeService.Tests ディレクトリに PrimeService.Tests プロジェクトが作成されます。Creates the PrimeService.Tests project in the PrimeService.Tests directory. このテスト プロジェクトでは、テスト ライブラリとして xUnit が使用されます。The test project uses xUnit as the test library.
    • プロジェクト ファイルに次の <PackageReference /> 要素を追加することで、テスト ランナーを構成します。Configures the test runner by adding the following <PackageReference />elements to the project file:
      • "Microsoft.NET.Test.Sdk""Microsoft.NET.Test.Sdk"
      • "xunit""xunit"
      • "xunit.runner.visualstudio""xunit.runner.visualstudio"
  • 次のコマンドを実行して、ソリューション ファイルにテスト プロジェクトを追加します。Add the test project to the solution file by running the following command:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • PrimeService.Tests プロジェクトへの依存関係として PrimeService クラス ライブラリを追加します。Add the PrimeService class library as a dependency to the PrimeService.Tests project:

    dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj  
    

ソリューションを作成するためのコマンドCommands to create the solution

このセクションでは、前のセクション内のすべてのコマンドの概要を示します。This section summarizes all the commands in the previous section. 前のセクションの手順を完了している場合は、このセクションをスキップしてください。Skip this section if you've completed the steps in the previous section.

次のコマンドによって、Windows コンピューター上にテスト ソリューションが作成されます。The following commands create the test solution on a windows machine. macOS と Unix の場合は、ren コマンドを ren の OS バージョンに更新してファイルの名前を変更します。For macOS and Unix, update the ren command to the OS version of ren to rename a file:

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 内のコードを次のコードに置き換える」の指示に従います。Follow the instructions for "Replace the code in PrimeService.cs with the following code" in the previous section.

テストを作成するCreate a test

テスト駆動開発 (TDD) の一般的なアプローチは、ターゲット コードを実装する前にテストを記述することです。A popular approach in test driven development (TDD) is to write a test before implementing the target code. このチュートリアルでは、この TDD アプローチを使用します。This tutorial uses the TDD approach. IsPrime メソッドは呼び出し可能ですが、実装されていません。The IsPrime method is callable, but not implemented. IsPrime のテスト呼び出しは失敗します。A test call to IsPrime fails. TDD では、失敗することがわかっているテストを記述します。With TDD, a test is written that is known to fail. テストに合格するように、ターゲット コードを更新します。The target code is updated to make the test pass. このアプローチを繰り返して、失敗するテストを記述した後、テストに合格するようにターゲット コードを更新します。You keep repeating this approach, writing a failing test and then updating the target code to pass.

PrimeService.Tests プロジェクトを更新します。Update the PrimeService.Tests project:

  • PrimeService.Tests/UnitTest1.cs を削除します。Delete PrimeService.Tests/UnitTest1.cs.
  • PrimeService.Tests/PrimeService_IsPrimeShould.cs ファイルを作成します。Create a PrimeService.Tests/PrimeService_IsPrimeShould.cs file.
  • PrimeService_IsPrimeShould.cs のコードを、次のコードに置き換えます。Replace the code in PrimeService_IsPrimeShould.cs with the following code:
using Xunit;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    public class PrimeService_IsPrimeShould
    {
        private readonly PrimeService _primeService;

        public PrimeService_IsPrimeShould()
        {
            _primeService = new PrimeService();
        }

        [Fact]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var result = _primeService.IsPrime(1);

            Assert.False(result, "1 should not be prime");
        }
    }
}

[Fact] 属性で、テスト ランナーによって実行されるテスト メソッドを宣言します。The [Fact] attribute declares a test method that's run by the test runner. PrimeService.Tests フォルダーから、dotnet test を実行します。From the PrimeService.Tests folder, run dotnet test. dotnet test コマンドで、両方のプロジェクトをビルドし、テストを実行します。The dotnet test command builds both projects and runs the tests. xUnit テスト ランナーには、テストを実行するためのプログラムのエントリ ポイントが含まれています。The xUnit test runner contains the program entry point to run the tests. dotnet test で、単体テスト プロジェクトを使用するテスト ランナーが開始されます。dotnet test starts the test runner using the unit test project.

IsPrime が実装されていないため、テストは失敗します。The test fails because IsPrime hasn't been implemented. TDD アプローチでは、このテストに合格するのに十分なコードだけを記述します。Using the TDD approach, write only enough code so this test passes. 次のコードを使用して IsPrime を更新します。Update IsPrime with the following code:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

dotnet test を実行します。Run dotnet test. テストは成功します。The test passes.

さらにテストを追加するAdd more tests

0 と -1 のための素数テストを追加します。Add prime number tests for 0 and -1. 前のテストをコピーし、次のコードを 0 と -1 を使用するように変更できます。You could copy the preceding test and change the following code to use 0 and -1:

var result = _primeService.IsPrime(1);

Assert.False(result, "1 should not be prime");

パラメーターだけを変更するときにテスト コードをコピーすると、コードの重複が発生してテストが膨張します。Copying test code when only a parameter changes results in code duplication and test bloat. 次の xUnit 属性を使用して、類似する一連のテストを記述できます。The following xUnit attributes enable writing a suite of similar tests:

  • [Theory] は同じコードを実行するものの、異なる入力引数が含まれる一連のテストを表します。[Theory] represents a suite of tests that execute the same code but have different input arguments.
  • [InlineData] 属性は、これらの入力の値を指定します。[InlineData] attribute specifies values for those inputs.

新しいテストを作成するのではなく、上記の xUnit 属性を適用することで、単一の理論を作成できます。Rather than creating new tests, apply the preceding xUnit attributes to create a single theory. 以下のコードをReplace the following code:

[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
    var result = _primeService.IsPrime(1);

    Assert.False(result, "1 should not be prime");
}

を、以下のコードに置き換えます。with the following code:

[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 未満のいくつかの値をテストできます。In the preceding code, [Theory] and [InlineData] enable testing several values less than two. 2 は最小の素数です。Two is the smallest prime number.

dotnet test を実行すると、2 のテストは失敗します。Run dotnet test, two of the tests fail. すべてのテストに合格するようにするには、次のコードで IsPrime メソッドを更新します。To make all of the tests pass, update the IsPrime method with the following code:

public bool IsPrime(int candidate)
{
    if (candidate < 2)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

TDD アプローチに従って、失敗するテストをさらに追加した後、ターゲット コードを更新します。Following the TDD approach, add more failing tests, then update the target code. テストの最終版と、ライブラリの完全な実装を参照してください。See the finished version of the tests and the complete implementation of the library.

完成した IsPrime メソッドは、素数性をテストするための効率的なアルゴリズムではありません。The completed IsPrime method is not an efficient algorithm for testing primality.

その他のリソースAdditional resources