컨테이너 기반 테스트 시작하기 — GenericContainer로 컨테이너 만들기

컨테이너 기반 테스트 시작하기 — GenericContainer로 컨테이너 만들기

통합 테스트에서 가장 번거로운 부분은 테스트에 필요한 DB나 외부 서비스 같은 의존성을 준비하는 일이에요. Testcontainers의 GenericContainer를 쓰면 이런 의존성을 Docker 컨테이너 위에서 그때그때 띄워서 테스트하고, 끝나면 알아서 정리할 수 있어요. 이 페이지에서는 거의 모든 컨테이너 이미지를 임시 테스트 의존성으로 쓰게 해 주는 GenericContainer를 중심으로, 이미지를 지정하는 방법과 컨테이너가 언제 시작되고 파괴되는지 살펴볼게요.

출처: 공식문서 — Creating a container

본문

이미지 기반의 범용 컨테이너 만들기

Testcontainers의 범용 컨테이너 지원은 가장 유연해서, 사실상 아무 컨테이너 이미지나 임시 테스트 의존성으로 쉽게 쓸 수 있어요. 예를 들어 이런 것들과의 상호작용을 테스트할 때 유용하죠.

  • NoSQL 데이터베이스나 다른 데이터 저장소 (예: redis, elasticsearch, mongo)
  • 웹 서버나 프록시 (예: nginx, apache)
  • 로그 서비스 (예: logstash, kibana)
  • 팀이나 조직에서 이미 도커라이즈해 둔 다른 서비스

범용 컨테이너에서는 컨테이너 이미지를 생성자 파라미터로 지정해요.

new GenericContainer(DockerImageName.parse("jboss/wildfly:9.0.1.Final"))

이미지 지정하기

Testcontainers의 많은 컨테이너 클래스가 역사적으로 두 가지 생성자를 지원했어요.

  • 인자가 없는 생성자 — 예를 들어 new GenericContainer()new ElasticsearchContainer(). 이런 생성자에서는 Testcontainers가 전통적으로 기본 이미지 이름(고정된 이미지 태그/버전 포함)을 썼어요. 기본값을 건전하게(즉 최신으로) 유지해야 하는 필요와, 새 Testcontainers 버전이 올라갈 때 의존성이 조용히 업그레이드되는 것을 피해야 하는 필요 사이에서 충돌이 생겼죠.
  • 문자열 인자 하나를 받는 생성자 — 버전이나 이미지 이름을 String으로 받았어요. 이 때문에 모호함과 혼란이 있었죠.

v1.15.0부터 이런 두 생성자 타입 모두 위와 같은 이유로 사용이 권장되지 않아요(Deprecated).

대신 모든 컨테이너DockerImageName 객체를 받는 생성자로 만드는 것을 강력히 권장해요. DockerImageName 클래스는 도커 이미지를 모호함 없이 가리키는 참조예요.

개발자들은 DockerImageName을 다른 상수가 될 수 있는 값처럼 다루는 것을 권해요 — 테스트 코드베이스에서 쓰는 의존성의 프로덕션 버전과 맞는 상수를 정의하는 걸 고려해 보세요.

예시

범용 컨테이너 규칙은 아무 공개 도커 이미지와도 함께 쓸 수 있어요. 예를 들어 볼게요.

@Container
public GenericContainer redis = new GenericContainer(DockerImageName.parse("redis:6-alpine"))
    .withExposedPorts(6379);

@Container로 선언한 컨테이너는 클래스의 어떤 테스트가 실행되기 전에 시작되고, 모든 테스트가 끝난 뒤에 파괴돼요.

더 알아보기