다음을 통해 공유


자습서: Visual Studio를 사용하여 .NET에서 .NET 클래스 라이브러리 테스트

이 자습서에서는 솔루션에 테스트 프로젝트를 추가하여 단위 테스트를 자동화하는 방법을 보여줍니다.

필수 구성 요소

  • 이 자습서는 Visual Studio을 사용하여 .NET 클래스 라이브러리를 만드는 에서 생성한 솔루션을 사용합니다.

단위 테스트 프로젝트 만들기

단위 테스트는 개발 및 게시 중에 자동화된 소프트웨어 테스트를 제공합니다. MSTest 선택할 수 있는 세 가지 테스트 프레임워크 중 하나입니다. 다른 것들은 xUnitnUnit입니다.

  1. Visual Studio를 시작합니다.

  2. ClassLibraryProjects'를 사용하여 .NET 클래스 라이브러리 만들기에서 작성한 솔루션을 엽니다.

  3. 솔루션에 "StringLibraryTest"라는 새 단위 테스트 프로젝트를 추가합니다.

    1. 솔루션 탐색기 솔루션을 마우스 오른쪽 단추로 클릭하고 추가>새 프로젝트선택합니다.

    2. 새 프로젝트 추가 페이지에서 검색 상자에 mstest 입력합니다. 언어 목록에서 C# 선택하거나 Visual Basic 플랫폼 목록에서 모든 플랫폼을 선택합니다.

    3. MSTest 테스트 프로젝트 템플릿을 선택한 다음 다음선택하세요.

    4. 새 프로젝트 구성 페이지의 프로젝트 이름 상자에 StringLibraryTest 입력합니다. 그런 다음 다음선택합니다.

    5. 추가 정보 페이지에서 Framework 상자 안의 .NET 8을 선택합니다. 그런 다음 만들기선택합니다.

  4. Visual Studio는 프로젝트를 만들고 다음 코드를 사용하여 코드 창에서 클래스 파일을 엽니다. 사용하려는 언어가 표시되지 않으면 페이지 맨 위에 있는 언어 선택기를 변경합니다.

    namespace StringLibraryTest;
    
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    단위 테스트 템플릿에서 만든 소스 코드는 다음을 수행합니다.

    • 단위 테스트에 사용되는 형식을 포함하는 Microsoft.VisualStudio.TestTools.UnitTesting 네임스페이스를 가져옵니다. C#에서 네임스페이스는 global using 지시문을 통해 GlobalUsings.cs에서 가져옵니다.
    • TestClassAttribute 특성을 UnitTest1 클래스에 적용합니다.
    • TestMethodAttribute 특성을 적용하여 C#의 TestMethod1 또는 Visual Basic의 TestSub를 정의합니다.

    [TestClass] 태그가 지정된 테스트 클래스에서 [TestMethod] 태그가 지정된 각 메서드는 단위 테스트가 실행될 때 자동으로 실행됩니다.

프로젝트 참조 추가

테스트 프로젝트가 StringLibrary 클래스와 함께 작동하려면 StringLibraryTest 프로젝트의 참조를 StringLibrary 프로젝트에 추가합니다.

  1. 솔루션 탐색기에서 StringLibraryTest 프로젝트의 종속성 노드를 오른쪽 클릭한 후, 상황에 맞는 메뉴에서 프로젝트 참조 추가 를 선택합니다.

  2. 참조 관리자 대화 상자에서 Projects 노드를 확장하고 StringLibrary옆에 있는 상자를 선택합니다. StringLibrary 어셈블리에 대한 참조를 추가하면 컴파일러가 StringLibraryTest 프로젝트를 컴파일하는 동안 StringLibrary 메서드를 찾을 수 있습니다.

  3. 확인선택합니다.

단위 테스트 메서드 추가 및 실행

Visual Studio에서 단위 테스트를 실행하는 경우 TestMethodAttribute 특성으로 표시된 클래스에서 TestClassAttribute 특성으로 표시된 각 메서드를 실행합니다. 첫 번째 오류가 발견되거나 메서드에 포함된 모든 테스트가 성공하면 테스트 메서드가 종료됩니다.

가장 일반적인 테스트는 Assert 클래스의 멤버를 호출합니다. 많은 어설션 메서드에는 두 개 이상의 매개 변수가 포함되며, 그 중 하나는 예상 테스트 결과이고 다른 하나는 실제 테스트 결과입니다. Assert 클래스의 가장 자주 호출되는 메서드 중 일부는 다음 표에 나와 있습니다.

