본문으로 건너뛰기
SDETRole
SDETRole

용어집 · CI/CD와 DevOps

Testcontainers

다른 이름: 테스트컨테이너, Testcontainers for Java, testcontainers-node

정의

데이터베이스, 메시지 브로커, 브라우저 같은 실제 의존성을 테스트 코드에서 일회용 Docker 컨테이너로 띄우고 끝나면 제거하는 라이브러리입니다.

Testcontainers는 Java, Node.js, .NET, Go, Python 등 여러 언어로 제공되는 오픈소스 라이브러리로, 테스트 안에서 Docker를 제어합니다. 테스트가 “Postgres 16 데이터베이스”를 요청하면 라이브러리가 컨테이너를 시작하고, 준비될 때까지 기다린 뒤 접속 정보를 넘겨주며, 테스트가 끝나면 컨테이너를 제거합니다. 인메모리 대체물이나 공유 환경이 아니라 실제 데이터베이스 엔진을 대상으로 테스트하게 됩니다.

예시 (Testcontainers for Java 1.x, JUnit 5)

import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

import static org.junit.jupiter.api.Assertions.assertTrue;

@Testcontainers
class DatabaseIT {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @Test
    void canQueryTheDatabase() throws Exception {
        try (Connection conn = DriverManager.getConnection(
                postgres.getJdbcUrl(), postgres.getUsername(), postgres.getPassword());
             ResultSet rs = conn.createStatement().executeQuery("SELECT 1")) {
            assertTrue(rs.next());
        }
    }
}

static 필드는 클래스 안의 모든 테스트가 컨테이너 하나를 공유하게 하고, 인스턴스 필드는 테스트마다 새 컨테이너를 시작합니다. 실제 스위트에서는 리포지토리나 Spring 컨텍스트가 getJdbcUrl()을 바라보도록 설정하고 마이그레이션을 먼저 실행합니다.

왜 중요한가

H2나 SQLite를 대상으로 한 통합 테스트는 통과하는데 운영 데이터베이스는 같은 SQL을 거부하는 일이 흔합니다. SQL 방언, 제약 조건, 트랜잭션 동작이 다르기 때문입니다. Testcontainers는 mock에 가까운 편의성으로 실제 엔진을 제공하며, 매 실행이 깨끗한 상태에서 시작하므로 데이터 공유로 인한 불안정성(flakiness)도 사라집니다.

알아 둘 점

  • 로컬 머신과 CI 러너에 Docker 호환 런타임이 필요합니다. GitHub 호스팅 Ubuntu 러너에는 Docker가 준비되어 있습니다.
  • 컨테이너 시작에는 몇 초가 걸립니다. 컨테이너는 클래스 단위나 스위트 단위로 공유하고, 테스트 사이에는 컨테이너를 재시작하지 말고 데이터를 초기화하십시오.
  • 이미지 버전은 운영 환경과 맞춰 고정하십시오.
  • 자주 쓰는 서비스(Postgres, MySQL, Kafka, LocalStack, Selenium 등)용 모듈이 준비되어 있고, 그 밖의 이미지는 GenericContainer로 다룰 수 있습니다.
  • 테스트 더블을 대체하는 것이 아니라 보완합니다. 단위 테스트는 여전히 메모리 안에서 빠르게 돌아가야 합니다.

SDETRole 전체에서 검색할 내용을 입력하세요.

Pagefind 전문 검색 · 브라우저에서 실행됩니다 검색 페이지 열기 →