다음을 통해 공유


Live Unit Testing을 시작하기

Visual Studio 솔루션에서 Live Unit Testing을 사용하도록 설정하면 테스트 검사 및 테스트 상태를 시각적으로 보여 줍니다. 또한 Live Unit Testing은 코드를 수정할 때마다 테스트를 동적으로 실행하고 변경으로 인해 테스트가 실패할 때 즉시 알 수 있습니다.

Live Unit Testing을 사용하여 .NET Framework, .NET Core 또는 .NET 5+를 대상으로 하는 솔루션을 테스트할 수 있습니다. 이 자습서에서는 .NET을 대상으로 하는 간단한 클래스 라이브러리를 만들어 Live Unit Testing을 사용하는 방법을 알아보고 테스트할 .NET을 대상으로 하는 MSTest 프로젝트를 만듭니다.

전체 C# 솔루션은 GitHub의 MicrosoftDocs/visualstudio-docs 리포지토리에서 다운로드할 수 있습니다.

필수 구성 요소

이 자습서에서는 .NET 데스크톱 개발 워크로드를 사용하여 Visual Studio Enterprise 버전을 설치해야 합니다.

솔루션 및 클래스 라이브러리 프로젝트 만들기

먼저 단일 .NET 클래스 라이브러리 프로젝트인 StringLibrary로 구성된 UtilityLibraries라는 Visual Studio 솔루션을 만듭니다.

솔루션은 하나 이상의 프로젝트에 대한 컨테이너일 뿐입니다. 빈 솔루션을 만들려면 Visual Studio를 열고 다음을 수행합니다.

  1. 최상위 Visual Studio 메뉴에서 파일>>프로젝트 선택합니다.

  2. 템플릿 검색 상자에 솔루션 입력한 다음 빈 솔루션 템플릿을 선택합니다. 프로젝트 이름을 UtilityLibraries으로 설정하십시오.

  3. 솔루션 만들기를 완료합니다.

이제 솔루션을 만들었으므로 문자열 작업을 위한 다양한 확장 메서드가 포함된 StringLibrary라는 클래스 라이브러리를 만듭니다.

  1. 솔루션 탐색기에서 UtilityLibraries 솔루션을 마우스 오른쪽 단추로 클릭한 후, 추가>새 프로젝트을 선택합니다.

  2. 템플릿 검색 상자에 클래스 라이브러리 입력하고 .NET 또는 .NET Standard를 대상으로 하는 클래스 라이브러리 템플릿을 선택합니다. 다음클릭합니다.

  3. 프로젝트의 이름을 StringLibrary로 지정하십시오.

  4. 프로젝트를 만들려면 만들기를 클릭하시기 바랍니다.

  5. 코드 편집기의 모든 기존 코드를 다음 코드로 바꿉다.

    using System;
    
    namespace UtilityLibraries
    {
        public static class StringLibrary
        {
            public static bool StartsWithUpper(this string s)
            {
                if (String.IsNullOrWhiteSpace(s))
                    return false;
    
                return Char.IsUpper(s[0]);
            }
    
            public static bool StartsWithLower(this string s)
            {
                if (String.IsNullOrWhiteSpace(s))
                    return false;
    
                return Char.IsLower(s[0]);
            }
    
            public static bool HasEmbeddedSpaces(this string s)
            {
                foreach (var ch in s.Trim())
                {
                    if (ch == ' ')
                        return true;
                }
                return false;
            }
        }
    }
    

    StringLibrary에는 세 가지 정적 메서드가 있습니다.

    • StartsWithUpper 문자열이 대문자로 시작하는 경우 true 반환합니다. 그렇지 않으면 false반환됩니다.

    • StartsWithLower 문자열이 소문자로 시작하는 경우 true 반환합니다. 그렇지 않으면 false반환됩니다.

    • HasEmbeddedSpaces 문자열에 포함된 공백 문자가 포함된 경우 true 반환합니다. 그렇지 않으면 false반환됩니다.

  6. 최상위 Visual Studio 메뉴에서 빌드>빌드 솔루션 선택합니다. 빌드는 성공할 것입니다.

테스트 프로젝트 만들기

