JUnit 5 가이드 핵심 요약

Rudy Lee (이재훈)·2021년 6월 24일
1
post-thumbnail

JUnit 5 가이드 핵심 요약

JUnit 5 공식 가이드 문서

※ 본 포스트는 제가 작성한 JUnit 5 공식 가이드 문서 정리의 핵심만 간추린 문서입니다.

JUnit 5 구조

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

  • JUnit Platform: JVM에서 Test Framework를 실행하기 위한 토대, Test Engine API 제공
  • JUnit Jupiter: 익스텐션 모델, Jupiter Test Engine
  • JUnit Vintage: JUnit 3와 JUnit 4 Test Engine

환경 설정

plugins {
	id 'java'
}

repositories {
	mavenCentral()
}

dependencies {
	testImplementation(platform('org.junit:junit-bom:5.7.2'))
	testImplementation('org.junit.jupiter:junit-jupiter')
}

test {
	useJUnitPlatform()
}

애노테이션

애노테이션대상용도상속 여부
@Test메서드일반 테스트O
@ParameterizedTest메서드파라미터 테스트O
@RepeatedTest메서드반복 테스트O
@TestFactory메서드다이나믹 테스트를 위한 테스트 팩토리O
@TestTemplate메서드테스트 케이스에 대한 템플릿O
@TestMethodOrder클래스테스트 메서드 실행 순서 설정O
@TestInstance클래스테스트 인스턴스 라이프사이클 설정O
@DisplayName클래스, 메서드표시 이름 지정X
@DisplayNameGeneration클래스표시 이름 생성기 지정O
@BeforeEach메서드각 테스트 메서드 실행 전 실행O
@AfterEach메서드각 테스트 메서드 실행 후 실행O
@BeforeAll메서드모든 테스트 메서드 실행 전 실행O
@AfterAll메서드모든 테스트 메서드 실행 후 실행O
@Nested클래스중첩 테스트 클래스X
@Tag클래스, 메서드태그 지정O
@Disabled클래스, 메서드테스트 비활성화X
@Timeout메서드타임아웃 지정O
@ExtendWith클래스익스텐션 등록O
@RegisterExtension클래스익스텐션 등록O
@TempDir클래스임시 디렉토리 지정X

테스트 구성 요소

  • 테스트 클래스: 테스트 메서드를 포함하고 있는 최상위 클래스
  • 테스트 메서드: @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, @TestTemplate
  • 라이프사이클 메서드: @BeforeAll, @AfterAll, @BeforeEach, @AfterEach

테스트 설정 파일

  • JVM 시스템 프로퍼티 또는 JUnit 플랫폼 설정 파일(src/test/resources/junit-platform.properties)로 제공

프로퍼티

기본

  • junit.jupiter.testmethod.order.default: 테스트 실행 순서 정렬 기본값 지정
  • junit.jupiter.testinstance.lifecycle.default: 테스트 인스턴스 라이프사이클 기본값 지정
  • junit.jupiter.displayname.generator.default: 표시 이름 생성기 기본값 지정
  • junit.jupiter.params.displayname.argument.maxlength: 인자 출력시 최대 길이 제한 설정

타임아웃

  • junit.jupiter.execution.timeout.default: 테스트 실행 타임아웃 기본값 설정
  • junit.jupiter.execution.timeout.mode: 타임 아웃 모드 설정
  • 개별 세부 설정 가능
    • junit.jupiter.execution.timeout.testable.method.default
    • junit.jupiter.execution.timeout.test.method.default
    • junit.jupiter.execution.timeout.testtemplate.method.default
    • junit.jupiter.execution.timeout.testfactory.method.default
    • junit.jupiter.execution.timeout.lifecycle.method.default
    • junit.jupiter.execution.timeout.beforeall.method.default
    • junit.jupiter.execution.timeout.beforeeach.method.default
    • junit.jupiter.execution.timeout.aftereach.method.default
    • junit.jupiter.execution.timeout.afterall.method.default

