다음을 통해 공유


dotnet test 및 xUnit을 사용하여 .NET에서 C# 단위 테스트

이 자습서에서는 단위 테스트 프로젝트 및 소스 코드 프로젝트를 포함하는 솔루션을 빌드하는 방법을 보여줍니다. 미리 빌드된 솔루션을 사용하여 자습서를 수행하려면 샘플 코드를 보거나 다운로드합니다. 다운로드 지침은 샘플 및 자습서참조하세요.

솔루션 만들기

이 섹션에서는 원본 및 테스트 프로젝트를 포함하는 솔루션을 만듭니다. 완료된 솔루션에는 다음과 같은 디렉터리 구조가 있습니다.

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

다음 지침에서는 테스트 솔루션을 만드는 단계를 제공합니다. 한 단계로 테스트 솔루션을 만들기 위한 지침은 테스트 솔루션 만들기 명령을 참조하세요.

  • 셸 창을 엽니다.

  • 다음 명령을 실행합니다.

    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
    
  • 클래스 라이브러리를 PrimeServicePrimeService.Tests 프로젝트에 종속성으로 추가합니다.

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

솔루션을 만드는 명령

이 섹션에서는 이전 섹션의 모든 명령을 요약합니다. 이전 섹션의 단계를 완료한 경우 이 섹션을 건너뜁니다.

다음 명령은 Windows 머신에서 테스트 솔루션을 만듭니다. macOS 및 Unix의 경우, 파일 이름을 변경하려면 ren 명령을 ren의 OS 버전에 맞게 업데이트합니다.

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 test 명령은 두 프로젝트를 빌드하고 테스트를 실행합니다. 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");

매개 변수만 변경되면 테스트 코드를 복사하면 코드가 중복되고 테스트가 bloat됩니다. 다음 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개는 가장 작은 소수입니다.

클래스 선언 뒤와 특성 앞에 [Theory] 다음 코드를 추가합니다.

private readonly PrimeService _primeService;

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

실행 dotnet test하면 두 테스트가 실패합니다. 모든 테스트를 통과하려면 메서드 IsPrime를 다음 코드로 업데이트합니다.

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

TDD 접근 방식에 따라 실패한 테스트를 더 추가한 다음 대상 코드를 업데이트합니다. 테스트의 완성된 버전라이브러리의 전체 구현을 참조하세요.

완료된 IsPrime 메서드는 원시성을 테스트하기 위한 효율적인 알고리즘이 아닙니다.

추가 리소스