내 코드, 얼마나 테스트되고 있을까? ‘화이트박스 테스트’와 ‘코드 커버리지’ 높이는 법

우리는 이전에 ‘화이트박스 테스트’가 소프트웨어의 내부 코드 구조를 직접 들여다보는 테스트라고 배웠습니다.

그렇다면, 코드 내부를 ‘얼마나’, 그리고 ‘어떻게’ 체계적으로 테스트했다고 말할 수 있을까요?

그에 대한 답이 바로 ‘코드 커버리지’라는 척도와, 커버리지를 높이기 위한 ‘화이트박스 테스트 설계 기법’에 있습니다.

이번 글에서는 이 기법들에 대해 자세히 알아보겠습니다.

Q. 다시 한번, ‘코드 커버리지’가 무엇인가요?

‘코드 커버리지’는 우리가 작성한 테스트 코드가 실제 제품 코드의 몇 퍼센트를 실행시켰는지를 나타내는 객관적인 지표입니다.

‘코드 커버리지’가 높다고 해서 버그가 없다는 보장은 없습니다.

하지만 이 수치가 낮다는 것은, 한 번도 실행되지 않은 위험한 코드가 많다는 확실한 증거가 됩니다.

Q. [기법 1] 가장 기본적인 ‘구문 커버리지(Statement Coverage)’란 무엇인가요?

‘구문 커버리지’는 코드의 모든 실행 가능한 ‘줄(구문)’이 적어도 한 번 이상 실행되었는지를 측정하는 기준입니다.

‘라인 커버리지’라고도 불립니다.

  • 간단한 예제 코드: Python def check_age(age): print("나이 확인 시작") # 구문 1 if age >= 19: print("성인입니다") # 구문 2 else: print("미성년자입니다") # 구문 3
  • ‘구문 커버리지’ 100%를 위한 테스트:
    • check_age(20)을 호출하면 구문 1과 2가 실행됩니다.
    • 하지만 이것만으로는 구문 3이 실행되지 않아 커버리지가 100%가 아닙니다.
    • check_age(15)를 추가로 호출해야 구문 1과 3이 실행되어, 모든 구문을 커버하게 됩니다.
    • 즉, 이 두 가지 테스트를 모두 수행해야 ‘구문 커버리지’ 100%를 달성할 수 있습니다.

Q. [기법 2] 더 강력한 ‘분기 커버리지(Branch Coverage)’는 무엇인가요?

‘분기 커버리지’는 if, while 과 같은 모든 분기문의 ‘참(True)’과 ‘거짓(False)’ 조건이 각각 한 번 이상 실행되었는지를 측정하는 기준입니다.

‘결정 커버리지’라고도 합니다.

‘구문 커버리지’보다 더 신뢰도가 높은 척도입니다.

왜냐하면 구문 커버리지는 100%를 만족하더라도, 특정 분기를 테스트하지 못하는 경우가 있기 때문입니다.

  • 간단한 예제 코드: Python def is_positive(num): if num > 0: # 분기 1 return True
  • ‘분기 커버리지’를 위한 테스트:
    • is_positive(10)을 호출하면, num > 0 조건이 ‘참’인 경우가 테스트됩니다.
    • 하지만 이 테스트만으로는 ‘거짓’인 경우를 확인하지 못했으므로, ‘분기 커버리지’는 50%에 불과합니다.
    • is_positive(-5)를 추가로 호출하여, num > 0 조건이 ‘거짓’인 경우까지 테스트해야 ‘분기 커버리지’ 100%를 달성할 수 있습니다.

Q. [기법 3] 가장 꼼꼼한 ‘경로 커버리지(Path Coverage)’는 무엇인가요?

‘경로 커버리지’는 코드 내에서 실행될 수 있는 모든 가능한 ‘경로’를 적어도 한 번 이상 테스트하는 것입니다.

이는 가장 강력하고 포괄적인 기준입니다.

  • 간단한 예제 코드: Python def complex_check(a, b): if a > 0: # 분기 1 print("A is positive") if b > 0: # 분기 2 print("B is positive")
  • ‘경로 커버리지’를 위한 테스트:
    • 이 코드에는 총 4가지의 실행 경로가 존재합니다.
    • 경로 1: a > 0 참, b > 0 참 (예: a=5, b=5)
    • 경로 2: a > 0 참, b > 0 거짓 (예: a=5, b=-5)
    • 경로 3: a > 0 거짓, b > 0 참 (예: a=-5, b=5)
    • 경로 4: a > 0 거짓, b > 0 거짓 (예: a=-5, b=-5)
    • 이 네 가지 케이스를 모두 테스트해야 ‘경로 커버리지’ 100%를 달성할 수 있습니다.
  • 현실적인 한계:
    • 코드의 분기문이 조금만 많아져도, 가능한 경로의 수는 기하급수적으로 늘어납니다.
    • 따라서 현실적으로 모든 프로젝트에서 ‘경로 커버리지’ 100%를 달성하는 것은 거의 불가능하며, 매우 비효율적입니다.

결론: 목표를 아는 것이 중요하다

‘화이트박스 테스트 설계 기법’은 우리의 테스트가 얼마나 깊이 있게 코드를 검증하고 있는지 객관적으로 보여줍니다.

모든 프로젝트에서 100% 커버리지를 목표로 할 필요는 없습니다.

중요한 것은 각 커버리지 기준의 의미를 이해하고, 우리 프로젝트의 중요도와 리스크에 맞는 적절한 ‘코드 커버리지’ 목표를 설정하고 관리하는 것입니다.

일반적으로, 신뢰도 높은 테스트를 위해서는 최소한 ‘분기 커버리지’를 80% 이상으로 유지하는 것을 목표로 하는 경우가 많습니다.

QA가 ‘코드 커버리지’ 개념을 이해하면, 개발자와 함께 테스트의 충분성에 대해 더 깊이 있는 논의를 할 수 있습니다.

댓글 남기기