Skip to Content
Suffering builds character
아카이브26.mutation Testing돌연변이 테스트1. 테스트 코드와 라인 커버리지

1. 테스트 코드와 라인 커버리지

1. 라인 커버리지가 100%라면?

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

line100

하지만 해당 지표만으로 “이 정도면 단위 테스트는 충분하다”고 단정할 수 있을까?

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