1. 개요
단위 테스트를 할 때 주기적으로 테스트 메서드 실행 결과를 처리하기를 원할 수 있습니다. 이 빠른 사용방법(예제)에서는 JUnit에서 제공하는 TestWatcher API를 사용하여 이를 수행하는 방법을 살펴보겠습니다 .
JUnit을 사용한 테스트에 대한 심층적인 사용방법(예제)는 훌륭한 JUnit 5 사용방법(예제)를 확인하세요 .
2. TestWatcher API
간단히 말해서 TestWatcher 인터페이스는 테스트 결과를 처리하려는 확장에 대한 API를 정의합니다 . 이 API를 생각할 수 있는 한 가지 방법은 개별 테스트 케이스의 상태를 가져오기 위한 후크를 제공하는 것입니다.
그러나 실제 예를 살펴 보기 전에 한 걸음 물러나서 TestWatcher 인터페이스 의 메서드를 간략하게 요약해 보겠습니다 .
-
testAborted(ExtensionContext context, Throwable cause)
중단된 테스트의 결과를 처리하기 위해 testAborted 메소드를 재정의할 수 있습니다 . 이름에서 알 수 있듯이 이 메서드는 테스트가 중단된 후에 호출됩니다.
-
testDisabled(ExtensionContext context, Optional reason)
비활성화된 테스트 메서드의 결과를 처리하려는 경우 testDisabled 메서드를 재정의할 수 있습니다 . 이 방법에는 테스트가 비활성화된 이유도 포함될 수 있습니다.
-
testFailed(ExtensionContext context, Throwable cause)
테스트 실패 후 추가 처리를 수행하려면 testFailed 메서드 에서 기능을 구현하면 됩니다 . 이 방법에는 테스트 실패의 원인이 포함될 수 있습니다.
-
testSuccessful(ExtensionContext context)
마지막으로 성공적인 테스트 결과를 처리하려면 testSuccessful 메서드 를 재정의하면 됩니다 .
모든 메소드에는 ExtensionContext가 포함되어 있다는 점에 유의해야 합니다 . 이것은 현재 테스트가 실행된 컨텍스트를 캡슐화합니다.
3. 메이븐 의존성
우선, 예제에 필요한 프로젝트 의존성을 추가해 보겠습니다.
기본 JUnit 5 라이브러리 junit-jupiter-engine 외에도 junit-jupiter-api 라이브러리 도 필요합니다 .
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
항상 그렇듯이 Maven Central 에서 최신 버전을 얻을 수 있습니다 .
4. TestResultLoggerExtension 예제
이제 TestWatcher API에 대한 기본적인 이해를 하였으므로 실제 예제를 살펴보겠습니다.
결과를 기록하고 테스트 요약을 제공하기 위한 간단한 확장을 만드는 것으로 시작하겠습니다 . 이 경우 확장을 생성하려면 TestWatcher 인터페이스 를 구현하는 클래스를 정의해야 합니다 .
public class TestResultLoggerExtension implements TestWatcher, AfterAllCallback {
private List<TestResultStatus> testResultsStatus = new ArrayList<>();
private enum TestResultStatus {
SUCCESSFUL, ABORTED, FAILED, DISABLED;
}
//...
}
모든 확장 인터페이스와 마찬가지로 TestWatcher 인터페이스는 마커 인터페이스일 뿐인 기본 확장 인터페이스 도 확장합니다 . 이 예에서는 AfterAllCallback 인터페이스 도 구현합니다 .
확장 프로그램 에는 테스트 결과의 상태를 나타내는 데 사용할 간단한 열거 인 TestResultStatus List이 있습니다.
4.1. 테스트 결과 처리
이제 개별 단위 테스트 방법의 결과를 처리하는 방법을 살펴보겠습니다.
@Override
public void testDisabled(ExtensionContext context, Optional<String> reason) {
LOG.info("Test Disabled for test {}: with reason :- {}",
context.getDisplayName(),
reason.orElse("No reason"));
testResultsStatus.add(TestResultStatus.DISABLED);
}
@Override
public void testSuccessful(ExtensionContext context) {
LOG.info("Test Successful for test {}: ", context.getDisplayName());
testResultsStatus.add(TestResultStatus.SUCCESSFUL);
}
확장의 본문을 채우고 testDisabled() 및 testSuccessful() 메서드를 재정의하는 것으로 시작 합니다 .
간단한 예제에서는 테스트 이름을 출력하고 테스트 상태를 testResultsStatus List 에 추가 합니다.
testAborted() 및 testFailed() 의 다른 두 가지 방법에 대해 이 방식으로 계속 진행합니다 .
@Override
public void testAborted(ExtensionContext context, Throwable cause) {
LOG.info("Test Aborted for test {}: ", context.getDisplayName());
testResultsStatus.add(TestResultStatus.ABORTED);
}
@Override
public void testFailed(ExtensionContext context, Throwable cause) {
LOG.info("Test Failed for test {}: ", context.getDisplayName());
testResultsStatus.add(TestResultStatus.FAILED);
}
4.2. 테스트 결과 요약
예제의 마지막 부분 에서 afterAll() 메서드를 재정의합니다 .
@Override
public void afterAll(ExtensionContext context) throws Exception {
Map<TestResultStatus, Long> summary = testResultsStatus.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
LOG.info("Test result summary for {} {}", context.getDisplayName(), summary.toString());
}
빠르게 요약하자면 모든 테스트 메서드가 실행된 후 afterAll 메서드가 실행됩니다. 이 방법을 사용 하여 매우 기본적인 요약을 출력하기 전에 테스트 결과 List에 있는 다른 TestResultStatus 를 그룹화합니다 .
수명 주기 콜백에 대한 심층 사용방법(예제)는 JUnit 5 확장에 대한 훌륭한 사용방법(예제)를 확인하세요 .
5. 테스트 실행
이 끝에서 두 번째 섹션에서는 간단한 로깅 확장을 사용하여 테스트의 출력이 어떻게 보이는지 확인할 것입니다.
확장을 정의했으므로 먼저 표준 @ExtendWith 어노테이션을 사용하여 확장을 등록합니다 .
@ExtendWith(TestResultLoggerExtension.class)
class TestWatcherAPIUnitTest {
@Test
void givenFalseIsTrue_whenTestAbortedThenCaptureResult() {
Assumptions.assumeTrue(false);
}
@Disabled
@Test
void givenTrueIsTrue_whenTestDisabledThenCaptureResult() {
Assert.assertTrue(true);
}
//...
다음으로, 비활성화된 테스트, 중단된 테스트 및 성공적인 테스트를 혼합하여 테스트 클래스를 단위 테스트로 채웁니다.
5.1. 출력 검토
단위 테스트를 실행할 때 각 테스트의 출력을 확인해야 합니다.
INFO c.b.e.t.TestResultLoggerExtension -
Test Successful for test givenTrueIsTrue_whenTestAbortedThenCaptureResult()
...
Test result summary for TestWatcherAPIUnitTest {ABORTED=1, SUCCESSFUL=1, DISABLED=2}
당연히 모든 테스트 방법이 완료되면 요약이 인쇄되는 것을 볼 수 있습니다.
6. 잡다한 것들
이 마지막 섹션에서는 TestWatcher 인터페이스로 작업할 때 알아야 할 몇 가지 미묘함을 검토해 보겠습니다 .
- TestWatcher 확장은 테스트 실행에 영향을 줄 수 없습니다. 이것은 TestWatcher 에서 예외가 발생 하면 실행 중인 테스트까지 전파되지 않음을 의미합니다.
- 현재 이 API는 @Test 메서드 및 @TestTemplate 메서드 의 결과를 보고하는 데만 사용됩니다.
- 기본적으로 testDisabled 메소드에 이유가 제공되지 않으면 테스트 메소드의 정규화된 이름 뒤에 ' is @Disabled '가 포함됩니다.
7. 결론
요약하자면 이 예제에서는 JUnit 5 TestWatcher API를 사용하여 테스트 메소드 실행 결과를 처리하는 방법을 보여 주었습니다 .
예제의 전체 소스 코드는 GitHub 에서 찾을 수 있습니다 .