다음을 통해 공유


자습서: .NET 클래스 라이브러리 테스트

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

필수 조건

이 자습서는 .NET 클래스 라이브러리 만들기에서 만든 솔루션에서 작동합니다.

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

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

  1. Visual Studio 시작합니다.

  2. ClassLibraryProjects에서 만든 솔루션을 엽니다.

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

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

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

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

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

    5. 추가 정보 페이지의 프레임워크 상자에서 .NET 10를 선택하고, Test runner에 대해 Microsoft.Testing.Platform을 선택한 다음 생성을 선택합니다.

    MSTest 테스트 프로젝트에 대한 추가 정보 입력

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

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

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

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

  1. Visual Studio Code 시작합니다.

  2. ClassLibraryProjects에서 만든 솔루션을 엽니다.

  3. 솔루션 탐색기에서 새 프로젝트를 선택하거나 명령 팔레트에서 .NET: 새 프로젝트 선택합니다.

  4. MSTest 테스트 프로젝트를 선택하고 이름을 "StringLibraryTest"로 지정하고 기본 디렉터리를 선택한 다음 프로젝트 만들기를 선택합니다.

    프로젝트 템플릿은 다음 코드를 사용하여 StringLibraryTest/Test1.cs 만듭니다.

    namespace StringLibraryTest;
    
    [TestClass]
    public class Test1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    

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

    • 클래스에 특성을 적용합니다.
    • 정의할 특성을 적용합니다.
    • 단위 테스트에 사용되는 형식을 포함하는 네임스페이스를 가져옵니다. 네임스페이스는 GlobalUsings.cs 지시문을 통해 가져옵니다.

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

  1. 터미널을 열고 StringLibrary 및 ShowCase 프로젝트가 포함된 자습서 폴더로 이동합니다.

  2. 새 MSTest 테스트 프로젝트를 만듭니다.

    dotnet new mstest -n StringLibraryTest
    

    프로젝트 템플릿은 다음 코드를 사용하여 StringLibraryTest/Test1.cs 만듭니다.

    namespace StringLibraryTest;
    
    [TestClass]
    public class Test1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    

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

    • 클래스에 특성을 적용합니다.
    • 정의할 특성을 적용합니다.
    • 단위 테스트에 사용되는 형식을 포함하는 네임스페이스를 가져옵니다.

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

프로젝트 참조 추가

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

  1. 솔루션 탐색기 StringLibraryTest 프로젝트의 >Dependencies 노드를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 프로젝트 참조 추가를 선택합니다.

  2. 참조 관리자 대화 상자에서 StringLibrary 옆에 있는 상자를 선택합니다.

    StringLibraryTest에 대한 프로젝트 참조로 StringLibrary를 추가합니다.

  3. 확인을 선택합니다.

  1. 솔루션 탐색기 'StringLibraryTest' 프로젝트를 마우스 오른쪽 단추로 클릭하고 프로젝트 참조 추가 선택합니다.

  2. "StringLibrary"를 선택합니다.

  1. StringLibraryTest 폴더로 이동하고 프로젝트 참조를 추가합니다.

    cd StringLibraryTest
    dotnet add reference ../StringLibrary/StringLibrary.csproj
    

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

단위 테스트가 실행되면 특성으로 표시된 클래스의 특성으로 표시된 각 메서드가 자동으로 실행됩니다. 첫 번째 오류가 발견되거나 메서드에 포함된 모든 테스트가 성공하면 테스트 메서드가 종료됩니다.

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

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