Assert 메서드 기능
Assert.AreEqual 두 값 또는 개체가 같은지 확인합니다. 값이나 개체가 같지 않으면 어설션이 실패합니다.
Assert.AreSame 두 개체 변수가 동일한 개체를 참조하는지 확인합니다. 변수가 다른 개체를 참조하는 경우 어설션이 실패합니다.
Assert.IsFalse 조건이 false인지 확인합니다. 조건이 true경우 어설션이 실패합니다.
Assert.IsNotNull 해당 개체가 null아닌지 확인합니다. 개체가 null경우 어설션이 실패합니다.

테스트 메서드에서 <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException%2A?displayProperty=nameWithType>(또는 MSTest 3.8 이상을 사용하는 경우 Assert.ThrowsAssert.ThrowsExactly) 메서드를 이용하여 예상되는 예외 유형을 표시할 수 있습니다. 지정된 예외가 throw되지 않으면 테스트가 실패합니다.

StringLibrary.StartsWithUpper 메서드를 테스트할 때 대문자로 시작하는 여러 문자열을 제공하려고 합니다. 이러한 경우 메서드가 true를 반환할 것으로 기대하므로 Assert.IsTrue 메서드를 호출할 수 있습니다. 마찬가지로, 대문자로 시작하지 않는 문자열을 여러 개 제공하고자 합니다. 이러한 경우 메서드가 false를 반환할 것으로 기대하므로 Assert.IsFalse 메서드를 호출할 수 있습니다.

라이브러리 메서드는 문자열을 처리하므로 빈 문자열(String.Empty), 문자가 없고 Length 0인 유효한 문자열 및 초기화되지 않은 null 문자열을 성공적으로 처리해야 합니다. StartsWithUpper 직접 정적 메서드로 호출하고 단일 String 인수를 전달할 수 있습니다. 또는 StartsWithUpper에 할당된 string 변수에서 null을 확장 메서드로 호출할 수 있습니다.

각각 문자열 배열의 각 요소에 대해 Assert 메서드를 호출하는 세 가지 메서드를 정의합니다. 테스트 실패 시 표시할 오류 메시지를 지정할 수 있는 메서드 오버로드를 호출합니다. 메시지는 오류를 발생시킨 문자열을 식별합니다.

테스트 메서드를 만들려면 다음을 수행합니다.

  1. UnitTest1.cs 또는 UnitTest1.vb 코드 창에서 코드를 다음 코드로 바꿉다.

    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    TestStartsWithUpper 메서드의 대문자 테스트에는 그리스어 대문자 알파(U+0391) 및 키릴 자모 대문자 EM(U+041C)이 포함됩니다. TestDoesNotStartWithUpper 메서드의 소문자 테스트에는 그리스어 작은 문자 알파(U+03B1) 및 키릴 자모 작은 문자 Ghe(U+0433)가 포함됩니다.

  2. 메뉴 모음에서 파일>UnitTest1.cs로 저장 를 선택하거나 또는 파일>UnitTest1.vb로 저장를 선택합니다. 파일 저장 대화 상자에서 저장 단추 옆에 있는 화살표를 선택하고 인코딩사용하여 저장을 선택합니다.

    Visual Studio 파일 다른 이름으로 저장 대화

  3. 다른 이름으로 저장 확인 대화 상자에서 단추를 선택하여 파일을 저장합니다.

  4. 고급 저장 옵션 대화 상자에서 인코딩 드롭다운 목록에서 유니코드(UTF-8 서명 포함) - Codepage 65001을 선택하고 확인을 선택합니다.

    Visual Studio 고급 저장 옵션 대화 상자

    소스 코드를 UTF8로 인코딩된 파일로 저장하지 못하면 Visual Studio에서 이를 ASCII 파일로 저장할 수 있습니다. 이 경우 런타임은 ASCII 범위를 벗어난 UTF8 문자를 정확하게 디코딩하지 않으며 테스트 결과가 올바르지 않습니다.

  5. 메뉴 모음에서 테스트>모든 테스트 실행선택합니다. 테스트 탐색기 창이 열리지 않으면 테스트>테스트 탐색기선택하여 엽니다. 세 가지 테스트는 통과한 테스트 섹션에 나열되며, 요약 섹션에서는 테스트 실행의 결과를 보고합니다.

    테스트가 통과된 테스트 탐색기 창

테스트 오류 처리

