[java] TestContainers를 사용하여 웹서비스 통합 테스트하기

통합 테스트는 웹서비스의 모든 컴포넌트들이 함께 동작하는지 확인하기 위해 중요한 단계입니다. 그러나 테스트 환경에서 실제 데이터베이스, 메시지 큐 등의 외부 리소스를 사용해야 할 때 문제가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 TestContainers를 사용할 수 있습니다.

TestContainers는 Docker를 기반으로 동작하는 테스트 컨테이너 프레임워크입니다. 이를 사용하면 테스트 코드 내에서 필요한 외부 리소스를 쉽게 관리할 수 있습니다. 이제 TestContainers를 사용하여 웹서비스의 통합 테스트를 수행하는 방법을 알아보겠습니다.

1. 의존성 추가하기

TestContainers를 사용하기 위해 먼저 의존성을 추가해야 합니다. pom.xml 파일에 다음과 같은 의존성을 추가합니다.

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

2. 테스트 클래스 작성하기

다음으로 테스트 클래스를 작성해보겠습니다. 예를 들어, 웹 서비스의 사용자 관리 기능을 테스트하는 클래스를 만들어보겠습니다.

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

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

@Testcontainers
public class UserServiceIntegrationTest {

    @Container
    public GenericContainer<?> postgres = new GenericContainer<>("postgres:latest")
            .withExposedPorts(5432)
            .withEnv("POSTGRES_USER", "test")
            .withEnv("POSTGRES_PASSWORD", "test");

    @Test
    public void testCreateUser() {
        // 외부 데이터베이스에 접속하여 사용자 생성 테스트 코드 작성
        String jdbcUrl = "jdbc:postgresql://" + postgres.getContainerIpAddress() + ":" + postgres.getMappedPort(5432) + "/test";
        try (Connection connection = DriverManager.getConnection(jdbcUrl, "test", "test")) {
            // 사용자 생성 로직 작성
            // Assertions 및 검증 로직 작성
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

위의 코드에서는 GenericContainer를 사용하여 PostgreSQL 컨테이너를 실행하고 테스트를 실행하는 예시입니다. @Container 어노테이션을 사용하여 postgres 필드가 테스트에 사용되는 컨테이너임을 지정하고, @Test 어노테이션을 사용하여 실제 테스트 코드를 작성합니다.

테스트 코드 내에서는 postgres 컨테이너의 IP 주소와 포트 정보를 가져와서 외부 데이터베이스에 접속하는 로직을 작성하게 됩니다.

3. 테스트 실행하기

이제 테스트를 실행해보면 TestContainers가 자동으로 Docker 컨테이너를 생성하고 실행할 것입니다. 웹 서비스의 모든 컴포넌트 통합 테스트가 완료될 때까지 기다리고, 테스트 결과를 출력해줍니다.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.UserServiceIntegrationTest
...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.857 s - in com.example.UserServiceIntegrationTest

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

테스트가 성공적으로 완료되었습니다!

결론

TestContainers를 사용하면 테스트 환경에서 외부 리소스를 쉽게 관리할 수 있으며, 웹서비스의 통합 테스트를 효과적으로 수행할 수 있습니다. 이를 통해 개발자는 실제 운영 환경과 유사한 환경에서 테스트를 진행하고 문제를 사전에 발견할 수 있습니다.

더 자세한 내용은 TestContainers 공식 사이트를 참고하시기 바랍니다.