다음 단계는 StringLibrary 라이브러리를 테스트하는 단위 테스트 프로젝트를 만드는 것입니다. 다음 단계를 수행하여 단위 테스트를 만듭니다.

  1. 솔루션 탐색기에서 UtilityLibraries 솔루션을 마우스 오른쪽 버튼으로 클릭하고, 새 프로젝트>추가를 선택합니다.

  2. 템플릿 검색 상자에 단위 테스트 입력하고, 언어로 C# 선택한 다음, .NET 템플릿에 MSTest 단위 테스트 프로젝트 선택합니다. 다음클릭합니다.

    메모

    Visual Studio 2019 버전 16.9에서 MSTest 프로젝트 템플릿 이름은 단위 테스트 프로젝트 .

  3. 프로젝트 이름을 StringLibraryTests 이름을 지정하고 다음클릭합니다.

  4. 권장 대상 프레임워크 또는 .NET 8을 선택한 다음 만들기선택합니다.

    메모

    이 시작 자습서에서는 MSTest 테스트 프레임워크에서 Live Unit Testing을 사용합니다. xUnit 및 NUnit 테스트 프레임워크를 사용할 수도 있습니다.

  5. 단위 테스트 프로젝트는 테스트 중인 클래스 라이브러리에 자동으로 액세스할 수 없습니다. 클래스 라이브러리 프로젝트에 대한 참조를 추가하여 테스트 라이브러리 액세스 권한을 부여합니다. 이렇게 하려면 StringLibraryTests 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가>프로젝트 참조선택합니다. 참조 관리자 대화 상자에서 솔루션 탭이 선택되어 있는지 확인하고 다음 그림과 같이 StringLibrary 프로젝트를 선택합니다.

    참조 관리자 대화

    참조 관리자 대화

  6. 템플릿에서 제공하는 기본 단위 테스트 코드를 다음 코드로 바꿉니다.

    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    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,
                                  $"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 ? "<null>" : word)}': " +
                                   $"false; Actual: {result}");
                }
            }
        }
    }
    
  7. 도구 모음에서 저장 아이콘을 선택하여 프로젝트를 저장합니다.

    단위 테스트 코드에는 ASCII가 아닌 일부 문자가 포함되어 있으므로 파일을 기본 ASCII 형식으로 저장하면 일부 문자가 손실된다는 경고 대화 상자가 표시됩니다.

  8. "다른 인코딩 으로 저장 단추를 선택합니다."

    파일 인코딩 선택

    파일 인코딩 선택

  9. 고급 저장 옵션 대화 상자의 인코딩 드롭다운 목록에서 다음 그림과 같이 유니코드(서명이 없는 UTF-8) - Codepage 65001선택합니다.

    UTF-8 인코딩 선택

  10. 최상위 Visual Studio 메뉴에서 빌드>솔루션 다시 빌드 선택하여 단위 테스트 프로젝트를 컴파일합니다.

클래스 라이브러리와 몇 가지 단위 테스트를 만들었습니다. 이제 Live Unit Testing을 사용하는 데 필요한 예비 작업을 완료했습니다.

라이브 유닛 테스트 활성화

지금까지 StringLibrary 클래스 라이브러리에 대한 테스트를 작성했지만 실행하지 않았습니다. Live Unit Testing은 사용하도록 설정하면 자동으로 실행됩니다. 이렇게 하려면 다음을 수행합니다.

  1. 필요에 따라 StringLibrary에 대한 코드가 포함된 코드 편집기 창을 선택합니다. 이는 C# 프로젝트에 대한 Class1.cs 또는 Visual Basic 프로젝트의 Class1.vb. (이 단계를 사용하면 Live Unit Testing을 사용하도록 설정한 후 테스트 결과 및 코드 검사 범위를 시각적으로 검사할 수 있습니다.)

  2. Visual Studio 최상위 메뉴에서 테스트>Live Unit Testing>시작 선택합니다.

  3. 리포지토리 루트에 유틸리티 프로젝트와 테스트 프로젝트 모두에 대한 원본 파일 경로가 포함되어 있는지 확인하여 Live Unit Testing에 대한 구성을 확인합니다. 다음 을 선택한 다음, 마침 을 선택합니다.

  1. Live Unit Testing 창에서 모든 테스트 링크를 포함할 선택합니다(또는 재생 목록 단추 아이콘을 선택한 다음, 그 아래에 있는 모든 테스트를 선택하는 StringLibraryTest선택합니다. 그런 다음 재생 목록 단추를 선택 취소하여 편집 모드를 종료합니다.)

  2. Visual Studio는 프로젝트를 다시 빌드하고 모든 테스트를 자동으로 실행하는 Live Unit Test를 시작합니다.

  1. Visual Studio는 프로젝트를 다시 빌드하고 모든 테스트를 자동으로 실행하는 Live Unit Test를 시작합니다.

테스트 실행이 완료되면 Live Unit Testing 전체 결과와 개별 테스트 결과를 모두 표시합니다. 또한 코드 편집기 창에는 테스트 코드 검사와 테스트 결과가 모두 그래픽으로 표시됩니다. 다음 그림과 같이 세 가지 테스트가 모두 성공적으로 실행되었습니다. 또한 테스트가 StartsWithUpper 메서드의 모든 코드 경로를 다루었으며 해당 테스트가 모두 성공적으로 실행되었음을 보여 줍니다(녹색 확인 표시 "✓"로 표시됨). 마지막으로 StringLibrary의 다른 메서드에는 코드 검사(파란색 선 ➖ ""로 표시됨)가 없음을 보여 줍니다.