테스트 메서드에서 메서드를 사용하여 발생할 것으로 예상되는 예외 유형을 나타낼 수도 있습니다. 지정된 예외가 throw되지 않으면 테스트가 실패합니다.

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

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

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

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

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

    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public sealed class Test1
        {
            [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, $"Expected for '{word}': true; Actual: {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, $"Expected for '{word}': false; Actual: {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, $"Expected for '{word ?? "<null>"}': false; Actual: {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
    

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

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

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

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

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

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

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

  1. StringLibraryTest/Test1.cs 열고 모든 코드를 다음 코드로 바꿉 있습니다.

    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public sealed class Test1
        {
            [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, $"Expected for '{word}': true; Actual: {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, $"Expected for '{word}': false; Actual: {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, $"Expected for '{word ?? "<null>"}': false; Actual: {result}");
                }
            }
        }
    }
    

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

  2. 변경 내용을 저장합니다.

테스트 빌드 및 실행

  1. 솔루션 탐색기 솔루션을 마우스 오른쪽 단추로 클릭하고 Build 또는 명령 팔레트에서 .NET: 빌드 선택합니다.

  2. 테스트 창을 선택하고 테스트 실행을 선택하거나 명령 팔레트에서 테스트: 모든 테스트 실행을 선택합니다.

    Visual Studio Code 테스트 탐색기

  1. StringLibraryTest/Test1.cs 열고 모든 코드를 다음 코드로 바꿉 있습니다.

    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public sealed class Test1
        {
            [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, $"Expected for '{word}': true; Actual: {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, $"Expected for '{word}': false; Actual: {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, $"Expected for '{word ?? "<null>"}': false; Actual: {result}");
                }
            }
        }
    }
    

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

  2. 변경 내용을 저장하고 테스트를 실행합니다.

    dotnet test
    

    테스트는 통과해야 합니다.

테스트 오류 처리

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

  1. "Error" 문자열을 포함하도록 메서드의 배열을 수정합니다.

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

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

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

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

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

  1. 편집기에서 테스트 옆에 있는 녹색 오류를 클릭하여 테스트를 실행합니다.

    출력은 테스트가 실패했음을 보여 줍니다. 그리고 실패한 테스트에 대한 오류 메시지를 제공합니다. "Assert.IsFalse가 실패했습니다. 'Error'에 대한 예상: false; 실제: true". 오류로 인해 "Error" 이후 배열의 문자열이 테스트되지 않았습니다.

    Visual Studio Code 실패한 테스트

  1. 테스트를 실행합니다.

    dotnet test
    

    출력은 테스트가 실패했음을 보여 줍니다. 그리고 실패한 테스트에 대한 오류 메시지를 제공합니다. "Assert.IsFalse가 실패했습니다. 'Error'의 기대: false; 실제: True". 오류로 인해 "Error" 이후 배열의 문자열이 테스트되지 않았습니다.

  1. 추가한 문자열 "Error"를 제거합니다.

  2. 테스트를 다시 실행하고 테스트가 통과합니다.

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

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

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

  1. Visual Studio 도구 모음에서 빌드 구성을 Debug에서 Release 변경합니다.

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

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

릴리스 빌드 구성을 사용하여 테스트를 실행합니다.

dotnet test StringLibraryTest/StringLibraryTest.csproj --configuration Release

테스트가 통과합니다.

릴리스 빌드 구성을 사용하여 테스트를 실행합니다.

dotnet test --configuration Release

테스트가 통과합니다.

디버그 테스트

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

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

Visual Studio Code IDE로 사용하는 경우 .NET 콘솔 애플리케이션에 표시된 것과 동일한 프로세스를 사용하여 단위 테스트 프로젝트를 사용하여 코드를 디버그할 수 있습니다. ShowCase 앱 프로젝트를 시작하는 대신 StringLibraryTest/Test1.cs 열고 7줄과 8줄 사이의 현재 파일에서 디버그 테스트를 선택합니다. 찾을 수 없는 경우 CtrlShiftP 를 눌러 명령 팔레트를 열고 창 다시 로드를 입력합니다.

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

추가 리소스

리소스 정리

GitHub 비활성 30일 후에 Codespace를 자동으로 삭제합니다. 이 시리즈에서 더 많은 자습서를 탐색하려는 경우 Codespace를 프로비전된 상태로 둘 수 있습니다. .NET 사이트 방문하여 .NET SDK를 다운로드할 준비가 되면 Codespace를 삭제할 수 있습니다. Codespace를 삭제하려면 브라우저 창을 열고 Codespaces로 이동합니다. 창에 코드스페이스 목록이 표시됩니다. 학습 자습서 코드스페이스에 대한 항목에서 세 개의 점()을 선택합니다. 그런 다음, "삭제"를 선택합니다.

다음 단계:

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

dotnet CLI를 사용하여 패키지 만들기 및 게시

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

dotnet CLI를 사용하여 패키지 설치 및 사용

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