현재 내가 진행중인 토이 프로젝트의 환경은 아래와 같다. 모듈에 관한 간략한 설명은 아래와 같다.
1. User 모듈
사용자 관련 비지니스 로직 및 기능 담당
2. Sales 모듈
매출 / 매입 관련 비지니스 로직 및 기능 담당
3. Common 모듈
테스트 코드 외에서 공통적으로 사용되는 기능 담당
4. Test 모듈
테스트 코드에서 공통적으로 사용되는 기능 담당
5. Api 모듈
어플리케이션 시작 및 API 관련 기능 담당
그리고 각 모듈은 프로젝트의 최상위 디렉토리에서 빌드되어 docker 환경에서 띄워지게 된다.
따라서 docker-compose.yml, Dockerfile은 모두 최상위 디렉토리에 위치한다. 그리고 실제 docker 환경 기반의 테스트를 위해 "testcontainers" 를 사용한다.
여기서 발생한 문제는 "test용 docker-compose.yml 파일을 어떻게 관리할 것인가" 이다.
가장 쉬운 해결책은 각 모듈별로 docker-compose.yml, Dockerfile을 만들어주는 것일 것이다. 하지만 이 해결책은 하나의 docker-compose 파일을 수정한다면 그 외 모든 docker-compose도 같이 수정해주어야 한다는 치명적인 단점이 있다.
그래서 생각한 것이 최상위 디렉토리에 test용 docker-compose.yml 파일을 위치시키는 것이다.
testcontainers를 활용한 테스트를 위해서는 DockerComposeContainer 객체를 생성해야 하는데, 이때 필요한 파일이 test용 docker-compose.yml 파일이다.
그리고 이 함수는 테스트 실행 시 공통적으로 사용되는 기능으로써 test 모듈에 위치해 있다.
# docker-compose.test.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: app
ports:
- "8081:8080"
env_file:
- .env
이제 이 해결책을 적용하기 위해서 필요한 것은 2가지이다.
1. 다른 모듈의 테스트에서 사용될 getDockerComposeContainer() 함수에서 어떻게 test용 docker-compose.yml 파일 경로를 지정해줄 것인가?
2. test용 docker-compose.yml에서 dockerfile을 찾기 위한 context를 어떻게 지정해줄 것인가?
1번의 대책은 "../docker-compose.test.yml"을 File 클래스 생성자의 파라미터로 넣어주는 것이었다.
System.out.println(new File(".").getAbsolutePath());
user 모듈에서 테스트를 실행시키고 test 모듈에 위치한 getDockerComposeContainer 함수에 위 코드를 넣고 실행시켜보면 "User/...(경로 생략)../user/." 와 같이 찍힌다.
이를 통해 최상위 디렉토리에 위치한 test용 docker-compose.yml에는 "../docker-compose.test.yml" path를 지정하여 접근할 수 있었다.
2번의 대책은 쉽지 않았다.
아래와 같이 docker 관련 파일들은 최상위 디렉토리에 위치해 있었다. 그래서 위에서 보이는 것처럼 context에 "."을 설정하면 될 것 같아다.
그렇지만 결과는 test용 docker-compose.yml 파일을 찾지 못하여 FileNotFound익셉션이 터져버렸다.. 무엇이 문제일까 곰곰히 생각해보다 문뜩 이런 생각이 났다.
"getDockerComposeContainer 함수가 선언되어 있는 클래스의 디렉토리가 docker-compose.test.yml의 . 디렉토리가 아닐까?"
그렇게 getDockerComposeContainer 함수가 선언되어 있는 클래스 디렉토리 -> Dockerfile이 위치한 최상위 디렉토리까지 '../' 를 반복하여 설정해주어 최종적으로 만들어진 docker-compose.test.yml 파일을 아래와 같다.
version: '3.8'
services:
user:
build:
context: ../../../../../../..
dockerfile: Dockerfile
image: app
ports:
- "8081:8080"
env_file:
- .env
그리고 놀랍게도 DockerComposeContainer 객체가 정상적으로 생성되면서 테스트 결과는 성공! (몇일 만이야.. ㅠ.ㅠ)
이렇게 모듈별로 test용 docker-compose 파일을 여러 개 생성하지 않고 하나로 관리할 수 있도록 코드를 작성해보았다.
그렇지만 아직 완벽한 코드는 아니다. 추후 개선 과제는 아래와 같다.
1. test용 docker-compose.yml 파일을 test 모듈의 resources 디렉토리에 위치시킬 수 있을까?
(현재까지는 하다가 실패..)
2. Dockerfile을 docker 이미지 저장소에 저장시켜놓고 불러오도록 설정하기
이 방법도 좋은 방법이지만, docker 이미지를 항상 최신 버전으로 관리해야 해야 하며 테스트용으로도 이미지를 만들어야 한다는 단점이 있다. (물론 dockefile이 변하면 얼만큼 자주 변하겠냐마나는..)
뭔가 이번 작업을 통해 testcontainer 내부 소스코드도 들여다보고, "이 상황에서 file의 path가 어떻게 될까" 궁리해보면서 코드에 대한 인스펙이 넓어지는 것 같다.
중간 과정이 많이 고통스럽지만.. 그래도 할 수 있다!
'Backend > Spring' 카테고리의 다른 글
[Spring] 멀티 모듈에 Spring Rest Docs 적용기 (0) | 2025.03.03 |
---|---|
[Gradle] Built-in Task의 내부 실행 순서 (0) | 2025.03.03 |
[Gradle] Gradle Wrapper 개념 정리 (0) | 2025.02.08 |