어제 오늘 내일

[JUnit5] dynamicContainer()로 테스트 그룹 구성하기 본문

IT/JUnit

[JUnit5] dynamicContainer()로 테스트 그룹 구성하기

hi.anna 2026. 1. 23. 08:04

1. dynamicContainer()란 무엇인가

dynamicContainer()는 JUnit5의 동적 테스트 기능 중 하나로, 여러 동적 테스트 또는 하위 컨테이너를 하나의 그룹으로 묶는 구조화 도구이다.
dynamicTest()가 단일 테스트를 생성한다면, dynamicContainer()는 테스트 그룹(폴더 역할) 을 만들어 복잡한 테스트 세트를 계층적으로 구성할 수 있게 한다.

특히 다음과 같은 경우에 유용하다.

  • 연관된 테스트들을 하나의 그룹으로 묶어 표현하고 싶을 때
  • 데이터 집합별 테스트 그룹을 만들고 싶을 때
  • 트리 구조의 테스트 리포트를 구성하고 싶을 때

 

2. 기본 사용 예제

import org.junit.jupiter.api.DynamicContainer;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

import java.util.List;

class DynamicContainerBasicExample {

    @TestFactory
    List<DynamicContainer> containerExample() {
        return List.of(
            DynamicContainer.dynamicContainer("Arithmetic Tests", List.of(
                DynamicTest.dynamicTest("1 + 1 = 2", () -> assertEquals(2, 1 + 1)),
                DynamicTest.dynamicTest("2 * 3 = 6", () -> assertEquals(6, 2 * 3))
            ))
        );
    }
}

설명

  • "Arithmetic Tests"라는 이름의 컨테이너(그룹)가 생성된다.
  • 그 아래에 두 개의 동적 테스트가 포함된다.
  • 테스트 실행 트리에서 보기 좋은 구조로 표시된다.

 

3. 컨테이너 안에 또 다른 컨테이너 넣기 (계층 구조)

계층형 테스트 그룹이 필요할 때 사용한다.

@TestFactory
DynamicContainer nestedContainers() {
    return DynamicContainer.dynamicContainer("Top Group", List.of(
        DynamicContainer.dynamicContainer("Group A", List.of(
            DynamicTest.dynamicTest("A1", () -> assertTrue(true)),
            DynamicTest.dynamicTest("A2", () -> assertTrue(true))
        )),
        DynamicContainer.dynamicContainer("Group B", List.of(
            DynamicTest.dynamicTest("B1", () -> assertTrue(true))
        ))
    ));
}

설명

  • Top Group 아래에 Group A, Group B라는 하위 그룹이 존재
  • 테스트 대규모화를 위해 트리 구조를 명확히 하고 싶을 때 적합

 

4. 데이터 기반 그룹화 예제

입력 데이터별로 컨테이너를 생성하면 테스트 가독성이 크게 향상된다.

@TestFactory
List<DynamicContainer> groupedByInputData() {
    List<String> groups = List.of("group1", "group2");

    return groups.stream()
        .map(name -> DynamicContainer.dynamicContainer(name, List.of(
            DynamicTest.dynamicTest(name + " test1", () -> assertTrue(name.length() > 0)),
            DynamicTest.dynamicTest(name + " test2", () -> assertNotNull(name))
        )))
        .toList();
}

활용 포인트

  • 데이터 세트별 테스트 묶음 표현
  • 외부 데이터(JSON, DB 값 등) 기반 자동 생성에 적합

 

5. 컨테이너 + 예외 테스트 활용하기

각 테스트 그룹에 다양한 형태의 테스트를 포함할 수 있다.

@TestFactory
DynamicContainer exceptionTestGroup() {
    return DynamicContainer.dynamicContainer("Exception Tests", List.of(
        DynamicTest.dynamicTest("Null 입력 시 예외", 
            () -> assertThrows(IllegalArgumentException.class, () -> validate(null))),
        DynamicTest.dynamicTest("빈 문자열 예외", 
            () -> assertThrows(IllegalArgumentException.class, () -> validate("")))
    ));
}

void validate(String input) {
    if (input == null || input.isEmpty()) throw new IllegalArgumentException();
}

 

6. dynamicContainer()를 쓰면 좋은 상황 정리

  • 테스트 세트를 그룹 단위로 구조화하고 싶을 때
  • 데이터 기반 테스트를 그룹별로 시각화하고 싶을 때
  • 하위 테스트를 계층적 트리 형태로 표현하고 싶은 경우
  • 테스트 규모가 크고, 테스트 묶음을 논리적으로 구분해야 할 때
  • 여러 API, 여러 기능 모듈별 테스트 그룹화를 자동화할 때

정적 테스트(@Test)로는 불가능한 “동적 + 계층 구조”를 만들 수 있어, 복잡한 테스트 체계를 깔끔하게 구성하는 데 매우 효과적이다.

 

반응형
Comments