jvnlee / catch-dining

맛집 검색 및 예약 서비스
0 stars 0 forks source link

refactor/#37 test environment improvement #38

Closed jvnlee closed 5 months ago

jvnlee commented 5 months ago

구현 내용

1. 독립적인 테스트 Profile 사용을 위해 프로젝트에 Profile 기반의 YML 생성

GitHub에는 application-dev.yml과 application-test.yml 2개의 Profile 설정만 외부에 노출함

dev는 개발 환경에서, test는 테스트 환경에서만 사용하며, 공개하지 않은 prod Profile은 배포 환경에서 사용함

 

2. TestContainers로 테스트 실행 환경 일반화

기존에는 임의의 로컬 환경에서 테스트 코드를 실행하기 위해서 MySQL과 Redis의 별도 설치와 실행이 요구되었음

💡 테스트용 MySQL의 대안

1) H2 Database

장점:
- In-Memory 방식으로 매우 가벼움

- 의존성 추가 후 복잡한 별도 세팅이 필요 없음

- MySQL 모드로 실제 DB인 MySQL과 유사하게 사용할 수 있음

단점:
- 운영 DB가 바뀌었을 때도 항상 유사성을 보장해주지는 않음

- 특정 DB의 기능을 지원하지 않는 경우 테스트가 어려움

 

2) Docker MySQL Container

장점:
- 동일한 규격(동일한 버전과 설정을 가진 MySQL)으로 실행 가능

단점:
- 테스트 코드를 실행하려는 임의의 로컬 사용자가 Docker에 대한 지식이 없다면 선수 학습이 필요할 수 있음

- Docker 설치 및 docker-compose 작성 등의 별도 세팅이 필요함

 

💡 테스트용 Redis의 대안

1) Embedded Redis

장점:
- H2처럼 앱 실행 시 내부에서 Redis를 실행하기 때문에 외부 설치나 실행이 필요 없음

단점:
- 오픈소스인데 마지막 업데이트가 kstyrc/embedded-redis 기준 6년전 (지속성이 불투명함)

    > 파생된 소스인 codemonstur/embedded-redis는 2개월 전 업데이트로 최신이긴 하지만 이 또한 언제 끊길지 알 수 없음...

- 별도 Config로 실행과 중지 과정에 대한 세팅이 필요함

2) Docker Redis Container

Docker MySQL Container 활용의 장단점과 동일

 

💡 최종 선택지: TestContainers

결국 H2나 Embedded Redis처럼 내장형으로 갈 것이냐, 아니면 Docker처럼 외부 컨테이너형으로 갈 것이냐를 두고 고민해야했음.

장단점을 놓고 봤을 때, Docker에 대한 지식만 있다면 후자가 더 낫다고 판단함. 본인은 Docker를 학습한 상태기 때문에 상관 없지만, 랜덤한 테스트 실행자가 Docker를 잘 모른다면 여전히 문제가 있을 수 있다고 생각했음.

이 때, 보다 쉽게 Docker Container 기반 테스트 환경을 구축할 수 있도록 도와주는 TestContainers라는 라이브러리가 있어서 이를 채택하게 됨.

 

장점:

단점:

 

TestContextInitializer: ApplicationContext의 초기화 로직을 커스터마이즈

Redis TestContainer는 실행될 때마다 바인딩된 포트 번호가 달라지기 때문에 이를 런타임에 받아와서 System Property로 지정

System Property에 저장된 포트 번호가 RedisConfig의 port 필드에 주입됨 → 해당 정보를 바탕으로 Application Context 생성

 

3. RestAssured로 E2E 통합테스트의 실용성 강화

기존 @MockMvc를 활용하는 방식은 가상 MVC, 즉 가상 환경에 가까운 방식이라서 실제 API의 동작을 테스트하기에는 부족한 면이 있었음.

@MockMvc는 컨트롤러의 단위 테스트에 좀 더 적합함

이 때문에 Postman 같은 외부 앱을 사용해서 부족한 E2E 테스트를 수동으로 커버중이었는데 매우 불편했음.

REST Assured라는 라이브러리를 도입해서 코드 레벨에서 E2E 테스트를 커버하고자 함.

 

장점: