MSTest 및 .NET Core를 사용한 C# 유닛 테스트Unit testing C# with MSTest and .NET Core

이 자습서에서는 샘플 솔루션을 단계별로 빌드하는 대화형 환경을 통해 단위 테스트 개념을 알아볼 수 있습니다.This tutorial takes you through an interactive experience building a sample solution step-by-step to learn unit testing concepts. 미리 빌드된 솔루션을 사용하여 이 자습서를 진행하려는 경우 시작하기 전에 샘플 코드를 보거나 다운로드.If you prefer to follow the tutorial using a pre-built solution, view or download the sample code before you begin. 다운로드 지침은 샘플 및 자습서를 참조하세요.For download instructions, see Samples and Tutorials.

소스 프로젝트 만들기Create the source project

셸 창을 엽니다.Open a shell window. 솔루션을 저장할 unit-testing-using-mstest라는 디렉터리를 만듭니다.Create a directory called unit-testing-using-mstest to hold the solution. 이 새 디렉터리 내에서 dotnet new sln을 실행하여 클래스 라이브러리 및 테스트 프로젝트에 대한 새 솔루션 파일을 만듭니다.Inside this new directory, run dotnet new sln to create a new solution file for the class library and the test project. 다음으로 PrimeService 디렉터리를 만듭니다.Next, create a PrimeService directory. 다음 개요에는 지금까지의 디렉터리 및 파일 구조가 나와 있습니다.The following outline shows the directory and file structure thus far:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService

PrimeService를 현재 디렉터리로 만들고 dotnet new classlib를 실행하여 소스 프로젝트를 만듭니다.Make PrimeService the current directory and run dotnet new classlib to create the source project. Class1.cs의 이름을 PrimeService.cs로 바꿉니다.Rename Class1.cs to PrimeService.cs. 다음과 같이 PrimeService 클래스의 실패 구현을 만듭니다.You create a failing implementation of the PrimeService class:

using System;

namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate) 
        {
            throw new NotImplementedException("Please create a test first.");
        } 
    }
}

디렉터리를 다시 unit-testing-using-mstest 디렉터리로 변경합니다.Change the directory back to the unit-testing-using-mstest directory. dotnet sln add PrimeService/PrimeService.csproj를 실행하여 클래스 라이브러리 프로젝트를 솔루션에 추가합니다.Run dotnet sln add PrimeService/PrimeService.csproj to add the class library project to the solution.

테스트 프로젝트 만들기Create the test project

다음으로 PrimeService.Tests 디렉터리를 만듭니다.Next, create the PrimeService.Tests directory. 다음 개요에는 디렉터리 구조가 나와 있습니다.The following outline shows the directory structure:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests

PrimeService.Tests 디렉터리를 현재 디렉터리로 만들고 dotnet new mstest를 사용하여 새 프로젝트를 만듭니다.Make the PrimeService.Tests directory the current directory and create a new project using dotnet new mstest. dotnet new 명령은 MSTest를 테스트 라이브러리로 사용하는 테스트 프로젝트를 만듭니다.The dotnet new command creates a test project that uses MSTest as the test library. 생성된 템플릿이 PrimeServiceTests.csproj 파일에 Test Runner를 구성했습니다.The generated template configures the test runner in the PrimeServiceTests.csproj file:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
  <PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
  <PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
</ItemGroup>

테스트 프로제트는 다른 패키지에 단위 테스트를 만들고 실행하도록 요구합니다.The test project requires other packages to create and run unit tests. 이전 단계의 dotnet new는 MSTest SDK, MSTest 테스트 프레임워크 및 MSTest Runner를 추가했습니다.dotnet new in the previous step added the MSTest SDK, the MSTest test framework, and the MSTest runner. 이제 PrimeService 클래스 라이브러리를 프로젝트에 다른 종속성으로 추가합니다.Now, add the PrimeService class library as another dependency to the project. dotnet add reference 명령을 사용합니다.Use the dotnet add reference command:

dotnet add reference ../PrimeService/PrimeService.csproj

GitHub의 샘플 리포지토리에서 전체 파일을 볼 수 있습니다.You can see the entire file in the samples repository on GitHub.

다음 개요에는 최종 솔루션 레이아웃이 나와 있습니다.The following outline shows the final solution layout:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests
        Test Source Files
        PrimeServiceTests.csproj

unit-testing-using-mstest 디렉터리에서 dotnet sln add .\PrimeService.Tests\PrimeService.Tests.csproj를 실행합니다.Execute dotnet sln add .\PrimeService.Tests\PrimeService.Tests.csproj in the unit-testing-using-mstest directory.

첫 번째 테스트 만들기Create the first test