병렬 실행

  • junit.jupiter.execution.parallel.enabled: 병렬 실행 활성화 여부 설정
  • junit.jupiter.execution.parallel.mode.default: 병렬 실행 모드 지정
  • junit.jupiter.execution.parallel.mode.classes.default: 테스트 클래스의 병렬 실행 모드 지정
  • junit.jupiter.execution.parallel.config.strategy: 병렬성 전략 지정
    • junit.jupiter.execution.parallel.config.dynamic.factor: dynamic 모드시 사용할 factor
    • junit.jupiter.execution.parallel.config.fixed.parallelism: fixed 모드시 사용할 병렬성 지정
    • junit.jupiter.execution.parallel.config.custom.class: custom 모드시 사용할 전략 지정

익스텐션

  • junit.jupiter.extensions.autodetection.enabled: 익스텐션 자동 감지 활성화 여부 설정

조건부 실행

  • junit.jupiter.conditions.deactivate: 비활성화할 조건 패턴 지정

표준 출력 및 에러 캡쳐

  • junit.platform.output.capture.stdout: 표준 출력 캡쳐 여부 설정
  • junit.platform.output.capture.stderr: 표준 에러 캡쳐 여부 설정
  • junit.platform.output.capture.maxBuffer: 캡쳐시 최대 버퍼 사이즈 지정

단언

  • fail

    • fail(String|Supplier?, Throwable?)
    • 테스트를 실패 처리
    • 특정 Throwablecause로 넘길 수 있음
  • assertTrue

    • assertTrue(boolean|BooleanSupplier, String|Supplier?)
    • 제공된 인자가 true인지 검사
  • assertFalse

    • assertFalse(boolean|BooleanSupplier, String|Supplier?)
    • 제공된 인자가 false인지 검사
  • assertNull

    • assertNull(Object, String|Supplier?):
    • 제공된 객체가 null인지 검사
  • assertNotNull

    • assertNotNull(Object, String|Supplier?)
    • 제공된 객체가 null이 아닌지 검사
  • assertSame

    • assertSame(Object, Object, String|Supplier?)
    • 두 객체가 동일한 객체인지 검사
  • assertNotSame

    • assertNotSame(Object, Object, String|Supplier?)
    • 두 객체가 동일한 객체가 아닌지 검사
  • assertEquals

    • assertEquals(T, S, String|Supplier?)
    • 첫번째 인자(기댓값)이 두번째 인자(실제값)과 동등한지 검사
  • assertNotEquals

    • assertNotEquals(T, S, String|Supplier?)
    • 첫번째 인자(특정값)이 두번째 인자(실제값)과 동등하지 않은지 검사
  • assertArrayEquals

    • assertArrayEquals(T[], T[], String|Supplier?)
    • 첫번째 배열(기댓값)이 두번째 배열(실제값)과 동등한지 검사
  • assertIterableEquals

    • assertIterableEquals(Iterable, Iterable, String|Supplier?)
    • 첫번째 Iterable(기댓값)이 두번째 Iterable(실제값)과 동등한지 검사
  • assertLinesMatch

    • assertLinesMatch(List, List, String|Supplier?)
    • 첫번째 문자열 리스트(기댓값)가 두번째 문자열 리스트(실제값)와 일치하는지 검사
  • assertAll

    • assertAll(String?, Executable...|Collection|Stream)
    • Executable 목록을 가변인자로 전달받아 각 Executable을 모두 실행한 뒤, 모두 성공했는지 검사
    • 실패한 Executable이 있다면, 실패한 검증 결과를 모아서 에러 메시지로 출력
  • assertThrows

    • assertThrows(Class, Executable, String|Supplier?)
    • Executable을 실행했을 때, 첫번째 인자로 명시한 타입의 예외가 발생하는지 검사
    • 예외 발생시 발생한 예외 객체를 리턴
  • assertDoesNotThrow

    • assertDoesNotThrow(Executable|ThrowingSupplier, String|Supplier?)
    • Executable을 실행했을 때 예외가 발생하지 않는지 검사
  • assertTimeout

    • assertTimeout(Duration, Executable|ThrowingSupplier, String|Supplier?)
    • Executable 또는 ThrowingSupplier를 실행했을 때 지정 시간 내에 실행이 완료되는지 확인
  • assertTimeoutPreemptively

    • assertTimeoutPreemptively(Duration, Executable|ThrowingSupplier, String|Supplier?)
    • 제공된 Executable 또는 ThrowingSupplier를 실행했을 때 명시한 시간 안에 실행이 완료되는지 확인
    • assertTimeoutPreemptively는 제공된 Executable 또는 ThrowingSupplier를 다른 스레드에서 실행
  • assertEquals, assertNotEquals, assertArrayEquals의 타입이 부동 소수점 타입인 경우, 세 번째 파라미터로 delta값(float|double)을 전달 가능

  • 단언이 실패하면 다음 코드를 실행하지 않고 바로 AssertionFailedError 예외를 발생

