1. 테스트 코드와 라인 커버리지
1. 라인 커버리지가 100%라면?
테스트를 작성하고 커버리지를 측정했더니 라인 커버리지가 100%로 표시되며, 페이지가 온통 초록색으로 물들어 있으면 마음이 편해짐

하지만 해당 지표만으로 “이 정도면 단위 테스트는 충분하다”고 단정할 수 있을까?
2. 실제 코드로 확인
다음은 점수를 등급으로 분류하는 간단한 메서드
Classfier.java
public String classify(int score) {
if (score < 0 || score > 100) {
throw new IllegalArgumentException("점수는 0~100 범위여야 합니다: " + score);
}
if (score >= 90) {
return "A";
} else if (score >= 80) {
return "B";
} else {
return "F";
}
}그리고 아래의 단위 테스트는 모든 라인을 실행하고 있음
→ 라인 커버리지: 100%. 모든 분기를 실행했고, 모든 return 문을 거침
겉보기에는 완벽해 보임
ClassifierTest.java
@Test void gradeA() { assertEquals("A", classifier.classify(95)); }
@Test void gradeB() { assertEquals("B", classifier.classify(85)); }
@Test void gradeF() { assertEquals("F", classifier.classify(30)); }
@Test void invalidNegative() { assertThrows(IllegalArgumentException.class, () -> classifier.classify(-1)); }
@Test void invalidOver100() { assertThrows(IllegalArgumentException.class, () -> classifier.classify(101)); }3. 만약 소스 코드의 일부분을 변경하고 다시 테스트할 경우?
score >= 90을 score > 90으로 변경
원본 코드
Classfier.java
if (score >= 90) { // 90점은 A
return "A";
}위 테스트는 score=95로 A 등급을 테스트하고 있음
따라서 >=가 >로 바뀌어도 95는 여전히 A
→ 테스트는 여전히 통과하게 됨
4. 돌연변이 커버리지
라인 커버리지는 코드를 실행했는지만 측정함
즉, classify(95)로만 테스트하면 A 경로를 실행하지만,
score=90일 때와 같은 경계값에 대해서는 정확히 A가 나오는지까지는 검증하지 않음
그래서 이를 보완하기 위해 등장한 지표로 돌연변이 커버리지(Mutation Coverage) 가 있음
| 라인 커버리지 | 돌연변이 커버리지 | |
|---|---|---|
| 측정 대상 | 코드를 실행했는가 | 코드를 검증했는가 |
| 퍼센테이지의 기준 | 모든 줄을 한 번 이상 실행 | 거의 모든 변이를 테스트를 통해 탐지 |
| 차이점 | 실행만 하고 결과를 안 봐도 100% | 결과를 정확히 검증해야 커버리지가 높아짐 |
5. 해결 방법
경계값 90을 직접 테스트하는 코드를 추가할 경우,
ClassifierTest.java
@Test
void exactly90_isA() {
assertEquals("A", classifier.classify(90));
}이제 >=가 >로 바뀌면 score=90이 B를 반환하게 되고,
→ 테스트가 실패하게 됨(돌연변이 탐지)
이런 식으로 경계값과 반환값 등을 보다 정밀하게 검증하는 테스트 코드를 작성하면 해당 테스트가 시나리오를 잘 커버하고 있다는 개발자의 신뢰도가 높아짐
또한 회귀(Regression)를 방지할 수 있는 효과도 있음
Last updated on