TDD(테스트 기반 개발)를 수행하는 경우 먼저 테스트를 작성하고 테스트를 처음 실행할 때 실패합니다. 그런 다음 테스트가 성공하도록 하는 코드를 앱에 추가합니다. 이 자습서에서는 유효성을 검사하는 앱 코드를 작성한 후에 테스트를 만들었기 때문에, 테스트가 실패하는 것을 보지 못했습니다. 테스트가 실패할 것으로 예상할 때 실패하는지 확인하려면 테스트 입력에 잘못된 값을 추가합니다.

  1. "Error" 문자열을 포함하도록 words 메서드의 TestDoesNotStartWithUpper 배열을 수정합니다. Visual Studio는 테스트를 실행하기 위해 솔루션을 빌드할 때 열려 있는 파일을 자동으로 저장하기 때문에 파일을 저장할 필요가 없습니다.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. 메뉴 모음에서 테스트> 모든 테스트 실행을 선택하여 테스트를 실행하세요. 테스트 탐색기 창은 두 개의 테스트가 성공했고 한 테스트가 실패했음을 나타냅니다.

    테스트 탐색기 창 , 실패한 테스트가 있는

  3. 실패한 테스트, TestDoesNotStartWith을 선택하세요.

    테스트 탐색기 창에는 어설션에 의해 생성된 메시지가 표시됩니다. "Assert.IsFalse가 실패했습니다. 'Error'에 대한 예상치: false; 실제: True". 오류로 인해 "Error" 이후 배열의 문자열이 테스트되지 않았습니다.

    테스트 탐색기 창의 IsFalse 어설션 실패를 보여 주는

  4. 1단계에서 추가한 문자열 "Error"를 제거합니다. 테스트를 다시 실행하고 테스트가 통과합니다.

라이브러리의 릴리스 버전을 테스트하세요

이제 라이브러리의 디버그 빌드를 실행할 때 테스트가 모두 통과되었으므로 라이브러리의 릴리스 빌드에 대해 테스트를 추가로 실행합니다. 컴파일러 최적화를 비롯한 다양한 요소는 디버그 빌드와 릴리스 빌드 간에 서로 다른 동작을 생성할 수 있습니다.

릴리스 빌드를 테스트하려면 다음을 수행합니다.

  1. Visual Studio 도구 모음에서 빌드 구성을 디버그에서 릴리스로 변경합니다.

    릴리스 빌드가 강조 표시된 Visual Studio 도구 모음

  2. 솔루션 탐색기StringLibrary 프로젝트를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 빌드 선택하여 라이브러리를 다시 컴파일합니다.

    StringLibrary 컨텍스트 메뉴에서 빌드 명령

  3. 메뉴 모음에서 테스트>모든 테스트 실행 선택하여 단위 테스트를 실행합니다. 테스트가 통과합니다.

디버그 테스트

Visual Studio를 IDE로 사용하는 경우 자습서에 표시된 것과 동일한 프로세스를 사용할 수 있습니다. Visual Studio 사용하여 .NET 콘솔 애플리케이션을 디버그하여 단위 테스트 프로젝트를 사용하여 코드를 디버그합니다. ShowCase 앱 프로젝트를 시작하는 대신 StringLibraryTests 프로젝트를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 디버그 테스트 선택합니다.

Visual Studio는 디버거가 연결된 상태에서 테스트 프로젝트를 시작합니다. 테스트 프로젝트 또는 기본 라이브러리 코드에 추가한 중단점에서 실행이 중지됩니다.

추가 리소스

다음 단계

이 자습서에서는 클래스 라이브러리를 단위 테스트를 수행했습니다. 라이브러리를 패키지로 NuGet 게시하여 다른 사용자가 라이브러리를 사용할 수 있도록 할 수 있습니다. 방법을 알아보려면 NuGet 자습서를 따릅니다.

Visual Studio 사용하여 NuGet 패키지 만들기 및 게시

라이브러리를 NuGet 패키지로 게시하는 경우 다른 사용자가 라이브러리를 설치하고 사용할 수 있습니다. 방법을 알아보려면 NuGet 자습서를 따릅니다.

Visual Studio 패키지 설치 및 사용

라이브러리는 패키지로 배포할 필요가 없습니다. 이를 사용하는 콘솔 앱과 함께 번들로 묶을 수 있습니다. 콘솔 앱을 게시하는 방법을 알아보려면 이 시리즈의 이전 자습서를 참조하세요.

Visual Studio 사용하여 .NET 콘솔 애플리케이션 게시