가정

  • 가정 메서드 실패시 테스트 취소
  • assumeTrue
    • assumeTrue(boolean|BooleanSupplier, String|Supplier)
    • 제공된 인자가 true면 테스트를 이어서 진행, false면 테스트를 취소
  • assumeFalse
    • assumeFalse(boolean|BooleanSupplier, String|Supplier)
    • 제공된 인자가 false면 테스트를 이어서 진행, true면 테스트를 취소
  • assumingThat
    • assumingThat(boolean|BooleanSupplier, Executable)
    • 제공된 인자가 true인 경우에만 Executable을 실행

조건부 테스트 실행

  • ExecutionCondition API를 이용해서 특정 조건에 따라 테스트를 실행 가능

운영체제 조건

  • @EnabledOnOs: 특정 운영체제에서만 테스트를 실행
  • @DisabledOnOs: 특정 운영체제에서 테스트를 비활성화

자바 런타임 환경 조건

  • @EnabledOnJre: 특정 자바 런타임 버전에서만 테스트를 실행
  • @DisabledOnJre: 특정 자바 런타임 버전에서 테스트를 비활성화
  • @EnabledForJreRange: min ≤ 자바 런타임 버전 ≤ max일 경우에만 테스트를 실행
  • @DisabledForJreRange: min ≤ 자바 런타임 버전 ≤ max일 경우 테스트를 비활성화
  • min의 기본값은 JRE.JAVA_8, max의 기본값은 JRE.OTHER

시스템 속성 값 조건

  • @EnabledIfSystemProperty: named로 제공된 JVM 시스템 속성 값이 matches 정규식과 일치하면 테스트를 실행
  • @DisabledIfSystemProperty: named로 제공된 JVM 시스템 속성 값이 matches 정규식과 일치하면 테스트를 비활성화

환경 변수 값 조건

  • @EnabledIfEnvironmentVariable: named로 제공된 운영체제 시스템의 환경 변수 값이 matches 정규식과 일치하면 테스트를 실행
  • @DisabledIfEnvironmentVariable: named로 제공된 운영체제 시스템의 환경 변수 값이 matches 정규식과 일치하면 테스트를 비활성화

사용자 지정 조건

  • @EnabledIf: 명시된 조건 메서드의 boolean 리턴 값이 true라면 테스트를 실행
  • @DisabledIf: 명시된 조건 메서드의 boolean 리턴 값이 true라면 테스트를 비활성화
  • ExtensionContext 타입의 단일 파라미터 선언 가능

테스트 표시 이름 지정

  • @DisplayName으로 표시 이름 지정 가능

