반응형
✍️ 문제 상황
- 로컬 환경에서 통합 테스트할 때 매번 서버를 올리는 일이 매우 번거로웠습니다. 세션과 캐시를 위한 redis 서버를 테스트할 때 마다 매번 올리는건 개발 생산성을 낮춘다고 판단했습니다. 이러한 현상은 제 팀원에게도 나타날 것이기 때문에 지금 개선하지 않으면 팀원 수에 비례하여 개발 생산성이 낮아질 것으로 판단했습니다.
💡 통합 테스트 과정 redis 서버를 실행(수동) → 통합 테스트 실행(수동) → 테스트 완료 → redis 서버 clear(수동)
✍️ 접근 방법과 해결 과정
- 로컬 환경에서 서버 환경 구축을 자동화할 수 있는 툴이 있는지 조사했습니다. 여러 툴들이 있었지만, 현업에서는 도커를 사용하기 때문에 이를 선택했습니다. 또한 docker가 Ubuntu20.04에서 기본으로 설치돼있는 것으로 보아 그만큼 보편적이고 안정된 툴이라고 생각했습니다.
- 처음에는 각각의 Dockerfile을 Manual 하게 실행했습니다. 하지만 이는 처음 문제 상황과 달라진게 없었습니다. 이에 대안을 찾았고, docker-compose가 있다는걸 알았습니다. docker-compose 내부에서 정의된 각 컨테이너들은 하나의 네트워크로 묶이기 때문에 호스트 이름만으로도 서로의 컨테이너에 접근할 수 있었습니다. docker-compose를 이용하여 서버 환경 구축을 명령어 한번에 할 수 있었습니다.
💡 통합 테스트 과정 docker-compose up(수동) → 통합 테스트 실행(수동) → 테스트 완료 → docker stop(수동) → docker rm(수동)
- docker-compose 구축 후에도 문제가 있었습니다. redis 서버 각각을 수동으로 구동 시키지 않고 docker-compose up으로 한번에 이를 처리하지만, 한번 실행 후에 도커를 전부 멈추고 컨테이너를 지우는 일이 번거로웠습니다. 제가 원했던건 통합 테스트를 실행하면 컨테이너가 전부 올라가고, 테스트가 끝나면 컨테이너가 내려가는 상황이었습니다.
- 테스트를 실행 시 도커 컨테이너를 자동으로 띄워주는 툴이 있는지 찾아봤습니다. 스프링과 호환 되면서 가장 보편적으로 쓰이는 툴은 Testcontainer 라이브러리였습니다. 해당 라이브러리의 특징은 다음과 같았습니다
Testcontainer의 장단점
- 장점
- Java 라이브러리
- Junit5 연동
- Mysql, Redis 등 다양한 db 호환
- 통합 테스트를 쉽게함.
- 테스트 시작 시 도커 컨테이너를 자동으로 띄워주고, 테스트 끝난 후 컨테이너를 자동으로 내려줌
- 단점
- 라이브러리 종속성
- 컨테이너 올리는 시간이 김.
- Testcontainer의 특징과 장단점을 분석한 것을 바탕하여 프로젝트에 적용했습니다. 아래 링크에 Testcontainer 적용 시 라이브러리의 작동 원리에 대한 분석 및 어떤 코드를 왜 썻는지에 대한 사고 과정이 적혀있습니다.
- https://github.com/f-lab-edu/resell-platform/pull/42
Feature/#40 도커와 Testcontainers를 이용한 서버 환경 구축 자동화 & 통합 테스트 적용 by michaelkimm · Pul
커밋에 작성된 Testcontainers의 작동 원리는 잘못된 것이 많습니다. 커밋 내용에서는 <구현 내용> <문제점> <원인 분석>을 보시고 <작동 원리>는 pr 내용을 봐주시면 감사하겠습니다:) <구현 결과> Docke
github.com
✍️ 결과
- Testcontainer 라이브러리를 적용하여 통합 테스트 실행 시 개발자가 수동으로 무언가를 실행시키는 횟수를 4번에서 1번으로 줄였습니다. 통합 테스트를 20개 개발하면 수동으로 무언가를 실행하는게 80번이 아닌 통합 테스트 개수 20번만 실행하면 됩니다.
💡 통합 테스트 과정
통합 테스트 실행(수동) → docker 컨테이너 up(자동) → 테스트 완료 → docker 컨테이너 down(자동)
- 물론 Testcontainer를 사용하면 불편한 점이 있습니다. 아래 PR 링크 내에서도 명시 했듯이, 서버 구성 환경이 변경될 시 두 군데(yml과 자바 코드)를 수정 해야 하는 문제가 존재합니다.
- 해결 방법1 : 환경 변수롤 주입하는 방식으로 해결할 수도 있지만 spring 애플리케이션이 docker-compose 정보에 포함되는 배포 환경에서만 적용할 수 있고, docker-compose에 spring 애플리케이션이 들어있지 않은 로컬 통합 테스트 환경에서는 어렵습니다.
- 해결 방법2 : application.properties에 미리 적어 놓는 것도 해결 방법이 되지 않습니다. Testcontainer에서는 @DynamicProperties로 application.properties에 데이터를 override하기 때문입니다.
📙 레퍼런스
반응형
'프레임워크 > Spring' 카테고리의 다른 글
@Transactional, @Cacheable 및 Redis 호환 문제 해결 (0) | 2022.09.04 |
---|---|
Filter를 사용하여 반복되는 응답 로직 제거 (feat.StandardResponse) (0) | 2022.06.30 |