[Test] Testcontainers를 사용하여 테스트 환경 구축하기

angie·2024년 6월 7일

Repository 테스트 코드 작성 중, 데이터베이스와 연동된 테스트를 실행하면서 예상치 못한 상황을 마주했다. 최종적으로 Testcontainers를 도입한 경험을 공유하고자 한다.

1. 기존 접근 방식의 한계

테스트 환경을 구축할 때, 주로 아래와 같은 방법들이 사용됩니다:

  • Local: 로컬에 데이터베이스를 설치하고, 환경을 구축하여 테스트를 수행.
  • In-Memory: 인메모리 데이터베이스를 활용하여 테스트 실행 시 사용.
  • Embedded Library: 임베디드 라이브러리를 이용하여 테스트 구동 시 사용

문제점
GitHub Actions를 사용해 CI 파이프라인을 설정하면서 테스트를 자동화했는데, 이로 인해 로컬에서 직접 데이터베이스를 설정하여 테스트하는 것은 불가능했다. 또한, CI 환경에서 서버에 데이터베이스를 올리는 방법도 고려했지만, 이 경우 비용 부담이 있었다.

처음에는 인메모리 데이터베이스를 사용하려 했으나, Spring Boot에서 인메모리 데이터베이스를 사용할 경우 테이블 이름을 변경해야 했다. 운영 환경에서는 MySQL을 사용하지만, 테스트 환경에서 H2를 사용하는 경우 이와 같은 차이로 인해 테스트 결과의 신뢰성이 저하되고, 오류가 발생할 가능성이 있다고 생각했다. 이러한 이유로, 더 나은 해결책을 찾고자 했다.

2. Docker를 활용한 테스트 환경의 고려

그 후, Docker를 사용해 로컬에서 데이터베이스를 구동하는 방법도 고려했다. 그러나 Dockerfile과 docker-compose 파일을 관리해야 하고, 컨테이너를 수동으로 시작하고 중지하는 등의 작업이 추가되는 귀찮은 작업을 진행해야 했다.

3. Testcontainers의 도입

TestContainer란?

Testcontainers란 Docker를 기반으로 Junit 수행 시 테스트를 도와주는 Java Library 이다.

Testcontainers 특징

  • Java로 Container를 동작시킬 수 있다.
  • Dockerfile, docker-compose, docker hub로 Container를 동작시킬 수 있다.
  • 테스트 실행 전/후로 Container를 start, stop 할 수 있다.
  • Parallel Test를 지원한다.
  • 다양한 module을 제공하고 있다.

코드

build.gradle

testImplementation 'org.testcontainers:testcontainers:1.19.7'

@Testcontainers
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@DataJpaTest
class ProductRepositoryTest {

   @Container
    static MySQLContainer mySQLContainer = new MySQLContainer<>(DockerImageName.parse("mysql:8.0-debian"));

    @DynamicPropertySource
    static void kafkaProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", () -> mySQLContainer.getJdbcUrl());
        registry.add("spring.datasource.driverClassName", () -> mySQLContainer.getDriverClassName());
        registry.add("spring.datasource.username", () -> mySQLContainer.getUsername());
        registry.add("spring.datasource.password", () -> mySQLContainer.getPassword());
        registry.add("spring.jpa.hibernate.ddl-auto", () -> "update");
    }

(생략)

}

결론

Testcontainers를 도입한 이후, 테스트 환경 설정이 훨씬 편해졌다. GitHub Actions와 같은 CI 환경에서도 손쉽게 테스트를 자동화할 수 있었으며, 실제 운영 환경과 유사한 조건에서 테스트를 수행할 수 있었다.
단점으로는 테스트하는데 시간이 좀 걸린다.


참고

https://dev.gmarket.com/76

profile
열심히 달리는 개발자

0개의 댓글