"라이브 유닛 테스트를 시작한 후, 라이브 테스트 탐색기와 코드 편집기 창 "

라이브 유닛 테스트를 시작한 후 라이브 테스트 탐색기와 코드 편집기 창

코드 편집기 창에서 특정 코드 검사 아이콘을 선택하여 테스트 검사 및 테스트 결과에 대한 자세한 정보를 얻을 수도 있습니다. 이 세부 정보를 검사하려면 다음을 수행합니다.

  1. StartsWithUpper 메서드에서 if (String.IsNullOrWhiteSpace(s)) 읽는 줄에서 녹색 확인 표시를 클릭합니다. 다음 그림에서 알 수 있듯이 Live Unit Testing은 세 가지 테스트가 해당 코드 줄을 포함하며 모두 성공적으로 실행되었음을 나타냅니다.

    if 조건문코드 검사

    if 조건문코드 검사

  2. StartsWithUpper 메서드에서 return Char.IsUpper(s[0]) 읽는 줄에서 녹색 확인 표시를 클릭합니다. 다음 그림에서 알 수 있듯이 Live Unit Testing은 두 개의 테스트만 해당 코드 줄을 포함하며 모두 성공적으로 실행되었음을 나타냅니다.

    반환문에 대한 코드 커버리지

    반환 문코드 커버리지

Live Unit Testing에서 식별하는 주요 문제는 불완전한 코드 검사입니다. 다음 섹션에서 해결합니다.

테스트 커버리지 확장

이 섹션에서는 단위 테스트를 StartsWithLower 메서드로 확장합니다. 이렇게 하는 동안 Live Unit Testing은 코드를 동적으로 계속 테스트합니다.

코드 검사를 StartsWithLower 메서드로 확장하려면 다음을 수행합니다.

  1. 프로젝트의 테스트 소스 코드 파일에 다음 TestStartsWithLowerTestDoesNotStartWithLower 메서드를 추가합니다.

    // Code to add to UnitTest1.cs
    [TestMethod]
    public void TestStartsWithLower()
    {
        // Tests that we expect to return true.
        string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство" };
        foreach (var word in words)
        {
            bool result = word.StartsWithLower();
            Assert.IsTrue(result,
                          $"Expected for '{word}': true; Actual: {result}");
        }
    }
    
    [TestMethod]
    public void TestDoesNotStartWithLower()
    {
        // Tests that we expect to return false.
        string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва",
                           "1234", ".", ";", " "};
        foreach (var word in words)
        {
            bool result = word.StartsWithLower();
            Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}");
        }
    }
    
  2. Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse 메서드를 호출한 직후에 다음 코드를 추가하여 DirectCallWithNullOrEmpty 메서드를 수정합니다.

    // Code to add to UnitTest1.cs
    result = StringLibrary.StartsWithLower(word);
    Assert.IsFalse(result,
                   $"Expected for '{(word == null ? "<null>" : word)}': " +
                   $"false; Actual: {result}");
    
  3. Live Unit Testing은 소스 코드를 수정할 때 새 테스트와 수정된 테스트를 자동으로 실행합니다. 다음 그림에서 볼 수 있듯이 추가한 두 테스트와 수정한 테스트를 포함한 모든 테스트가 성공했습니다.

    라이브 테스트 탐색기 테스트 범위 확장 후

    라이브 테스트 탐색기 테스트 범위 확장 후

  4. StringLibrary 클래스의 소스 코드가 포함된 창으로 전환합니다. 이제 Live Unit Testing은 코드 검사 범위가 StartsWithLower 메서드로 확장되었음을 보여줍니다.

    StartsWithLower 메서드코드 커버리지

    StartsWithLower 메서드의 코드 커버리지

경우에 따라 테스트 탐색기 성공한 테스트가 회색으로 표시될 수 있습니다. 즉, 테스트가 현재 실행 중이거나 마지막으로 실행된 이후 테스트에 영향을 주는 코드 변경 내용이 없기 때문에 테스트가 다시 실행되지 않음을 나타냅니다.

지금까지 모든 테스트가 성공했습니다. 다음 섹션에서는 테스트 실패를 처리하는 방법을 살펴보겠습니다.

테스트 오류 처리

