주요 콘텐츠로 건너뛰기 이 브라우저는 더 이상 지원되지 않습니다. Show 최신 기능, 보안 업데이트, 기술 지원을 이용하려면 Microsoft Edge로 업그레이드하세요. .NET Core 및.NET 표준을 사용하는 단위 테스트 모범 사례
이 문서의 내용단위 테스트를 작성할 때는 다양한 이점이 있습니다. 회귀를 돕고, 설명서를 제공하고, 좋은 디자인을 용이하게 합니다. 그러나 읽기 어렵고 불안정한 단위 테스트는 코드 기반을 파괴할 수 있습니다. 이 문서에서는.NET Core 및 .NET 표준 프로젝트용 단위 테스트 디자인과 관련된 몇 가지 모범 사례를 설명합니다. 이 가이드에서는 복원력과 이해하기 쉬운 테스트를 유지하기 위해 단위 테스트를 작성할 때 몇 가지 모범 사례를 알아봅니다. John Reese, Roy Osherove에 대한 특별한 감사 단위 테스트하는 이유는?기능 테스트 수행 시간 단축기능 테스트는 비용이 많이 듭니다. 일반적으로 애플리케이션을 열고 예상 동작의 유효성을 검사하기 위해 사용자(또는 다른 사람)가 따라야 하는 일련의 단계를 수행하는 작업이 포함됩니다. 이러한 단계는 테스터에게 항상 알려지지 않을 수 있습니다. 그들은 테스트를 수행하기 위해 지역에서 더 지식이 있는 사람에게 손을 내밀어야 합니다. 테스트 자체는 사소한 변경인 경우에는 몇 초가 걸리거나 큰 변경의 경우에는 몇 분 정도 걸릴 수 있습니다. 마지막으로, 이 프로세스는 시스템에서 수행하는 모든 변경 사항에 대해 반복되어야 합니다. 반면에 단위 테스트는 밀리초가 소요되고 단추를 눌러 실행할 수 있으며 시스템 전체에 대한 정보가 반드시 필요하지는 않습니다. 테스트 통과 또는 실패 여부는 개인이 아닌 test runner의 몫입니다. 회귀에 대한 보호회귀 오류는 애플리케이션이 변경될 때 도입된 결함입니다. 테스터는 새 기능을 테스트할 뿐만 아니라 이전에 구현된 기능이 여전히 예상대로 작동하는지 확인하기 위해 기존 기능을 테스트하는 것이 일반적입니다. 단위 테스트를 사용하면 모든 빌드 후에 또는 코드 줄을 변경한 후에도 전체 테스트 도구 모음을 다시 실행할 수 있습니다. 새 코드가 기존 기능을 중단하지 않는다는 확신을 줍니다. 실행 가능한 설명서특정 입력이 제공된 경우 특정 메서드가 수행하는 작업이나 동작 방식이 항상 명확하지는 않을 수 있습니다. 빈 문자열을 전달하면 이 메서드가 어떻게 동작하나요? Null? 이름이 잘 지정된 단위 테스트의 도구 모음이 있는 경우 각 테스트는 지정된 입력에 대해 예상되는 출력을 명확하게 설명할 수 있어야 합니다. 또한 실제로 작동하는지 확인할 수 있어야 합니다. 적은 결합 코드코드가 밀접하게 결합되면 단위 테스트하기가 어려울 수 있습니다. 작성하는 코드에 대한 단위 테스트를 만들지 않으면 결합이 덜 분명해질 수 있습니다. 코드 테스트를 작성하면 자연스럽게 분리됩니다. 그렇지 않으면 테스트하기가 더 어려워지기 때문입니다. 좋은 단위 테스트의 특징
코드 검사높은 코드 검사 비율이 높으면 코드 품질이 높아지는 경우가 많습니다. 그러나 측정 자체는 코드 품질을 확인할 수 없습니다 . 코드 검사 비율 목표를 지나치게 욕심을 부려 높게 설정하면 역효과가 날 수 있습니다. 수천 개의 조건부 분기가 포함된 복잡한 프로젝트에서 95% 코드 검사 목표를 설정한다고 가정해 보세요. 현재 프로젝트에서는 90% 코드 검사를 유지합니다. 나머지 5%의 극단적인 경우를 모두 고려하는 데에는 엄청난 시간이 들 수 있으며 가치 제안의 중요성이 곧 낮아집니다. 높은 코드 검사 비율은 성공의 지표가 아니며 높은 코드 품질을 의미하지도 않습니다. 단위 테스트에서 검사되는 코드의 양을 나타낼 뿐입니다. 자세한 내용은 유닛 테스트 코드 검사를 참조하세요. 동일한 언어 사용mock이라는 용어는 불행히도 테스트에 대해 이야기할 때 종종 잘못 사용됩니다. 다음은 단위 테스트를 작성할 때 fakes의 가장 일반적인 유형을 정의합니다. Fake - fake는 스텁 또는 모의 개체를 설명하는 데 사용할 수 있는 일반적인 용어입니다. stub 또는 mock인지 여부는 사용되는 컨텍스트에 따라 달라집니다. 즉, fake는 stub 또는 mock이 될 수 있습니다. Mock - mock 개체는 단위 테스트가 통과되었는지 여부를 결정하는 시스템에서 fake 개체입니다. mock은 어설션될 때까지 fake로 시작합니다. Stub - stub은 시스템의 기존 종속성(또는 협력자)을 제어할 수 있는 대체품입니다. stub을 사용하여 종속성을 직접 처리하지 않고 코드를 테스트할 수 있습니다. 기본적으로 stub은 fake로 시작합니다. 다음 코드 조각을 살펴봅니다.
앞의 예제는 모의 스텁이라고 하는 스텁입니다. 이 경우 스텁입니다. 더 나은 방법은 다음과 같습니다.
클래스의 이름을 변경하여 클래스 모의 코드로 사용하려면 다음 코드와 같은 작업을 수행할 수 있습니다.
이 경우 Fake에서 속성을 확인하므로(이에 대해 어설션), 앞의 코드 조각 중요 이 용어를 올바르게 사용하는 것이 중요합니다. 스텁을 "모의 항목"이라고 부르는 경우 다른 개발자는 의도에 대해 거짓 가정을 할 것입니다. 모의 및 스텁에 대해 기억해야 할 중요한 점은 모의 항목이 스텁과 비슷하지만 모의 개체에 대해 어설션하는 반면 스텁에 대해 어설션하지 않는다는 것입니다. 최선의 구현 방법단위 테스트를 작성하는 경우 인프라에 대한 종속성을 도입하지 않습니다. 종속성을 사용하면 테스트 속도가 느리고 부서지기 쉬우며 통합 테스트를 위해 예약되어야 합니다. 명시적 종속성 원칙을 따르고 종속성 주입을 사용하여 애플리케이션에서 이러한 종속성을 방지할 수 있습니다. 통합 테스트의 개별 프로젝트에서 단위 테스트를 유지할 수도 있습니다. 이 방법을 사용하면 단위 테스트 프로젝트에 인프라 패키지에 대한 참조 또는 종속성이 없습니다. 테스트 이름 지정테스트의 이름은 다음 세 부분으로 구성되어야 합니다.
이유이름 지정 표준은 테스트의 의도를 명시적으로 표현하기 때문에 중요합니다. 테스트는 단순히 코드가 작동하는지 확인하는 것 이상이며, 문서도 제공합니다. 단위 테스트 도구 모음을 살펴봄으로써 코드 자체를 조회하지 않고도 코드의 동작을 유추할 수 있습니다. 또한 테스트가 실패하면 예상을 충족하지 않는 시나리오를 정확하게 확인할 수 있습니다. Bad:
Better:
테스트 정렬정렬, 동작, 어설션은 단위 테스트 시 일반적인 패턴입니다. 이름에서 알 수 있듯이 세 가지 주요 작업으로 구성됩니다.
이유
가독성은 테스트를 작성할 때 가장 중요한 측면 중 하나입니다. 테스트 내에서 이러한 각 작업을 구분하면 코드를 호출하는 데 필요한 종속성, 코드가 호출되는 방법 및 어설션하려는 항목이 명확하게 강조 표시됩니다. 몇 가지 단계를 결합하고 테스트 크기를 줄일 수 있지만, 주요 목표는 테스트를 가능한 한 읽을 수 있도록 하는 것입니다. Bad:
Better:
최소한의 테스트 통과 작성단위 테스트에 사용할 입력은 현재 테스트 중인 동작을 확인하기 위해 가능한 가장 간단해야 합니다. 이유
테스트를 통과하는 데 필요한 것보다 많은 정보를 포함하는 테스트는 테스트에 오류가 발생할 가능성이 높으며 테스트의 의도를 덜 명확하게 할 수 있습니다. 테스트를 작성할 때 동작에 집중하려고 합니다. 모델의 추가 속성을 설정하거나 필요하지 않을 때 0이 아닌 값을 사용하면 증명하려고 시도한 것만 손상됩니다. Bad:
Better:
매직 문자열 방지단위 테스트에서 변수 이름을 지정하는 것은 프로덕션 코드에서 변수 이름을 지정하는 것보다 더 중요하지 않은 경우 중요합니다. 단위 테스트에는 매직 문자열이 포함되어서는 안 됩니다. 이유
매직 문자열은 테스트 판독기에 혼동을 일으킬 수 있습니다. 문자열이 일반 값을 벗어나는 경우 매개 변수 또는 반환 값에 대해 특정 값을 선택한 이유가 궁금할 수 있습니다. 이러한 형식의 문자열 값은 테스트에 집중하지 않고 구현 세부 정보를 자세히 살펴볼 수 있습니다. 팁 테스트를 작성할 때는 가능한 한 많은 의도를 표현하는 것을 목표로 해야 합니다. 매직 문자열의 경우 좋은 방법은 이러한 값을 상수에 할당하는 것입니다. Bad:
Better:
테스트에서 논리 방지단위 테스트를 작성할 때는 수동 문자열 연결, 논리 조건(예: 이유
테스트 도구 모음에 논리를 도입하면 버그가 발생할 가능성이 크게 증가합니다. 버그를 찾고자 하는 마지막 위치는 테스트 도구 모음 내에 있습니다. 테스트가 작동한다는 높은 수준의 신뢰가 있어야 합니다. 그렇지 않으면 테스트를 신뢰하지 않습니다. 신뢰하지 않는 테스트는 값을 제공하지 않습니다. 테스트가 실패할 때 코드에 문제가 있고 무시할 수 없다는 느낌을 주려고 합니다. 팁 테스트의 논리가 불가피한 경우 테스트를 두 개 이상의 다른 테스트로 분할하는 것이 좋습니다. Bad:
Better:
설정 및 해제할 도우미 방법 선호테스트에 유사한 개체 또는 상태가 필요한 경우 사용 이유
단위 테스트 프레임워크에서 참고 xUnit은 버전 2.x에서 SetUp 및 TearDown을 모두 제거했습니다. Bad:
Better:
다중 동작 방지테스트를 작성할 때는 테스트당 하나의 작업만 포함하려고 합니다. 하나의 동작만 사용하는 일반적인 방법은 다음과 같습니다.
이유
여러 행위는 개별적으로 어설션되어야 하며 모든 어설션이 실행될 것이라고 보장되지는 않습니다. 대부분의 단위 테스트 프레임워크에서 단위 테스트에 어설션이 실패하면 절차 테스트는 자동으로 실패한 것으로 간주됩니다. 이러한 종류의 프로세스는 실제로 작동하는 기능이 실패로 표시되므로 혼동될 수 있습니다. Bad:
Better:
공용 메서드를 테스트하여 전용 메서드 유효성 검사대부분의 경우 프라이빗 메서드를 테스트할 필요가 없습니다. 프라이빗 메서드는 구현 세부 정보이며 격리된 상태로 존재하지 않습니다. 어떤 시점에서는 프라이빗 메서드를 구현의 일부로 호출하는 공용 연결 메서드가 있을 것입니다. 주의해야 할 것은 사적인 것을 호출하는 공용 메서드의 최종 결과입니다. 다음 경우를 참조하십시오.
첫 번째 반응은 메서드가 예상대로 작동하는지 확인하려고 하기 때문에 테스트 실제 테스트는 공용 연결 메서드
이 관점에서, 전용 메서드를 표시하는 경우 공용 메서드를 찾아 해당 메서드에 대해 테스트를 작성합니다. 프라이빗 메서드가 예상된 결과를 반환한다고 해서 결국 프라이빗 메서드를 호출하는 시스템이 결과를 올바르게 사용하는 것은 아닙니다. Stub 정적 참조단위 테스트의 원칙 중 하나는 테스트
중인 시스템을 완전히 제어해야 한다는 것입니다. 프로덕션 코드에 정적 참조(예
이 코드를 어떻게 단위 테스트할 수 있나요? 다음과 같은 방법을 시도할 수 있습니다.
아쉽게도 테스트에 몇 가지 문제가 있다는 것을 빠르게 알게 될 것입니다.
이러한 문제를 해결하려면 프로덕션 코드에 이음새를 도입해야 합니다. 한 가지 방법은 인터페이스에서 제어해야 하는 코드를 래핑하여 프로덕션 코드가 해당 인터페이스에 종속되도록 하는 것입니다.
이제 테스트 도구 모음이 다음과 같이 됩니다.
이제 테스트 도구 모음은 |