TestForge | Aidevops | 📊 Plogger ✍️ Blog 📚 Docs
plogger

AI DevOps Korea

AI 서비스 개발, 운영, 성능개선을 하나의 루프로 연결합니다

aidevops.kr에서 LLMOps, RAG, AI Agent, 관측성, 평가, 비용-성능 최적화를 실전 운영 관점으로 정리합니다.

Spring Boot 테스트 전략 가이드

· 수정 4월 22일
Spring Boot 테스트 전략 가이드 다이어그램
이 글에서 다루는 핵심 흐름, 아키텍처 구조, 주요 판단 포인트를 한눈에 이해할 수 있도록 정리한 그림입니다.
테스트 전략의 핵심은 테스트 개수를 늘리는 것이 아니라, **어떤 실패를 어떤 속도로 잡을 것인지 설계하는 것**입니다. 빠른 피드백과 운영 신뢰도는 서로 경쟁하는 목표가 아니라, 잘 나눈 테스트 계층 위에서 함께 올라가야 합니다.

Spring Boot에서는 특히 모든 테스트를 @SpringBootTest처럼 만들고 싶은 유혹을 경계해야 합니다.

위험을 계층별로 나눠 생각해야 합니다

버그마다 잡혀야 하는 위치가 다릅니다.

  • 도메인 규칙과 서비스 판단 오류는 단위 테스트에서 빠르게 실패해야 함
  • HTTP 계약과 직렬화 문제는 웹 슬라이스 테스트에서 드러나야 함
  • 쿼리와 매핑 문제는 데이터 슬라이스 테스트에서 검증돼야 함
  • 몇 개 안 되는 핵심 사용자 흐름만 통합 테스트가 책임져야 함

모든 검증을 전체 컨텍스트 부팅까지 기다리게 만들면, 피드백 루프가 느려지고 팀은 테스트를 개발 도중 신뢰하지 않게 됩니다.

단위 테스트는 핵심 규칙을 보호합니다

단위 테스트는 비즈니스 로직이 진하고 프레임워크 의존이 적은 지점에서 가장 강합니다.

좋은 대상은 다음과 같습니다.

  • 순수 도메인 규칙
  • 가격 계산과 검증 로직
  • 서비스 계층의 오케스트레이션 판단
  • 비즈니스 의미가 있는 매핑과 변환 로직

반대로 mock을 과도하게 써서 구현 디테일만 검증하는 테스트는 쉽게 깨지고 신뢰도는 높이지 못합니다.

슬라이스 테스트는 프레임워크 경계를 검증합니다

Spring Boot가 test slice를 제공하는 이유는 많은 실패가 비즈니스 로직이 아니라 프레임워크 경계에서 발생하기 때문입니다.

대표 예시는 다음과 같습니다.

  • @WebMvcTest: 요청 매핑, 검증, JSON 응답 형태, 상태 코드
  • @DataJpaTest: 쿼리 정확성, 매핑 동작, 영속성 경계
  • 직렬화 또는 컨트롤러 중심의 계약 테스트

이 테스트들은 전체 통합 테스트보다 빠르면서도, 순수 단위 테스트보다 경계 현실을 더 잘 반영합니다.

@SpringBootTest는 선택적으로 써야 합니다

@SpringBootTest는 분명 가치가 있지만, 부팅 시간과 환경 설정 비용, 디버깅 복잡성도 큽니다.

보통 다음 경우에 한정하는 편이 좋습니다.

  • 가장 중요한 사용자 흐름
  • 슬라이스 테스트로는 검증하기 어려운 cross-layer wiring
  • 설정 민감도가 높은 동작
  • 운영 신뢰도에 직접 연결되는 인프라 통합 경로

모든 테스트를 여기에 몰아넣으면, 스위트가 느리고 시끄럽고 유지보수하기 어려워집니다.

영속성 테스트는 실제 쿼리 리스크를 반영해야 합니다

Repository 코드는 메서드 이름이 이상해서보다, 조인과 페이지네이션, fetch 전략, 트랜잭션 경계에서 실제 동작이 기대와 다르기 때문에 자주 실패합니다.

그래서 @DataJpaTest가 특히 중요한 경우는 다음과 같습니다.

  • custom JPQL 또는 native query
  • lazy loading 가정
  • N+1 민감 경로
  • DB 벤더 특화 매핑 동작

현실적인 데이터 접근 테스트가 없는 repository는 코드 리뷰에서는 멀쩡해 보여도, 스테이징이나 운영 데이터에서 쉽게 깨집니다.

API 테스트는 상태 코드만이 아니라 계약을 검증해야 합니다

웹 계층 테스트는 다음을 확인할 때 가장 가치가 큽니다.

  • 요청 유효성 검사
  • 응답 구조
  • 오류 payload 일관성
  • HTTP 경계에서의 보안과 권한 규칙

200 OK만 검증하는 웹 테스트는 실행 시간 대비 얻는 신뢰도가 낮습니다.

테스트 데이터 전략도 중요합니다

많은 Spring Boot 테스트 스위트가 시간이 지나며 약해지는 이유는 테스트 데이터가 읽기 어렵고 수정하기 더 어려워지기 때문입니다.

건강한 접근은 보통 다음을 포함합니다.

  • 의도가 드러나는 fixture 또는 builder
  • 테스트당 최소 시나리오 데이터
  • 거대한 공용 초기화 남용 피하기
  • 기본값 상속보다 edge case를 명시적으로 표현

좋은 테스트 데이터는 실패 원인을 읽기 쉽게 만들고, 리팩터링을 더 안전하게 해줍니다.

흔한 전략 실수

다음 패턴은 자주 테스트 스위트를 비싸고 약하게 만듭니다.

  • 단순 비즈니스 로직까지 full-context 테스트로 검증
  • 프레임워크 동작을 mock-heavy 단위 테스트로 억지 검증
  • “JPA가 해주겠지”라며 repository query를 테스트하지 않음
  • validation과 오류 payload 계약 검증이 없음
  • 테스트 데이터 소유권이 불분명해 flaky integration test가 늘어남

이런 상태에서는 테스트가 많아도 믿기 어려운 스위트가 됩니다.

현실적인 분배 기준

정답 비율은 없지만, 건강한 프로젝트는 대체로 다음 패턴을 가집니다.

  • 대부분은 단위 테스트
  • 그보다 적지만 의미 있는 수의 슬라이스 테스트
  • 정말 중요한 흐름만 full integration test

비율은 도메인과 팀 성숙도에 따라 달라도, 원칙은 같습니다. 잡고 싶은 실패를 가장 싸고 현실적인 테스트로 검증하는 것이 핵심입니다.

체크리스트

테스트 체계가 건강하다고 하려면 최소한 다음이 확인되어야 합니다.

  • 도메인 규칙을 전체 Spring 컨텍스트 없이 검증하는가
  • API 계약을 웹 슬라이스 테스트로 검증하는가
  • 핵심 JPA 쿼리를 데이터 슬라이스 테스트로 검증하는가
  • 정말 중요한 흐름만 @SpringBootTest를 쓰는가
  • 테스트 데이터가 읽기 쉽고 시나리오 중심인가

마무리

좋은 Spring Boot 테스트 전략은 테스트 종류를 많이 섞는 데 있지 않습니다. 각 테스트가 어떤 실패를 책임지는지 역할을 명확히 나누는 것이 핵심입니다.

그럴 때 빠른 피드백과 높은 신뢰도를 동시에 얻을 수 있습니다.

Continue Reading

다음으로 읽기 좋은 글

다음 탐색

이 주제를 시스템 관점으로 더 이어서 보기