이 자습서에서는 단위 테스트 프로젝트 및 소스 코드 프로젝트를 포함하는 솔루션을 빌드하는 방법을 보여줍니다. 미리 빌드된 솔루션을 사용하여 자습서를 수행하려면 샘플 코드를 보거나 다운로드합니다. 다운로드 지침은 샘플 및 자습서참조하세요.
솔루션 만들기
이 섹션에서는 원본 및 테스트 프로젝트를 포함하는 솔루션을 만듭니다. 완료된 솔루션에는 다음과 같은 디렉터리 구조가 있습니다.
/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
클래스 라이브러리를
PrimeService
PrimeService.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
메서드는 원시성을 테스트하기 위한 효율적인 알고리즘이 아닙니다.
추가 리소스
.NET