swtest

코드 커버리지 Code Coverage 종류와 예시


by Kitle · 2020. 08. 20.



코드 커버리지(Code Coverage)

코드 커버리지란 소프트웨어의 테스트를 논할 때 얼마나 테스트가 충분한가를 나타내는 지표중 하나다. 말 그대로 코드가 얼마나 커버되었는가이다. 소프트웨어 테스트를 진행했을 때 코드 자체가 얼마나 실행되었냐는 것이다.

코드의 구조를 이루는 것은 크게 구문(Statement), 조건(Condition), 결정(Decision)이다. 이러한 구조를 얼마나 커버했느냐에 따라 코드커버리지의 측정기준은 나뉘게 된다. 일반적으로 많이 사용되는 커버리지는 구문(Statement)커버리지이며, 실행 코드라인이 한번 이상 실행 되면 충족된다. 조건(Condition)커버리지는 각 내부 조건이 참 혹은 거짓을 가지면 충족된다. 결정(Decision) 커버리지는 각 분기의 내부 조건자체가 아닌 이러한 조건으로 인해 전체 결과가 참 혹은 거짓이면 충족된다. 그리고 조건과 결정을 복합적으로 고려하는 MC/DC 커버리지 또한 있다.


개별 조건식과 전체 조건식

if(a > b and a < c):
print('some')
개별 조건식
1) a > b
2) a < c

전체 조건식 → 결정 포인트
(a > b and a < c)



커버리지 측정을 위한 예시 코드
if(a and b):
print('1')
else: print('2')
해당코드로 다양한 커버리지를 측정하면 다음과 같다.


구문 커버리지
구문 커버리지는 모든 구문(코드라인)이 한번이상 수행되면 된다. 여기서는 조건문이 있으므로 a and b 전체 조건에 따라 T한번 F한번을 만족해야 한다.

AB구문 커버리지
111, 2 라인 구문 커버
101, 3 라인 구문 커버
- if문이 참인 경우 1,2번 라인 구문을 커버한다.
- if문이 거짓인 경우 1,3번 라인 구문을 커버한다. 

python coverage 를 사용한 커버리지 특정 시 위의 경우 각 라인별로 총 3개의 구문으로 판단하며,
 - A=1, B=1만 테스트 했을 때 3개구문중에 2개를 커버했으므로 66% 로 표시된다.  
 - A=1, B=0만 테스트 했을 때 3개구문중에 2개를 커버했으므로 66%로 표시된다.


결정 커버리지
AB전체 조건식(결정포인트)
100
111
-전체 조건이 T, F 만 나오게 만들면 됨 
-단점 개별 조건식에 오류가 있는 경우 찾지 못할 수 있음

조건 커버리지
AB전체 조건식(결정포인트)
100
010
- 개별조건식이 각각 T, F 만 나오게 만들면 됨
- 개별조건식의 T/F는 커버되었지만 전체 조건식의 T/F를 보장하지 못함


조건/결정 커버리지
AB전체 조건식(결정포인트)
000
111
전체 조건식 T/F, 개별조건식 T/F를 모두 나오게 만들면 됨


변형 조건/결정 커버리지(MC/DC)

AB전체 조건식(결정포인트)
010
100
111
모든 결정 포인트 내의 전체 조건식은 적어도 한번 T, F를 가져야 함
결정 포인트 내의 개별 조건식은 적어도 한번 T, F를 가져야 함
각 개별 조건식이 다른 개별 조건식에 영향을 받지 않고 전체 조건식의 결과에 독립적으로 영향을 주어야 함
- 이론적으로 가장 안전한 조합이며 케이스도 줄일 수 있으나 수동으로 적용하기엔 리소스 많이 소모됨, 수동으로 하면 실수 가능성 많음


다중 조건 커버리지
AB전체 조건식(결정포인트)
000
010
100
111
모든 개별 조건식의 논리적 조합을 고려하면 됨 (여기서는 a and b 의 모든 조합)


현실 적용 팁

현실적으로 손으로 하기엔 리소스가 너무 많이 든다. 따라서 툴을 이용한다. 일반적인 툴들은 커버리지 %정도만 표시한다.따라서 툴을 이용한다고 커버리지가 상승하는 것이 아니라 해당 조건들을 만족시킬 수 있는 테스트 코드 (및 데이터)를 같이 만들어야 하므로 d-day가 정해진 프로젝트에서는 burden으로 작용한다. (비싼 툴은 조건에 맞는 케이스를 뽑아 줄지도... 써보지 않아 모르겠음)
회사에 따라 케바케지만 특정 커버리지 기준 예) 80% 달성 목표 을 두고 관리하는 회사도 있다.

n사 같은 경우는 커버리지를 6-7년전에는 굉장히 중요시 여기다가 몇년사이에는 숫자놀이(?) 보다는 빨리 서비스 하고 피드백 받고 유지보수하는 것이 더 좋겠다고 전향하기도 했다. 그만큼 어려운 부분이다.

특히 state / branch 같은 경우는 어지간한 툴에서 커버하지만 언어에 따라 MC/DC 같은 것은 고가 상용 툴에서 지원하는 경우가 있어 도입이 어려울 수도 있다.

테스팅분야의 세계적 전문가인 스튜어트 리드(Stuart Reid) 테스팅 박사는 MC/DC가 어려우면 차라리 MCC 를 사용하는 것도 나쁘지 않다고 했다. (MC/DC에서 결과에 독립적으로 영향을 주는 개별 조건식을 골라내느거보다 그냥 풀조합인 MCC가 케이스 조합하기도 쉬울 수 있으니)

또한 커버리지를 달성 했다고 해서 버그가 없다는건 아니다.

요구사항이 바뀌는 경우, 기능이 바뀌는 경우 커버리지를 유지하기 위해 굉장한 노력이 들어가거나 그동안의 테스트 코드들이 무쓸모 되는곳도 발생할 수 있다.


참조 : https://ko.wikipedia.org/wiki/%EC%BD%94%EB%93%9C_%EC%BB%A4%EB%B2%84%EB%A6%AC%EC%A7%80

참조 : https://www.slideshare.net/daunjae/istqb-420153