표시 이름 생성기

  • @DisplayNameGeneration으로 생성기 지정
  • 생성기는 DisplayNameGenerator를 구현해야 함
  • 기본제공:
    • DisplayNameGenerator.Standard.class: 메서드 이름과 괄호를 그대로 표시 (기본값)
    • DisplayNameGenerator.Simple.class: 파라미터가 없다면, 메서드 이름 뒤의 괄호(())를 제거
    • DisplayNameGenerator.ReplaceUnderScores.class: 언더스코어(_)를 공백(``)으로 치환
    • DisplayNameGenerator.IndicativeSentences.class: 테스트 클래스 이름과 테스트 이름을 이어서 표시
      • @IndicativeSentencesGeneration로 구분자 추가 명시 가능

태그 지정

  • @Tag로 태그 지정 가능
  • 지정된 태그로 필터링하여 테스트 실행 가능

태그 표현식

  • !, &, | 연산자와 괄호 및 any()none() 등을 조합하여 사용

테스트 실행 순서 지정

  • @TestMethodOrder로 실행 순서 정렬기 지정 가능
  • 정렬기는 MethodOrderer를 구현해야 함
  • 기본제공:
    • MethodOrderer.DisplayName.class: 표시 이름으로 정렬
    • MethodOrderer.MethodName.class: 메서드 이름으로 정렬
    • MethodOrderer.OrderAnnotation.class: @Order 애노테이션으로 정렬
    • MethodOrderer.Random.class: 임의 정렬

테스트 인스턴스 라이프사이클

  • @TestInstance로 테스트 인스턴스 라이프사이클 지정 가능
  • 기본값 = PER_METHOD
    • 각 테스트 메서드를 실행하기 전에 해당 테스트 클래스의 인스턴스를 새로 만든다.
  • @TestInstance(Lifecycle.PER_CLASS):테스트 클래스마다 하나의 인스턴스만 만든다.

중첩 테스트 클래스

  • 내부 테스트 클래스에 @Nested 지정 가능

생성자 및 메서드 파라미터 주입

  • ParameterResolver로 런타임에 파라미터를 주입 가능

  • 기본제공:

    • TestInfoParameterResolver: TestInfo 주입
    • RepetitionInfoParameterResolver: RepetitionInfo 주입
    • TestReporterParamterResolver: TestReporter 주입
  • ParameterResolver 또는 TypeBasedParameterResolver를 구현하여 사용자 지정 주입기 구현 가능

  • 구현한 주입기는 @ExtendWith으로 등록

테스트 인터페이스

  • 테스트 인터페이스에 @ExtendWith@Tag 선언 가능
  • 인터페이스 기본(default) 메서드에 @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, @TestTemplate, @BeforeEach, @AfterEach 등을 선언 가능
  • 인터페이스를 구현한 테스트 클래스는 자동으로 태그와 익스텐션을 상속받는다.

테스트 템플릿

  • @TestTemplate: 테스트 케이스를 위한 템플릿
    • ex. @ParameterizedTest, @RepeatedTest
  • 등록된 TestTemplateInvocationContextProvider 익스텐션과 함께 사용되어야 함

반복 테스트

  • @RepeatedTest로 반복 테스트 실행 가능
  • 각 호출은 @Test 메서드와 동일한 라이프사이클 콜백과 익스텐션을 지원
  • RepetitionInfo 파라미터 주입 받을 수 있음
  • name 속성으로 표시 이름 패턴 지정 가능

파라미터 테스트

  • @ParameterizedTest로 파라미터 테스트 가능
  • 인자 소스 지정 필요
  • 파라미터 순서
    1. 인자 소스로부터 받을 파라미터
    2. 애그리게이션으로 받을 파라미터
    3. ParameterResolver로 주입받을 파라미터

