Share via


.NET CLI를 사용하여 프로젝트 구성 및 테스트

이 자습서는 자습서: Visual Studio Code를 사용하여 .NET으로 콘솔 애플리케이션 만들기의 후속으로, 간단한 콘솔 앱을 만드는 것을 넘어 잘 구성된 고급 애플리케이션을 개발하도록 안내합니다. 이 자습서에서는 폴더를 사용하여 코드를 구성하는 방법을 보여 준 후에 xUnit 테스트 프레임워크를 사용하여 콘솔 애플리케이션을 확장하는 방법을 보여 줍니다.

참고 항목

이 자습서에서는 애플리케이션 프로젝트와 테스트 프로젝트를 별도의 폴더에 배치하는 것이 좋습니다. 일부 개발자는 이러한 프로젝트를 동일한 폴더에 보관하는 것을 선호합니다. 자세한 내용은 GitHub 문제 dotnet/docs #26395를 참조하세요.

폴더를 사용하여 코드 구성

콘솔 앱에 새 유형을 도입하려는 경우 유형이 포함된 파일을 앱에 추가하면 됩니다. 예를 들어 AccountInformationMonthlyReportRecords 유형이 포함된 파일을 프로젝트에 추가하는 경우 프로젝트 파일 구조가 단순하며 쉽게 탐색할 수 있습니다.

/MyProject
|__AccountInformation.cs
|__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

그러나 이 플랫 구조는 프로젝트 규모가 상대적으로 작은 경우에만 잘 작동합니다. 프로젝트에 20개의 유형을 추가하면 어떻게 될지 상상이 되시나요? 프로젝트의 루트 디렉터리에 너무 많은 파일이 있으면 분명히 프로젝트 탐색과 유지 관리가 쉽지 않을 것입니다.

프로젝트를 구성하려면 유형 파일을 보관할 새 폴더를 만들고 이름을 Models로 지정합니다. Models 폴더에 유형 파일을 넣습니다.

/MyProject
|__/Models
   |__AccountInformation.cs
   |__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

논리적으로 파일을 폴더로 그룹화하는 프로젝트는 탐색과 유지 관리가 용이합니다. 다음 섹션에서는 폴더 및 유닛 테스트를 사용하여 좀 더 복잡한 샘플을 만듭니다.

NewTypes Pets 샘플을 사용하여 구성 및 테스트

필수 조건

샘플 빌드

다음 단계를 위해 NewTypes Pets 샘플을 사용할 수도 있고, 고유한 파일과 폴더를 만들 수도 있습니다. 나중에 더 많은 유형을 추가할 수 있는 폴더 구조로 유형이 논리적으로 구성되며, 테스트도 나중에 더 많은 테스트를 추가할 수 있는 폴더에 논리적으로 배치됩니다.

샘플에는 두 유형 DogCat이 포함되어 있으며, 두 유형이 공용 인터페이스 IPet을 구현하도록 합니다. NewTypes 프로젝트의 목표는 애완 동물 관련 유형을 Pets 폴더로 구성하는 것입니다. 나중에 WildAnimals등의 다른 유형 집합을 추가하면 Pets 폴더와 함께 NewTypes 폴더에 배치됩니다. WildAnimals 폴더에는 애완 동물이 아닌 동물 유형(예: SquirrelRabbit)이 포함될 수 있습니다. 이렇게 하면 유형을 추가해도 프로젝트의 체계적인 구성이 유지됩니다.

표시된 파일 내용으로 다음 폴더 구조를 만듭니다.

/NewTypes
|__/src
   |__/NewTypes
      |__/Pets
         |__Dog.cs
         |__Cat.cs
         |__IPet.cs
      |__Program.cs
      |__NewTypes.csproj

IPet.cs:

using System;

namespace Pets
{
    public interface IPet
    {
        string TalkToOwner();
    }
}

Dog.cs:

using System;

namespace Pets
{
    public class Dog : IPet
    {
        public string TalkToOwner() => "Woof!";
    }
}

Cat.cs:

using System;

namespace Pets
{
    public class Cat : IPet
    {
        public string TalkToOwner() => "Meow!";
    }
}

Program.cs:

using System;
using Pets;
using System.Collections.Generic;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            List<IPet> pets = new List<IPet>
            {
                new Dog(),
                new Cat()
            };

            foreach (var pet in pets)
            {
                Console.WriteLine(pet.TalkToOwner());
            }
        }
    }
}

NewTypes.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

다음 명령을 실행합니다.

dotnet run

다음 출력이 표시됩니다.

Woof!
Meow!

연습(옵션): 이 프로젝트를 확장하여 Bird 등의 새로운 애완 동물 유형을 추가할 수 있습니다. 새의 TalkToOwner 메서드를 통해 소유자에게 Tweet!을 제공합니다. 앱을 다시 실행합니다. 출력에 Tweet!이 포함됩니다.

샘플 테스트

NewTypes 프로젝트가 구현되었으며, 애완 동물 관련 유형을 폴더에 보관하여 구성했습니다. 다음으로, 테스트 프로젝트를 만들고 xUnit 테스트 프레임워크를 사용하여 테스트 작성을 시작합니다. 유닛 테스트를 사용하면 애완동물 유형의 동작을 자동으로 검사하여 제대로 작동하는지 확인할 수 있습니다.

src 폴더를 다시 탐색하고 test 폴더를 만들며, 이 폴더 안에 NewTypesTests 폴더를 만듭니다. NewTypesTests 폴더의 명령 프롬프트에서 dotnet new xunit를 실행합니다. 이 명령은 NewTypesTests.csprojUnitTest1.cs라는 두 개의 파일을 생성합니다.

