Testcontainers: 실제 데이터베이스 통합 테스트
Testcontainers로 Docker에서 PostgreSQL을 실행하고 실제 데이터베이스를 대상으로 통합 테스트를 수행합니다.
Testcontainers: 실제 데이터베이스 통합 테스트은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
Testcontainers를 사용하는 이유
H2 인메모리 데이터베이스는 PostgreSQL 전용 기능(JSON, 전문 검색, ON CONFLICT)을 지원하지 않습니다. Testcontainers는 테스트 중에 실제 Docker 컨테이너를 실행하므로 프로덕션과 동일한 데이터베이스를 사용할 수 있습니다.
Testcontainers 의존성 추가
빌드 파일에 Testcontainers BOM과 PostgreSQL 모듈을 추가합니다. Spring Boot 3.1 이상에는 관리되는 Testcontainers 버전이 포함되어 있습니다.
// build.gradle:
testImplementation "org.testcontainers:junit-jupiter"
testImplementation "org.testcontainers:postgresql"
// Optionally use Spring Boot Testcontainers support:
testImplementation "org.springframework.boot:spring-boot-testcontainers"@Testcontainers 및 @Container
테스트 클래스에 @Testcontainers를 지정하고 컨테이너를 정적 @Container 필드로 선언합니다. JUnit 5가 컨테이너를 자동으로 시작하고 중지합니다.
@Testcontainers
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserRepositoryIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
}컨테이너에서 DataSource 구성
@DynamicPropertySource를 사용하여 컨테이너의 동적 포트와 인증 정보를 Spring의 DataSource 구성에 주입합니다.
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}Spring Boot 3.1 ServiceConnection
Spring Boot 3.1 이상에서는 @ServiceConnection이 지정된 Testcontainers의 @Container 빈으로부터 DataSource를 자동 구성하므로 @DynamicPropertySource가 필요하지 않습니다.
@Bean
@ServiceConnection
static PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16-alpine");
}싱글턴 컨테이너 패턴
테스트 클래스마다 컨테이너를 시작하면 느립니다. Startables.deepStart()를 사용하는 정적 필드나 추상 기본 클래스를 통해 모든 테스트에서 하나의 컨테이너를 공유하십시오.
abstract class AbstractIntegrationTest {
@Container
static final PostgreSQLContainer<?> POSTGRES =
new PostgreSQLContainer<>("postgres:16-alpine").withReuse(true);
static { POSTGRES.start(); }
@DynamicPropertySource
static void props(DynamicPropertyRegistry r) {
r.add("spring.datasource.url", POSTGRES::getJdbcUrl);
r.add("spring.datasource.username", POSTGRES::getUsername);
r.add("spring.datasource.password", POSTGRES::getPassword);
}
}PostgreSQL 전용 기능 테스트
Testcontainers를 사용하면 JSON 열, JSONB 연산자, 전문 검색 및 ON CONFLICT DO UPDATE를 테스트할 수 있습니다. H2에서는 이러한 기능을 테스트할 수 없습니다.
@Test
void jsonb_search_works() {
// Insert row with JSONB column, then query
List<Event> logins = repo.findByType("login");
assertEquals(1, logins.size());
}여러 컨테이너: Compose
여러 서비스를 필요로 하는 통합 테스트에서 전체 스택(PostgreSQL + Redis + Kafka)을 실행하려면 DockerComposeContainer를 사용하십시오.
@Container
static DockerComposeContainer<?> compose = new DockerComposeContainer<>(
new File("src/test/resources/docker-compose.yml"))
.withExposedService("postgres", 5432)
.withExposedService("redis", 6379);Ryuk: 자동 정리
Testcontainers는 JVM이 종료될 때 컨테이너를 자동으로 중지하고 제거하기 위해 Ryuk 컨테이너를 사용합니다. 테스트가 실패한 경우에도 동작하므로 컨테이너 누수를 방지할 수 있습니다.
Testcontainers와 @SpringBootTest
실제 Postgres 컨테이너를 대상으로 전체 애플리케이션 스택(컨트롤러, 서비스, 리포지토리)을 테스트하려면 @DataJpaTest 대신 @SpringBootTest를 사용하십시오.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class FullIntegrationTest extends AbstractIntegrationTest {
@LocalServerPort int port;
@Autowired TestRestTemplate rest;
@Test
void end_to_end_user_creation() {
ResponseEntity<UserDto> r = rest.postForEntity("/api/users", createReq(), UserDto.class);
assertEquals(HttpStatus.CREATED, r.getStatusCode());
}
}컨테이너 이미지 캐싱
Testcontainers는 가져온 도커 이미지를 로컬에 캐시합니다. 테스트 실행 중 다운로드로 인한 부담을 피하려면 테스트를 실행하기 전에 지속적 통합 환경에서 이미지를 가져오십시오(docker pull postgres:16-alpine).
빠른 확인
Spring Boot 3.1 이상에서 Testcontainers 컨테이너를 Spring의 DataSource에 자동 연결하는 애너테이션은 무엇입니까
복습
Testcontainers는 통합 테스트를 위해 실제 도커 컨테이너를 실행합니다. @Container와 @DynamicPropertySource 또는 @ServiceConnection(Boot 3.1 이상)을 사용하십시오. 싱글턴 패턴으로 테스트 간에 컨테이너를 공유하십시오. H2에서는 테스트할 수 없는 PostgreSQL 전용 기능을 테스트하십시오.
자주 묻는 질문
“Testcontainers: 실제 데이터베이스 통합 테스트” 강의는 무료인가요?
네 — “Testcontainers: 실제 데이터베이스 통합 테스트” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“Testcontainers: 실제 데이터베이스 통합 테스트”에서 뭘 배우나요?
Testcontainers로 Docker에서 PostgreSQL을 실행하고 실제 데이터베이스를 대상으로 통합 테스트를 수행합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Java Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“Testcontainers: 실제 데이터베이스 통합 테스트” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- @CsvSource와 @MethodSource를 사용한 매개변수화 테스트
- Mockito 고급: 인수 캡처와 스파이
- Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest
- Testcontainers: 실제 데이터베이스 통합 테스트