하나의 실패 테스트를 작성하고, 테스트가 성공하도록 만듭니다. 이 작업을 반복합니다.You write one failing test, make it pass, then repeat the process. PrimeService.Tests 디렉터리에서 UnitTest1.cs를 제거하고 다음과 같은 내용으로 새 C# 파일 PrimeService_IsPrimeShould.cs를 만듭니다.Remove UnitTest1.cs from the PrimeService.Tests directory and create a new C# file named PrimeService_IsPrimeShould.cs with the following content:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Prime.Services;

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

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

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

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

TestClass 특성은 단위 테스트가 포함된 클래스를 나타냅니다.The TestClass attribute denotes a class that contains unit tests. TestMethod 특성은 메서드가 테스트 메서드임을 나타냅니다.The TestMethod attribute indicates a method is a test method.

이 파일을 저장하고 dotnet test를 실행하여 테스트 및 클래스 라이브러리를 빌드한 다음 테스트를 실행합니다.Save this file and execute dotnet test to build the tests and the class library and then run the tests. MSTest Test Runner에는 테스트를 실행할 프로그램 진입점이 포함되어 있습니다.The MSTest test runner contains the program entry point to run your tests. dotnet test는 만든 단위 테스트 프로젝트를 사용하여 Test Runner를 시작합니다.dotnet test starts the test runner using the unit test project you've created.

테스트가 실패합니다.Your test fails. 구현은 아직 만들지 않았습니다.You haven't created the implementation yet. PrimeService 클래스에서 작동하는 가장 간단한 코드를 작성하여 이 테스트를 통과시킵니다.Make this test pass by writing the simplest code in the PrimeService class that works:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

unit-testing-using-mstest 디렉터리에서 dotnet test를 다시 실행합니다.In the unit-testing-using-mstest directory, run dotnet test again. dotnet test 명령은 PrimeService 프로젝트에 대한 빌드를 실행한 다음 PrimeService.Tests 프로젝트에 대한 빌드를 실행합니다.The dotnet test command runs a build for the PrimeService project and then for the PrimeService.Tests project. 두 프로젝트를 모두 빌드한 후 이 단일 테스트를 실행합니다.After building both projects, it runs this single test. 전달합니다.It passes.

더 많은 기능 추가Add more features

이제 하나의 테스트를 통과했으므로 더 작성할 수 있습니다.Now that you've made one test pass, it's time to write more. 소수에 대한 몇 가지 다른 간단한 사례가 있습니다 (0, -1).There are a few other simple cases for prime numbers: 0, -1. 새 테스트를 TestMethod 특성과 함께 추가할 수도 있지만, 이렇게 하면 금방 지루해질 수 있습니다.You could add new tests with the TestMethod attribute, but that quickly becomes tedious. 비슷한 테스트 모음을 작성하는 데 사용할 수 있는 다른 MSTest 특성이 있습니다.There are other MSTest attributes that enable you to write a suite of similar tests. DataTestMethod 특성은 같은 코드를 실행하지만 다른 입력 인수가 있는 테스트 도구 모음을 나타냅니다.A DataTestMethod attribute represents a suite of tests that execute the same code but have different input arguments. DataRow 특성을 사용하여 그러한 입력의 값을 지정할 수 있습니다.You can use the DataRow attribute to specify values for those inputs.

새 테스트를 만드는 대신 이러한 두 특성을 적용하여 단일 데이터 기반 테스트를 만듭니다.Instead of creating new tests, apply these two attributes to create a single data driven test. 이 데이터 기반 테스트는 가장 작은 소수인 2보다 작은 몇 가지 값을 테스트하는 메서드입니다.The data driven test is a method that tests several values less than two, which is the lowest prime number:

[DataTestMethod]
[DataRow(-1)]
[DataRow(0)]
[DataRow(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    var result = _primeService.IsPrime(value);

    Assert.IsFalse(result, $"{value} should not be prime");
}

dotnet test를 실행합니다. 그러면 이러한 테스트 중 2개가 실패합니다.Run dotnet test, and two of these tests fail. 모든 테스트가 통과하도록 하려면 메서드의 시작 부분에서 if 절을 변경합니다.To make all of the tests pass, change the if clause at the beginning of the method:

if (candidate < 2)

기본 라이브러리에서 더 많은 테스트, 더 많은 이론, 더 많은 코드를 추가하여 계속 반복합니다.Continue to iterate by adding more tests, more theories, and more code in the main library. 테스트의 완료된 버전라이브러리의 완전한 구현을 얻게 됩니다.You have the finished version of the tests and the complete implementation of the library.

작은 라이브러리 및 이 라이브러리에 대한 단위 테스트 집합을 작성했습니다.You've built a small library and a set of unit tests for that library. 새 패키지 및 테스트 추가가 정상 워크플로에 포함되도록 솔루션을 구조화했습니다.You've structured the solution so that adding new packages and tests is part of the normal workflow. 애플리케이션의 목표를 해결하는 데 대부분의 시간과 노력을 들였습니다.You've concentrated most of your time and effort on solving the goals of the application.

참고 항목See also