테스트 프로젝트는 현재 NewTypes의 형식을 테스트할 수 없으며, NewTypes 프로젝트에 대한 프로젝트 참조가 필요합니다. 프로젝트 참조를 추가하려면 dotnet add reference 명령을 사용합니다.

dotnet add reference ../../src/NewTypes/NewTypes.csproj

또는 NewTypesTests.csproj 파일에 <ItemGroup> 노드를 추가하여 수동으로 프로젝트 참조를 추가할 수도 있습니다.

<ItemGroup>
  <ProjectReference Include="../../src/NewTypes/NewTypes.csproj" />
</ItemGroup>

NewTypesTests.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
    <PackageReference Include="xunit" Version="2.8.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="../../src/NewTypes/NewTypes.csproj"/>
  </ItemGroup>

</Project>

NewTypesTests.csproj 파일에는 다음 패키지 참조가 포함되어 있습니다.

  • Microsoft.NET.Test.Sdk, .NET 테스트 인프라
  • xunit, xUnit 테스트 프레임워크
  • xunit.runner.visualstudio, 테스트 실행자
  • NewTypes, 테스트할 코드

UnitTest1.cs의 이름을 PetTests.cs로 변경하고 파일의 코드를 다음으로 바꿉니다.

using System;
using Xunit;
using Pets;

public class PetTests
{
    [Fact]
    public void DogTalkToOwnerReturnsWoof()
    {
        string expected = "Woof!";
        string actual = new Dog().TalkToOwner();

        Assert.NotEqual(expected, actual);
    }

    [Fact]
    public void CatTalkToOwnerReturnsMeow()
    {
        string expected = "Meow!";
        string actual = new Cat().TalkToOwner();

        Assert.NotEqual(expected, actual);
    }
}

연습(옵션): 소유자에 대한 Tweet!을 생성하는 Bird 유형을 이전에 추가한 경우 PetTests.cs 파일에 테스트 메서드 BirdTalkToOwnerReturnsTweet을 추가하여 TalkToOwner 메서드가 Bird 유형에 대해 제대로 작동하는지 확인합니다.

참고 항목

expectedactual 값이 같다고 예상하는 경우에도 Assert.NotEqual 검사를 사용한 초기 어설션에서는 이러한 값이 같지 않다고 지정합니다. 테스트 논리를 검사하기 위해 항상 먼저 실패할 테스트를 만듭니다. 테스트가 실패했음을 확인한 후 테스트를 통과할 수 있도록 어설션을 조정합니다.

전체 프로젝트 구조는 다음과 같습니다.

/NewTypes
|__/src
   |__/NewTypes
      |__/Pets
         |__Dog.cs
         |__Cat.cs
         |__IPet.cs
      |__Program.cs
      |__NewTypes.csproj
|__/test
   |__NewTypesTests
      |__PetTests.cs
      |__NewTypesTests.csproj

test/NewTypesTests 디렉터리에서 시작합니다. dotnet test 명령을 사용하여 테스트를 실행합니다. 이 명령은 프로젝트 파일에 지정된 Test Runner를 시작합니다.

예상대로 테스트에 실패하고, 콘솔에 다음 출력이 표시됩니다.

Test run for C:\Source\dotnet\docs\samples\snippets\core\tutorials\testing-with-cli\csharp\test\NewTypesTests\bin\Debug\net5.0\NewTypesTests.dll (.NETCoreApp,Version=v5.0)
Microsoft (R) Test Execution Command Line Tool Version 16.8.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.50]     PetTests.DogTalkToOwnerReturnsWoof [FAIL]
  Failed PetTests.DogTalkToOwnerReturnsWoof [6 ms]
  Error Message:
   Assert.NotEqual() Failure
Expected: Not "Woof!"
Actual:   "Woof!"
  Stack Trace:
     at PetTests.DogTalkToOwnerReturnsWoof() in C:\Source\dotnet\docs\samples\snippets\core\tutorials\testing-with-cli\csharp\test\NewTypesTests\PetTests.cs:line 13

Failed!  - Failed:     1, Passed:     1, Skipped:     0, Total:     2, Duration: 8 ms - NewTypesTests.dll (net5.0)

테스트 어설션을 Assert.NotEqual에서 Assert.Equal로 변경합니다.

using System;
using Xunit;
using Pets;

public class PetTests
{
    [Fact]
    public void DogTalkToOwnerReturnsWoof()
    {
        string expected = "Woof!";
        string actual = new Dog().TalkToOwner();

        Assert.Equal(expected, actual);
    }

    [Fact]
    public void CatTalkToOwnerReturnsMeow()
    {
        string expected = "Meow!";
        string actual = new Cat().TalkToOwner();

        Assert.Equal(expected, actual);
    }
}

dotnet test 명령을 사용하여 테스트를 다시 실행하면 다음 출력이 표시됩니다.

Test run for C:\Source\dotnet\docs\samples\snippets\core\tutorials\testing-with-cli\csharp\test\NewTypesTests\bin\Debug\net5.0\NewTypesTests.dll (.NETCoreApp,Version=v5.0)
Microsoft (R) Test Execution Command Line Tool Version 16.8.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

Passed!  - Failed:     0, Passed:     2, Skipped:     0, Total:     2, Duration: 2 ms - NewTypesTests.dll (net5.0)

테스트를 통과합니다. 애완 동물 유형의 메서드가 소유자에게 설명할 때 올바른 값을 반환합니다.

xUnit를 사용하여 프로젝트를 구성 및 테스트하는 기술을 배웠습니다. 이러한 기술을 활용하여 사용자 고유의 프로젝트에 적용해 보세요. 즐거운 코딩을 경험하시기 바랍니다!