인자 소스

  • @ValueSource: 인자 값의 배열 지정
  • @NullSource: 단일 null값 제공
  • @EmptySource: 단일 빈 값 제공
  • @NullAndEmptySource: @NullSource + @EmptySource
  • @EnumSource
    • value: 파라미터로 사용할 enum 클래스, 명시하지 않으면 첫 번째 파라미터 타입이 사용됨
    • names: 사용할 enum 상수 (optional)
    • mode: names로 명시한 값 처리 방법 (ex. EXLUDE, MATCH_ALL)
  • @MethodSource: 지정한 팩토리 메서드 리턴 값을 인자로 사용
    • 명시적으로 팩토리 메서드를 지정하지 않은 경우, 관례에 따라 테스트 메서드와 동일한 이름의 팩토리 메서드를 사용
    • 팩토리 메서드는 인자를 받지 않으며, 인자의 스트림을 리턴해야 함
  • @CsvSource: CSV 문자열로부터 인자 제공
    • delimiter: 구분자 (default = ,)
    • delimiterString: 문자열 구분자 지정 (delimiter와 동시 사용 불가)
    • emptyValue: 빈 문자열을 특정 문자열로 해석하도록 지정
    • nullValue: 특정 문자열들을 null로 해석하도록 지정
    • 인용 문자로 작은 따옴표(')를 사용
      • 빈 인용구('')는 빈 문자열, 완전히 빈 값은 null로 해석
      • null로 해석된 값의 타입이 원시형인 경우 ArgumentConversionException 예외 발생
  • @CsvFileSource: CSV 파일로부터 인자 제공
    • 각 라인마다 테스트 메서드 호출(# 문자로 시작하는 라인은 주석)
    • delimiter: 구분자 (default = ,)
    • delimiterString: 문자열 구분자 지정 (delimiter와 동시 사용 불가)
    • emptyValue: 빈 문자열을 특정 문자열로 해석하도록 지정
    • nullValue: 특정 문자열들을 null로 해석하도록 지정
    • 인용 문자로 큰 따옴표(")를 사용
      • 빈 인용구('')는 빈 문자열, 완전히 빈 값은 null로 해석
      • null로 해석된 값의 타입이 원시형인 경우 ArgumentConversionException 예외 발생
  • @ArgumentsSource: ArgumentsProvider로부터 인자 제공

인자 변환

  • 확장 변환(Widening Conversion): 제공된 인자에 대한 확장 변환을 지원
  • 묵시적 변환(Implicit Conversion): 제공된 문자열을 메서드 파라미터 타입으로 변환
  • 문자열-객체 변환 폴백(Fallback String-to-Object Conversion): 팩토리 메서드나 팩토리 생성자를 호출하여 문자열을 객체로 변환
    • 팩토리 메서드와 팩토리 생성자는 단일 문자열 인자를 받아 해당 객체를 리턴해야 함
  • 명시적 변환(Explicit Conversion): @ConvertWith으로 ArgumentConverter를 지정
    • ArgumentConverter 또는 TypedArgumentConverter를 구현하여 제공

인자 애그리게이션

  • ArgumentAccessor로 여러 개의 인자를 하나의 인자로 받을 수 있음
  • 또는 ArgumnetAggregator를 구현한 뒤 @AggregateWith로 애그리게이터 지정

표시 이름 사용자화

  • @ParameterizedTestname 속성으로 표시 이름 MessageFormat 패턴 지정 가능

동적 테스트

  • @TestFactory 메서드로 런타임에 동적으로 테스트 생성
  • @TestFactory 메서드는 하나의 DynamicNode, Stream, Collection, Iterable, Iterator, 또는 DynamicNode 인스턴스의 배열을 리턴해야 함

라이프사이클

  • 각 개별 동적 테스트는 라이프사이클 콜백을 가지지 않음

URI 테스트 소스

  • DynamicTest.dynamicTest(String, URI, Executable)DynamicContainer.dynamicContainer(String, URI, Stream) 팩토리 메서드로 TestSource 생성 가능
  • TestSource 구현체
    • ClasspathResourceSource: URIclasspath 스킴
    • DirectorySource: URI가 파일 시스템의 디렉토리
    • FileSource: URI가 파일 시스템의 파일
    • MethodSource: URImethod 스킴
    • UriSource: 그 외

타임아웃

  • @Timeout으로 특정 시간이 지나면 테스트가 실패하도록 선언 가능
  • @TestTemplate에 선언시 각 호출에 타임아웃 적용
  • 동적 테스트의 경우, assertTimeout() 또는 assertTimeoutPreemptively()를 사용

병렬 실행

  • 기본적으로 테스트는 싱글 스레드에서 순차적으로 실행
    • 테스트 실행 속도를 높이기 위해서 병렬 실행 설정 가능
  • 설정 값으로 병렬 실행 사용 여부 및 병렬 실행 모드 및 전략 지정 가능
    • 병렬 실행 모드: SAME_THREAD(기본값), CONCURRENT (기본값 = SAME_THREAD)
    • 병렬성 전략: dynamic(기본값), fixed, custom
      • custom 모드 사용시 ParallelExecutionConfigurationStrategy 구현하여 등록 필요
  • @Execution으로 실행 모드 지정 가능

동기화

  • @ResourceLock으로 특정한 공유 리소스에 대한 동기화된 접근을 보장
    • 리소스 이름: SYSTEM_PROPERTIES, SYSTEM_OUT, SYSTEM_ERR, LOCALE, TIME_ZONE, 또는 사용자 지정 이름
  • @Isolated로 특정 테스트를 다른 테스트로부터 격리하여 실행
    • 접근 모드 지정 가능: READ, READ_WRITE

익스텐션

임시 디렉토리 익스텐션

  • TempDirectory 익스텐션은 기본적으로 등록되어 있음
  • 필드 또는 파라미터에 @TempDir 선언하여 임시 디렉토리를 생성
    • Path 또는 File 타입 제공해야 함
    • 생성자 파라미터 지원하지 않으므로 필드 주입 사용

익스텐션 등록

  • @ExtendWith로 선언적으로 등록
    • 등록하고자 하는 클래스 참조를 제공
    • 소스 코드에 명시된 순서대로 등록됨
  • @RegisterExtension로 프로그램적으로 등록
    • 정적 필드 또는 인스턴스 필드에 선언하여 익스텐션 등록
  • 또는 Java의 ServiceLoader 메커니즘을 통해 자동 등록
    • 기본적으로 비활성화 되어 있으므로 설정 파라미터로 활성화 해야 함
    • 클래스 경로 내의 써드 파티 익스텐션이 자동으로 감지되고 등록
    • /META-INF/services 경로의

익스텐션 상속

  • 익스텐션은 상속되며, 특정 익스텐션 구현은 상속 구조 상에서 한번만 등록된다.

조건부 테스트 실행

  • ExecutionCondition: ExtensionContext에 따른 조건부 실행
  • 설정 파라미터로 특정 조건을 비활성화 할 수 있다.

테스트 인스턴스 팩토리

  • TestInstanceFactory: 테스트 클래스 인스턴스 생성
  • 유스케이스:
    • 의존성 주입 프레임워크로부터 테스트 인스턴스 가져오기
    • 테스트 인스턴스를 생성하기 위한 정적 팩토리 메서드 호출
  • 한 클래스에 대해 TestInstanceFactory를 구현한 익스텐션을 여러 개 등록하면 예외가 발생
    • TestInstanceFactory는 상속된다.
    • 모든 테스트 클래스에 대해 단 하나의 TestInstanceFactory가 등록되도록 해야 한다.

테스트 인스턴스 후처리

  • TestInstancePostProcessor: 테스트 인스턴스 후처리
  • 유스케이스:
    • 테스트 인스턴스에 의존성 주입
    • 테스트 인스턴스의 사용자 지정 초기화 메서드 호출
  • 참고: MockitoExtension, SpringExtension

테스트 인스턴스 소멸전 콜백

  • TestInstancePreDestroyCallback: 테스트 인스턴스가 테스트에 사용된 후 소멸되기 전에 특정 처리를 수행
  • 유스케이스: 테스트 인스턴스에 주입되었던 의존성 정리

파라미터 결정

  • ParameterResolver: 런타임에 동적으로 파라미터를 결정
  • 구현에 애노테이션 관련 작업이 필요할 경우 ParameterContext를 사용
  • 참고: CustomTypeParameterResolver, CustomAnnotationParameterResolver, MapOfListsTypeBasedParameterResolver

테스트 결과 처리

  • TestWatcher: 테스트 메서드 실행의 결과를 처리

테스트 라이프사이클 콜백

  • BeforeAllCallback
    • BeforeEachCallback
      • BeforeTestExecutionCallback
      • AfterTestExecutionCallback
    • AfterEachCallback
  • AfterAllCallback
  • 참고: SpringExtension

테스트 실행 전후 콜백

  • BeforeTestExecutionCallback
  • AfterTestExecutionCallback
  • BeforeEachCallback
  • AfterEachCallback
  • 유스케이스: 타이밍, 트레이싱

예외 처리

  • TestExecutionExceptionHandler: 테스트 실행 도중 발생한 예외 처리
  • LifecycleMethodExecutionExceptionHandler: 라이프사이클 메서드에서 발생한 예외 처리
  • 유스케이스: 에러 로깅, 리소스 해제

호출 인터셉트

  • InvocationInterceptor: 테스트 코드에 대한 호출을 인터셉트함

테스트 템플릿을 위한 호출 컨텍스트 제공하기

  • TestTemplateInvocationContextProvider: @TestTemplate 메서드에 TestTemplateInvocationContext 인스턴스의 Stream을 제공

익스텐션 내부 상태 유지하기

  • ExtensionContext: 익스텐션의 상태를 유지하기 위한 Store를 제공
  • 익스텐션 컨텍스트 스토어는 자신의 익스텐션 컨텍스트 라이프사이클로 제한됨
  • 익스텐션 컨텍스트 라이프사이클이 끝나면 해당 익스텐션은 자신의 스토어 안의 리소스를 닫음

익스텐션에서 지원되는 유틸리티들

  • org.junit.platform.commons.support 패키지 참고

애노테이션 지원

  • AnnotationSupport: 애노테이션을 가진 요소에 사용할 수 있는 정적 유틸리티 메서드 제공
  • 유스케이스:
    • 요소의 애노테이션 보유 여부 확인
    • 요소가 특정 애노테이션으로 메타 애노테이션되어 있는지 확인
    • 특정 애노테이션 탐색
    • 클래스 또는 인터페이스에서 애노테이션을 가진 메서드 탐색

클래스 지원

  • ClassSupport: 클래스에 사용할 수 있는 정적 유틸리티 메서드 제공

리플렉션 지원

  • ReflectionSupport: JDK 표준 리플렉션과 클래스 로딩 메커니즘과 관련된 정적 유틸리티 메서드 제공
  • 유스케이스:
    • 클래스 경로에서 특정 조건을 만족하는 클래스 탐색
    • 클래스를 로드하고 새로운 인스턴스 생성
    • 클래스를 찾고 메서드를 호출

접근제어자 지원

  • ModifierSupport: 클래스 또는 멤버의 접근제어자와 관련된 정적 유틸리티 메서드 제공

사용자 코드와 익스텐션 실행 순서

  • 주황색: 사용자가 제공한 테스트와 라이프사이클 메서드
  • 파란색: 익스텐션이 구현한 콜백 코드
  • 회색 상자: 한 테스트 메서드의 실행

extensions lifecycle

단계타입구분FQCN 및 설명
1인터페이스익스텐션org.junit.jupiter.api.extension.BeforeAllCallback
컨테이너의 모든 테스트가 실행되기 전에 실행되는 코드
2애노테이션사용자org.junit.jupiter.api.BeforeAll
컨테이너의 모든 테스트가 실행되기 전에 실행되는 코드
3인터페이스익스텐션org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler #handleBeforeAllMethodExecutionException
@BeforeAll 메서드에서 발생한 예외를 처리하기 위한 코드
4인터페이스익스텐션org.junit.jupiter.api.extension.BeforeEachCallback
각 테스트가 실행되기 전에 실행되는 코드
5애노테이션사용자org.junit.jupiter.api.BeforeEach
각 테스트가 실행되기 전에 실행되는 코드
6인터페이스익스텐션org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler #handleBeforeEachMethodExecutionException
@BeforeEach 메서드에서 발생한 예외를 처리하기 위한 코드
7인터페이스익스텐션org.junit.jupiter.api.extension.BeforeTestExecutionCallback
테스트 실행 직전에 실행되는 코드
8애노테이션사용자org.junit.jupiter.api.Test
실제 테스트 메서드의 코드
9인터페이스익스텐션org.junit.jupiter.api.extension.TestExecutionExceptionHandler
테스트 중에 발생한 예외를 처리하기 위한 코드
10인터페이스익스텐션org.junit.jupiter.api.extension.AfterTestExecutionCallback
테스트 실행과 대응하는 예외 처리기 직후에 실행되는 코드
11애노테이션사용자org.junit.jupiter.api.AfterEach
각 테스트가 실행된 이후에 실행되는 코드
12인터페이스익스텐션org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler #handleAfterEachMethodExecutionException
@AfterEach 메서드에서 발생한 예외를 처리하기 위한 코드
13인터페이스익스텐션org.junit.jupiter.api.extension.AfterEachCallback
각 테스트가 실행된 이후 실행되는 코드
14애노테이션사용자org.junit.jupiter.api.AfterAll
컨테이너의 모든 테스트가 실행된 후 실행되는 코드
15인터페이스익스텐션org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler #handleAfterAllMethodExecutionException
@AfterAll 메서드에서 발생한 예외를 처리하는 코드
16인터페이스익스텐션org.junit.jupiter.api.extension.AfterAllCallback
컨테이너의 모든 테스트가 실행된 후 실행되는 코드
  • InvocationInterceptor: 사용자 코드 메서드의 모든 호출을 인터셉트

콜백의 래핑

  • 라이프사이클 콜백을 구현한 익스텐션이 여러개 등록된 경우, 등록 순서에 따라 콜백 래핑이 일어남
  • Extension1이 등록된 후 Extension2가 등록되었다고 가정하면:
    • Extension1의 모든 사전(before) 콜백은 Extension2의 모든 사전 콜백 이전에 실행된다.
    • Extension1의 모든 사후(after) 콜백은 Extension2의 모든 사후 콜백 이후에 실행된다.
  • 사용자 제공 라이프사이클 메서드에 대해서도 동일
    • 부모클래스(인터페이스)의 @BeforeAll 메서드는 자식(구현) 클래스의 @BeforeAll 메서드 이전에 실행된다.
    • 부모클래스(인터페이스)의 @BeforeEach 메서드는 자식(구현) 클래스의 @BeforeEach 메서드 이전에 실행된다.
    • 부모클래스(인터페이스)의 @AfterEach 메서드는 자식(구현) 클래스의 @AfterEach 메서드 이후에 실행된다.
    • 부모클래스(인터페이스)의 @AfterAll 메서드는 자식(구현) 클래스의 @AfterAll 메서드 이후에 실행된다.
  • 하나의 테스트 클래스 또는 인터페이스에 선언되어있는 라이프사이클 메서드가 여러개일 경우 래핑 지원 안함
    • 하나의 테스트 클래스 또는 인터페이스에 대해 최대 한 개의 라이프사이클 메서드만 선언하는 것을 권장

1개의 댓글

comment-user-thumbnail
2022년 12월 25일

junit5에 대해서 발표를 하기위해서 공부를 하고 있는데 많이 부끄럽네요...
공부는 이렇게 하는거군요 진짜 대단하십니다. 많이 깨닫게 되었습니다.

답글 달기