도커와 테스트

이연중·2021년 2월 6일
0

JAVA

목록 보기
17/20

Testcontainers 소개

테스트에서 도커 컨테이너를 실행할 수 있는 라이브러리

  • 테스트 실행시 DB를 설정하거나 별도의 프로그램 또는 스크립트를 실행할 필요 없음
  • 보다 Production에 가까운 테스트를 만들 수 있음
  • 테스트가 느려짐

Testcontainers 설치

Testcontainers JUnit5 지원 모듈 설치

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>1.15.1</version>
    <scope>test</scope>
</dependency>

@Testcontainers

  • JUnit5 확장팩으로 테스트 클래스에 @Container를 사용한 필드를 찾아 컨테이너 라이프 사이클 관련 메소드 실행

@Container

  • 인스턴스 필드에 사용하면 모든 테스트마다 컨테이너를 재시작하고, 스태틱 필드에 사용하면 클래스 내부 모든 테스트에서 동일한 컨테이너를 재사용

각 모듈 별도 설치 필요

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <version>1.15.1</version>
    <scope>test</scope>
</dependency>

applecation.propertiesd에 다음 추가

spring.datasource.url=jdbc:tc:postgresql:///studytest

spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver //tc 키워드가 붙어있는 url 정보에 해당하는 driver로 test containers가 제공하는 driver 사용

static PostgreSQLContainer postgreSQLContainer= new PostgreSQLContainer()
    .withDatabaseName("studytest");

이렇게 하면 test containers가 띄운 postgres에 연결이 됌

Testcontainers 기능 살펴보기

컨테이너 만들기

  • New GenericContainer(String imageName)

    static GenericContainer postgreSQLContainer= new GenericContainer("postgres").withEnv("POSTGRES_DB","studytest");

네트워크

  • withExposedPorts(int...): 컨테이너 안에서 특정 포트 노출
  • getMappedPort(int): 노출된 포트가 실제 호스트의 어떤 포트와 매핑 되는지 확인

환경 변수 설정

  • withEnv(key, value): 컨테이너가 사용할 환경변수 설정

명령어 실행

  • withCommand(String cmd..)

사용할 준비가 됐는지 확인

  • waitingFor(Wait): 컨테이너가 언제 가용한지
  • Wait.forHttp(String url): 특정 url에 대한 응답이 오는지 기다림
  • Wait.forLogMessage(String message): 컨테이너의 특정 로그 메시지가 출력될때까지

로그 살펴보기

  • getLogs(): 현재까지 컨테이너안에 있는 로그 메시지를 모두 가져옴
  • followOutput(): 로그가 쌓일때마다 어플리케이션에서 출력(스트리밍)

Testcontainers: 컨테이너 정보를 스프링 테스트에서 참조하기

@ContextConfiguration

  • 스프링이 제공하는 어노테이션으로, 스프링 테스트 컨텍스트가 사용할 설정 파일 또는 컨텍스트를 커스터마이징할 수 있는 방법 제공

ApplicationContextInitializer

  • 스프링 ApplicationContext를 프로그래밍으로 초기화할 때 사용할 수 있는 콜백 인터페이스로, 특정 프로파일을 활성화 하거나, 프러퍼티 소스를 추가하는 등의 작업을 할 수 있음

TestPropertyValues

  • 테스트용 프러퍼티 소스를 정의할 때 사용

Environment

  • 스프링의 핵심 API로, 프로퍼티와 프로파일을 담당

전체 흐름

  1. Testcontainer를 사용해 컨테이너 생성
  2. ApplicationContextInitializer를 구현해 생성된 컨테이너에서 정보를 추출해 Environment에 넣어줌
  3. @ContextConfiguration을 사용해 ApplicationContextInitializer 구현체를 등록
  4. 테스트 코드에서 Environment, @Value, @ConfigurationProperties 등 다양한 방법으로 해당 프로퍼티 사용

Testcontainers: 도커 Compose 사용

테스트에서 서로 관련있는 컨테이너 사용시

Docker Compose: https://docs.docker.com/compose/

  • 여러 컨테이너를 한번에 띄우고 서로 간 의존성 및 네트워크 등을 설정할 수 있는 방법
  • docker-compose up/down

Testcontainer의 docker compose 모듈을 사용할 수 있음

도커 Compose 서비스 정보 참조

특정 서비스 Expose

@Container
static DockerComposeContainer composeContainer =
        new DockerComposeContainer(new File("src/test/resources/docker-compose.yml"))
        .withExposedService("study-db", 5432);

Compose 서비스 정보 참조

static class ContainerPropertyInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext context) {
        TestPropertyValues.of("container.port=" + composeContainer.getServicePort("study-db", 5432))
                .applyTo(context.getEnvironment());
    }
}

참고

https://www.inflearn.com/course/the-java-application-test

profile
Always's Archives

0개의 댓글