이 섹션에서는 Live Unit Testing을 사용하여 테스트 실패를 식별, 문제 해결 및 해결하는 방법을 살펴봅니다. 테스트 범위를 HasEmbeddedSpaces 메서드로 확장하여 이 작업을 수행합니다.

  1. 테스트 파일에 다음 메서드를 추가합니다.

    [TestMethod]
    public void TestHasEmbeddedSpaces()
    {
        // Tests that we expect to return true.
        string[] phrases = { "one car", "Name\u0009Description",
                             "Line1\nLine2", "Line3\u000ALine4",
                             "Line5\u000BLine6", "Line7\u000CLine8",
                             "Line0009\u000DLine10", "word1\u00A0word2" };
        foreach (var phrase in phrases)
        {
            bool result = phrase.HasEmbeddedSpaces();
            Assert.IsTrue(result,
                          $"Expected for '{phrase}': true; Actual: {result}");
        }
    }
    
  2. 테스트가 실행되면 Live Unit Testing은 다음 그림과 같이 TestHasEmbeddedSpaces 메서드가 실패했음을 나타냅니다.

    라이브 테스트 탐색기 이 실패한 테스트을 보고합니다.

    라이브 테스트 탐색기 가 실패한 테스트를 보고합니다.

  3. 라이브러리 코드를 표시하는 창을 선택합니다. Live Unit Testing은 코드 범위를 HasEmbeddedSpaces 메서드로 확장했습니다. 또한 실패한 테스트가 적용되는 줄에 빨간색 "🞩"을 추가하여 테스트 실패를 보고합니다.

  4. HasEmbeddedSpaces 메서드 시그니처를 사용하여 선 위로 마우스를 가져다 킵니다. Live Unit Testing은 다음 그림과 같이 메서드가 한 테스트에서 처리된다는 것을 보고하는 도구 설명을 표시합니다.

    실패한 테스트

    실패한 테스트

  5. TestHasEmbeddedSpaces 테스트에 실패한 선택합니다. Live Unit Testing은 다음 그림과 같이 모든 테스트 실행 및 모든 테스트 디버깅과 같은 몇 가지 옵션을 제공합니다.

    실패한 테스트에 대한 Live Unit Testing 옵션

    실패한 테스트에 대한 Live Unit Testing 옵션.

  6. 실패한 테스트를 디버그하려면 Debug All을 선택하십시오.

  7. Visual Studio는 디버그 모드에서 테스트를 실행합니다.

    이 테스트는 배열의 각 문자열을 phrase 변수에 할당하고 HasEmbeddedSpaces 메서드에 전달합니다. 어설션 식이 처음으로 false일 때 프로그램 실행이 일시 중지되고 디버거가 호출됩니다. Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue 메서드 호출에서 예기치 않은 값으로 인해 발생하는 예외 대화 상자는 다음 그림에 나와 있습니다.

    Live Unit Testing 예외 대화상자

    Live Unit Testing 예외 대화 상자

    또한 다음 그림과 같이 Visual Studio에서 제공하는 모든 디버깅 도구를 사용하여 실패한 테스트 문제를 해결할 수 있습니다.

    visual Studio 디버깅 도구

    visual Studio 디버깅 도구

    자동 창에서 phrase 변수의 값은 배열의 두 번째 요소인 "Name\tDescription"입니다. 테스트 메서드는 이 문자열을 전달할 때 HasEmbeddedSpacestrue 반환해야 합니다. 대신 false반환합니다. 분명히 탭 문자인 "\t"는 포함된 공간으로 인식되지 않습니다.

  8. 디버그>계속선택하고 F5 누르거나 도구 모음에서 계속 단추를 클릭하여 테스트 프로그램을 계속 실행합니다. 처리되지 않은 예외가 발생했기 때문에 테스트가 종료됩니다. 이렇게 하면 버그에 대한 예비 조사를 위한 충분한 정보가 제공됩니다. TestHasEmbeddedSpaces(테스트 루틴)가 잘못된 가정을 했거나 HasEmbeddedSpaces 포함된 모든 공간을 올바르게 인식하지 못합니다.

  9. 문제를 진단하고 해결하려면 StringLibrary.HasEmbeddedSpaces 메서드로 시작합니다. HasEmbeddedSpaces 메서드에서 비교를 확인합니다. 포함된 공간을 U+0020으로 간주합니다. 그러나 유니코드 표준에는 여러 다른 공백 문자가 포함됩니다. 이는 라이브러리 코드가 공백 문자에 대해 잘못 테스트되었음을 시사합니다.

  10. 같음 비교를 System.Char.IsWhiteSpace 메서드에 대한 호출로 바꿉니다.

    if (Char.IsWhiteSpace(ch))
    
  11. Live Unit Testing은 실패한 테스트 방법을 자동으로 다시 실행합니다.

    Live Unit Testing은 업데이트된 결과가 표시되며 코드 편집기 창에도 표시됩니다.