문제 상황
Playback 도메인 테스트 코드를 작성한 뒤 JaCoCo로 커버리지를 확인했을 때,
대부분의 로직은 테스트되었지만 서비스 계층 일부 분기가 실행되지 않아 커버리지 100%에 도달하지 못했다.

특히 아래 두 부분이 미실행으로 남았다.
- play() 메서드에서 동일 곡 재생 중 요청 처리 분기
- handlePlay() 메서드 마지막 INVALID_PLAYBACK_STATE 예외 분기
커버리지 100%를 달성하기 위해 추가 테스트 작성이 필요한 상황이었다.
원인 분석
코드 흐름을 다시 따라가며 분석해보니,
남아 있는 분기들은 단순히 테스트를 덜 작성해서가 아니라 현재 구조상 정상적인 흐름으로는 도달하기 어려운 코드였다.
1. 동일 곡 재생 중 분기
play()에서는 현재 세션에서 PLAYING 상태의 playback을 조회한 뒤,
- 동일한 곡이면 → 중복 재생 요청으로 간주하여 예외 발생
- 다른 곡이면 → 기존 playback 종료
하도록 구성되어 있다.
즉 이 분기는 실제 비즈니스 규칙인 “같은 곡을 중복 재생할 수 없다”를 명확하게 표현한 로직이다.

2. handlePlay() 마지막 예외 분기
handlePlay()는 다음 상태만 처리한다.
- PAUSED → resume
- STOPPED, COMPLETED, SKIPPED → 새 playback 생성
그 외 상태는 마지막에서 예외를 던진다.
throw new BusinessException(PlaybackErrorCode.INVALID_PLAYBACK_STATE);
하지만 현재 play() 흐름상 이 메서드로 전달되는 객체는 이미 위 상태들로 제한되어 있기 때문에, 해당 분기는 사실상 방어 코드에 가깝다.
즉 이 코드를 실행시키기 위해 테스트를 작성하려면 실제 흐름과 맞지 않는 비자연스러운 상황을 만들어야 했다.
따라서 이 분기는 테스트를 위한 코드가 아니라, 시스템 안정성을 위한 방어 코드로 판단하였다.

고민
여기서 두 가지 선택지가 있었다.
1. 커버리지 100% 달성
- 모든 분기를 억지로라도 실행시키는 테스트 작성
- 테스트가 구현 세부사항에 강하게 의존
2. 의미 있는 테스트 유지
- 실제 발생 가능한 흐름 중심 테스트 유지
- 방어 코드는 그대로 두고 커버리지 일부 포기
해결 방향
이번에는 커버리지 100% 달성보다 코드의 의미와 테스트의 자연스러움을 더 중요하게 판단했다.
따라서 다음과 같은 방향으로 정리하였다.
- 중복 재생 요청 시 즉시 예외 발생하도록 로직 명확화
- 상태 전이 흐름(pause, stop, skip)을 기준으로 테스트 구성
- 상태 변경 시 save()를 명시적으로 호출하여 코드 의도 명확화
- 방어 코드 분기는 유지하되, 억지 테스트는 작성하지 않음
결과
- 핵심 재생 흐름(play, pause, stop, skip)에 대한 테스트 검증 완료
- 중복 재생 방지 및 상태 전이 로직 정상 동작 확인
- 주요 예외 케이스(404, 409 등) 테스트로 검증
결과적으로 서비스 커버리지는 100%에 도달하지 않았지만,
실제 비즈니스 흐름을 충분히 검증할 수 있는 테스트는 확보된 상태라고 판단하였다.
느낀 점
이번 경험을 통해 커버리지 100%라는 숫자 자체가 항상 좋은 것은 아니라는 것을 느꼈다.
특히 방어 코드나 구조적으로 도달하기 어려운 분기까지 억지로 테스트하려 하면, 오히려 테스트가 복잡해지고 코드 구조가 왜곡될 수 있다는 점을 알게 되었다. 앞으로는 커버리지 수치를 참고 지표로 활용하되, 그보다 중요한 것은 “이 테스트가 실제 비즈니스 흐름을 잘 설명하고 있는가”라는 기준이라고 생각한다.
테스트는 단순히 수치를 채우기 위한 도구가 아니라, 코드의 의도를 설명하기 위한 도구라는 것을 다시 한번 느낄 수 있었다.
'Fivefy 프로젝트 > 트러블슈팅' 카테고리의 다른 글
| DB 유니크 제약 적용 이후 constraint 기반 예외 분기 처리로 개선 (0) | 2026.04.20 |
|---|---|
| 스케줄러 기반 로직 테스트 설계와 운영 환경 고려 (0) | 2026.04.16 |
| 동시 요청에서 발생할 수 있는 중복 데이터 문제와 DB 유니크 제약으로 해결 (2) | 2026.04.14 |
| 컬럼명 문제로 인한 DDL 오류 및 테이블 생성 실패 해결 (0) | 2026.04.13 |
| 서비스와 엔티티의 검증 책임 분리 (1) | 2026.04.10 |