본문 바로가기

Study

[내일배움캠프 TIL] Testcontainers와 Karate DSL로 구축하는 MSA 테스트 환경 (통합 테스트 vs E2E 테스트)

728x90
반응형

최근 프로젝트 테스트 환경을 세팅하면서 TestcontainersKarate라는 강력한 도구들을 접하게 되었습니다. 하나의 API가 내 내부 레이어(Controller-Service-DB)를 잘 통과하는지 검증하는 통합 테스트와, 전체 서비스 인프라를 다 띄워놓고 사용자 시나리오를 검증하는 E2E 테스트의 차이를 명확히 정리해 봅니다.

📌 한눈에 보는 테스트 레벨 요약

구분 테스트 범위 인프라 필요 여부 실행 속도 주요 목적
단위 테스트 함수 및 단일 클래스 불필요 (전부 Mocking) 매우 빠름 비즈니스 로직 검증
통합 테스트 API 1개 (컨트롤러-> DB) PostgreSQL (Testcontainers) 보통 단일 API 전체 흐름 + 실제 DB 저장 검증
Karate E2E 여러 API 연계 시나리오 전체 인프라 실기동 (Docker Compose) 느림 실제 배포 환경과 유사한 환경에서 흐름 검증

1. Testcontainers 기반 통합 테스트 (Integration Test)

🎯 목적

하나의 API 요청이 Controller -> Service -> Repository(DB)까지 끊기지 않고 연결되는 전체 흐름을 검증합니다.

💡 주요 특징

  • @SpringBootTest: 애플리케이션 컨텍스트 전체를 테스트 프로세스 내에 기동합니다.
  • MockMvc: 실제 HTTP 포트를 열지 않고, 가상으로 HTTP 요청/응답을 시뮬레이션합니다.
  • Testcontainers: 테스트 코드가 실행될 때 실제 PostgreSQL 도커 컨테이너를 자동으로 띄우고 종료합니다. 로컬 DB 환경에 의존하지 않는 독립적인 테스트가 가능해집니다.
  • 외부 API Mocking: 무거운 외부 인증 서버(Keycloak)는 WireMock으로 대체하여 가짜 응답을 활용합니다.

🔄 테스트 흐름 및 대상

검증 대상: POST /api/v1/users/signup 한 번의 호출로 응답 상태(201), Body 구조, 실제 DB 저장 여부, 중복 가입 차단(409)까지 모두 검증

[MockMvc] ──(POST /signup)──> [Controller] ──> [UserService]
                                                     │
                                                     ├──> [WireMock] (Keycloak 가짜 응답)
                                                     └──> [PostgreSQL Container] (실제 저장)

🛠 사용 도구

  • JUnit 5 + @SpringBootTest + MockMvc
  • Testcontainers (PostgreSQL)
  • WireMock (Keycloak Admin API Mocking)

2. Karate DSL 기반 E2E(End-to-End) 테스트

🎯 목적

Gateway, Keycloak, DB 등 모든 마이크로서비스 인프라가 실제로 기동된 상태에서 진짜 HTTP 요청을 날려 전체 비즈니스 시나리오를 검증합니다.

💡 주요 특징

  • 실제 환경 기반: docker-compose로 모든 서비스가 살아있어야 실행 가능합니다. (배포 후 스모크 테스트로도 활용 가능)
  • Gherkin 문법 (.feature): Given-When-Then 구조의 자연어 기반 스크립트로 시나리오를 정의합니다.
  • No Node.js / No npm: 보통 E2E tool(Cypress, Playwright 등)은 NodeJS 환경이 필요하지만, Karate는 JUnit 5 기반으로 구동되어 ./gradlew :e2e:test 명령어 하나로 Java 생태계 안에서 통합 실행이 가능합니다.

📁 E2E 프로젝트 폴더 구조

Plaintext
 
e2e/
├── build.gradle
├── README.md
└── src/test/
    ├── java/e2e/
    │   └── E2ERunner.java          ← JUnit 5 실행 진입점 (수정 불필요)
    └── resources/
        ├── karate-config.js        ← 환경변수(Gateway Secret, URL 등) 설정
        ├── user/                   ← user-service 단독 시나리오 (.feature)
        └── saga/                   ← 서비스 연계 시나리오 (회원가입→주문→결제 등)

🏃‍♂️ 실행 및 리포트 확인 방법

환경변수 세팅과 대상 지정을 자동화하기 위해 쉘 스크립트(run.sh)를 활용합니다.

Bash
 
# 1. 인프라 및 서비스 기동 (Gateway 헬스체크 확인 후 진행)
docker compose up -d
docker compose -f docker-compose.services.yml up -d

# 2. Karate 테스트 실행 (전체 혹은 특정 도메인)
bash e2e/run.sh              # 전체 실행
bash e2e/run.sh user         # user 폴더 전체 실행
bash e2e/run.sh user/signup  # 회원가입 시나리오만 실행

# 3. HTML 리포트 확인
open e2e/build/karate-reports/karate-summary.html

✍️ 요약 및 회고

  • Testcontainers 덕분에 로컬 DB를 더럽히지 않고도 CI/CD 파이프라인에서 완벽하게 독립된 DB 통합 테스트를 수행할 수 있게 되었다.
  • Karate는 JS 기반 E2E 도구보다 백엔드(Java/Gradle) 환경에 친숙하고 가벼우며, 특히 여러 마이크로서비스가 얽히는 Saga 패턴이나 복합 시나리오 검증에 강력한 무기가 될 것 같다. 역시 테스트 환경 구축이 까다로울수록 코드의 안정성은 올라간다!
반응형