조급하면 모래성이 될뿐

멀티모듈에서 통합테스트 본문

구현 기록/TestContiners

멀티모듈에서 통합테스트

Pawer0223 2023. 6. 23. 18:54

현재 프로젝트 구조는 위와 같다. Domain 모듈에서 Repository 계층을 책임지고 있기 때문에, 해당 단위테스트는 mariaDB Container를 사용해 해결했다. Infra 모듈에서 역시 Redis 컨테이너를 통해 단위테스트를 진행할 수 있을 것이다. 그럼 통합 테스트 환경은 어떻게 구성하는 것이 좋을까??

 

처음에는 아래와 같은 구조로 통합테스트를 진행하고자 시도했다.

즉, 각 모듈의 /test/resources/application.yml에 실행에 필요한 테스트 컨테이너 환경 설정정보가 정의되어 있기 때문에 api 모듈에서는 이 정보만 참조하면 되겠다! 싶었다.

 

하지만 Domain 모듈의 컨테이너는 yml 설정으로 가능하지만, Infra 모듈의 컨테이너 (Redis Container)는 이러한 방식으로 구성할 수 없다. 위 방식은 JDBC support에서만 지원하기 때문이다.

 

따라서 Redis 컨테이너 환경은 소스코드로 구축해주어야 했다. 일반적으로 싱글턴으로 컨테이너를 구축하기 위해 공식문서에서는 아래와 같은 방식으로 설정하라고 권장한다. - 공식문서

abstract class AbstractContainerBaseTest {

    static final MySQLContainer MY_SQL_CONTAINER;

    static {
        MY_SQL_CONTAINER = new MySQLContainer();
        MY_SQL_CONTAINER.start();
    }
}

class FirstTest extends AbstractContainerBaseTest {

    @Test
    void someTestMethod() {
        String url = MY_SQL_CONTAINER.getJdbcUrl();

        // create a connection and run test as normal
    }
}

 

결과적으로.. api 모듈에서 다른 모듈에 있는 테스트 컨테이너 설정을 읽어올 수 있는 방법이 없었다. 정확히는 못 찾았다. Infra 모듈이 사용되지 않는다고 해도 (properties 만으로 테스트 컨테이너가 전부 설정되어 있다고 해도) api/test/resources/application.yml 에서 domain/test/resources/application.yml의 설정정보를 참조하는 방식도 찾지 못했다...

 

대안으로 아래와 같은 구조를 만들어서 해결할 수 있었다.

즉, 통합테스트에서 테스트 컨테이너 환경을 별도로 구축하는 것이다. 이 방식이 마음에 안 들었던 가장 큰 이유는.. 만약 DB가 바뀐다면 Domain 모듈의 컨테이너와 API 모듈의 컨테이너 설정을 각각 변경해주어야 한다는 점이었다. 그러나 위 구조 말고는 다른 대안을 찾지 못했다. 위 방법이 Best Practice가 아닐 수도 있다..

 

하지만 변경에 따른 영향이 많아진다는 것을 제외하곤 만족했다. 특히 모든 모듈에서 테스트 컨테이너의 장점을 취할 수 있다는 점이 좋았다. (멱등성 보장, 테스트 환경 구성에 유연한 점)

 

다음 문제점..

위에서 Redis 구성은 공식문서에서 제안하는 싱글톤 방식으로 정의해주어야 한다고 했다. 이 방식은 컨테이너가 필요한 경우 상속해서 사용하는 방식이다. 하지만 현재 프로젝트는 kotest를 사용하고 있기 때문에 위와 같은 방식을 적용할 수 없다. (다중 상속이 안되기 때문에)

 

또한 위에서 추천하는 방식은 만약 TestA.java, TestB.java, TestC.java 가 있다면 3개의 클래스 모두 @Continers 어노테이션을 붙이고 AbstractContainerBaseTest를 상속해야 한다.. 이 방식이 너무 번거롭다고 생각했다.

 

다음 포스팅에서는 kotest와 TestContainers를 통합테스트 과정에서 사용하면서 Redis 컨테이너 설정을 단 한번만 하고 사용할 수 있도록 해볼것이다.

반응형