맨위로가기

코드 커버리지

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

코드 커버리지는 테스트 스위트에 의해 실행된 코드의 비율을 측정하는 데 사용되는 기준이다. 커버리지 기준에는 문장, 분기, 조건, 경로 커버리지 등이 있으며, 코드 커버리지를 통해 최종 제품 인증에 필요한 테스트 수준을 결정한다. 다양한 커버리지 기준이 존재하며, 함수, 구문, 에지, 분기, 조건 커버리지 등이 있다. 안전 필수 애플리케이션에서는 수정 조건/결정 커버리지(MC/DC)와 같은 고급 기준이 사용된다. 완전 경로 커버리지는 실용적이지 않으며, 산업 분야별로 항공, 자동차 등에서 안전 인증의 기준으로 활용된다.

더 읽어볼만한 페이지

  • 소프트웨어 메트릭 - 결합도
    결합도는 소프트웨어 설계에서 모듈 간 상호 의존성을 나타내는 척도로, 유지보수 및 수정 비용을 줄이기 위해 낮은 결합도를 지향하는 것이 중요하며, 내용 결합, 공통 결합, 외부 결합 등 다양한 유형으로 분류된다.
  • 소프트웨어 메트릭 - 응집도
    응집도는 객체 지향 프로그래밍에서 클래스 내 요소들의 연관성을 나타내는 척도로, 코드 가독성과 재사용성 향상, 유지보수 용이성, 모듈 복잡성 감소 등의 장점을 가지며 다양한 유형으로 분류된다.
  • 소프트웨어 테스트 도구 - Valgrind
    Valgrind는 동적 분석 도구들의 프레임워크로, 가상 머신 기반으로 작동하며 메모리 오류 감지, 멀티스레드 코드 분석 등 다양한 기능을 제공하지만, 정적 또는 스택 할당 데이터의 경계 오류는 모두 감지하지 못한다.
  • 소프트웨어 테스트 도구 - Doctest
    Doctest는 파이썬의 docstring과 내부 검사 기능을 활용하여 코드의 정확성을 검증하고 문서화하며, 테스트 실패 시 오류를 보고한다.
  • 소프트웨어 테스트 - 보안 취약점
    보안 취약점은 시스템의 설계, 구현, 운영, 관리상 결함이나 약점으로, 위협에 의해 악용되어 시스템 보안 정책을 위반할 수 있는 요소이며, ISO 27005, IETF RFC 4949, NIST SP 800-30, ENISA 등 다양한 기관에서 정의하고 있다.
  • 소프트웨어 테스트 - A/B 테스트
    A/B 테스트는 두 가지 이상의 대안을 비교하여 더 나은 성과를 판단하는 방법으로, 웹사이트, 애플리케이션 등 다양한 분야에서 사용자 인터페이스 등을 테스트하며 통계적 가설 검정을 기반으로 한다.
코드 커버리지
개요
유형소프트웨어 테스트 메트릭
목적소프트웨어 테스트의 효과 측정
측정 대상소스 코드
상세 정보
정의코드 커버리지는 소프트웨어 테스트의 메트릭이다. 소스 코드의 어떤 부분이 실행되었는지, 실행되지 않았는지 나타낸다.
활용테스트 스위트의 품질을 평가하는 데 사용할 수 있다.
소프트웨어 테스트 프로세스를 안내하는 데 사용할 수 있다.
장점테스트되지 않은 코드 영역을 식별하는 데 도움이 된다.
테스트 노력의 효과를 측정하는 데 도움이 된다.
소프트웨어 품질을 개선하는 데 도움이 된다.
단점높은 코드 커버리지가 반드시 높은 소프트웨어 품질을 의미하지는 않는다.
코드 커버리지를 높이기 위해 테스트를 작성하는 데 너무 집중하면 다른 중요한 테스트 측면을 간과할 수 있다.
코드 커버리지는 테스트가 코드를 실행하는지 여부만 알려주며, 코드가 올바르게 작동하는지는 알려주지 않는다.
커버리지 기준
구문 커버리지 (Statement coverage)프로그램 내의 모든 구문이 적어도 한 번 실행되는지 확인한다.
분기 커버리지 (Branch coverage)프로그램 내의 모든 분기가 적어도 한 번 실행되는지 확인한다.
조건 커버리지 (Condition coverage)프로그램 내의 모든 조건이 참과 거짓을 모두 갖는지 확인한다.
경로 커버리지 (Path coverage)프로그램 내의 가능한 모든 실행 경로가 적어도 한 번 실행되는지 확인한다.
함수 커버리지 (Function coverage)프로그램 내의 모든 함수가 적어도 한 번 호출되는지 확인한다.
라인 커버리지 (Line coverage)프로그램 내의 모든 라인이 적어도 한 번 실행되는지 확인한다.
조건/결정 커버리지 (Condition/Decision Coverage)분기 커버리지와 조건 커버리지를 결합한 것이다.
도구
사용 가능한 도구EclEmma
JaCoCo
Cobertura
추가 정보
주의 사항높은 코드 커버리지가 반드시 버그가 없음을 보장하지는 않는다.
코드 커버리지는 테스트 품질을 측정하는 하나의 요소일 뿐이다.

2. 커버리지 기준

코드 커버리지 기준은 테스트 스위트가 만족해야 하는 규칙이나 요구 사항을 정의한다.[4] 다양한 커버리지 기준이 존재하며, 각각 다른 수준의 테스트 강도를 제공한다.

소프트웨어 개발 환경에서 테스트 커버리지 정책을 구현할 때 고려해야 할 사항은 다음과 같다.


  • 최종 제품 인증에 대한 커버리지 요구 사항과 필요한 테스트 커버리지 수준 (구문, 분기/결정, 수정된 조건/결정 커버리지(MC/DC), LCSAJ (선형 코드 시퀀스 및 점프))
  • 테스트 대상 시스템에 부과된 요구 사항을 확인하는 테스트에 대한 커버리지 측정 여부 (DO-178B)
  • 생성된 오브젝트 코드가 소스 코드 구문에 직접 추적 가능한지 여부 (특정 인증의 경우, 그렇지 않으면 어셈블리 수준 커버리지 필요)


일반적으로 사용되는 테스트 커버리지의 형태로는 구문(또는 라인) 커버리지와 분기(또는 에지) 커버리지가 있다. 라인 커버리지는 테스트를 완료하기 위해 실행된 코드 라인 측면에서 테스트의 실행 흔적을 보고하고, 에지 커버리지는 테스트를 완료하기 위해 실행된 분기 또는 코드 결정 지점을 보고한다. 둘 다 백분율로 측정된 커버리지 지표를 보고하는데, 67% 분기 커버리지는 67% 구문 커버리지보다 더 포괄적이다.

일반적으로 테스트 커버리지 도구는 실제 프로그램 외에 계산 및 로깅을 발생시켜 응용 프로그램의 속도를 늦추므로, 프로덕션 환경에서는 수행되지 않는다. 또한, 이러한 도구의 영향을 받는 경쟁 조건이나 실시간 컴퓨팅 관련 결함은 테스트 환경에서 가려지거나 더 쉽게 발견될 수 있다.

코드 커버리지 측정에는 여러 기법이 있으며, 주요 기법은 다음과 같다.

  • '''문장 커버리지''': 소스 코드의 각 문장이 테스트에서 실행되었는지 여부를 판단한다.
  • '''분기 커버리지''': 제어 구조상의 분기에서 각 분기 방향이 테스트되었는지 여부를 판단한다.
  • '''조건 커버리지''': 분기 조건의 각 항목에서 참과 거짓 모두가 테스트되었는지 여부를 판단한다.
  • '''경로 커버리지''': 대상 코드의 가능한 모든 경로가 테스트에서 실행되었는지 여부를 판단한다.
  • '''입구/출구 커버리지''': 존재하는 모든 함수 호출이 테스트에서 실행되었는지 여부를 판단한다.


인프라 등 중요한 애플리케이션에서는 어떤 형태로든 코드 커버리지 100%를 달성해야 하는 경우가 많다.

경로 커버리지는 분기 커버리지, 문장 커버리지, 입구/출구 커버리지를 포함하지만, 문장 커버리지가 분기 커버리지를 포함하는 것은 아니다. 완전한 경로 커버리지는 현실적으로 불가능하며, 실용적인 경로 커버리지 기법으로는 루프 횟수가 다른 경로를 경로 클래스로 묶어 커버하는 방법이 있다.

일반적으로 테스트를 실행한 후 결과를 분석하여 코드 커버리지를 산출하고, 필요에 따라 테스트를 수정하여 재시도한다. 이러한 테스트 작성의 최종 목적은 코드 수정 시 버그 발생을 막는 회귀 테스트를 작성하는 것이다. 코드 커버리지는 백분율로 표시되지만, 기법에 따라 숫자가 달라질 수 있으므로 주의해야 한다.

2. 1. 기본 커버리지 기준

테스트 스위트에 의해 실행된 코드의 비율을 측정하기 위해 하나 이상의 ''커버리지 기준''이 사용된다. 이는 일반적으로 테스트 스위트가 충족해야 하는 규칙 또는 요구 사항으로 정의된다.[4]

주요 커버리지 기준은 다음과 같다.[5]

  • '''함수 커버리지''': 프로그램 내 각 함수(또는 서브루틴)가 호출되었는가?
  • '''구문 커버리지''': 프로그램 내 각 구문이 실행되었는가?
  • '''에지 커버리지''': 그래프제어 흐름 그래프 내 모든 에지가 실행되었는가?
  • '''분기 커버리지''': 각 제어 구조(예: ''if'' 및 ''case'' 문)의 각 분기(DD-경로라고도 함)가 실행되었는가? 예를 들어, ''if'' 문이 주어졌을 때, ''true'' 및 ''false'' 분기 모두가 실행되었는가? (이것은 에지 커버리지의 하위 집합이다.)
  • '''조건 커버리지''': 각 불리언 하위 표현식이 참과 거짓 둘 다로 평가되었는가? (술어 커버리지라고도 함)


결함 주입은 예외 처리 코드의 모든 조건 및 분기가 테스트 중에 적절한 커버리지를 갖도록 보장하는 데 필요할 수 있다.

일반적으로 일련의 테스트를 실행한 후, 그 결과를 분석하여 코드 커버리지를 산출하고, 필요에 따라 테스트를 수정하여 재시도한다. 이러한 테스트 작성의 최종적인 목적은 코드 수정 시의 버그 발생을 막는 회귀 테스트의 작성에 있다.

코드 커버리지는 일반적으로 백분율로 표시되지만, 기법에 따라 동일한 테스트에서도 숫자가 달라지므로 주의가 필요하다.

2. 1. 1. 함수 커버리지 (Function Coverage)

프로그램 내의 각 함수(또는 서브루틴)가 호출되었는지 측정한다.[5] 어떤 테스트 실행 중에 `foo` 함수가 최소 한 번 호출되면 함수 커버리지가 충족된다.

2. 1. 2. 구문 커버리지 (Statement Coverage)

구문 커버리지는 프로그램 내의 각 구문이 최소 한 번 이상 실행되었는지 여부를 측정한다.[5] 예를 들어, 다음 C 함수를 보자.



int foo (int x, int y)

{

int z = 0;

if ((x > 0) && (y > 0))

{

z = x;

}

return z;

}



이 함수의 구문 커버리지는 foo(1,1)과 같이 호출하면 충족된다. 이렇게 하면 함수 내 모든 줄(z = x; 포함)이 실행되기 때문이다.

코드 커버리지 측정 기법 중 하나인 문장 커버리지는 소스 코드의 각 문장이 테스트에서 실행되었는지 여부로 판단한다. 다음의 C 언어 코드를 보자.



void foo(int bar)

{

printf("This is ");

if (bar < 0)

{

printf("not ");

}

printf("a positive integer.\n");

return;

}



이 함수 "foo"를 인자 "bar = -1"로 호출하면 문장 커버리지는 달성된다. 그러나 분기 커버리지는 달성되지 않는다.

2. 1. 3. 분기 커버리지 (Branch Coverage)

분기 커버리지는 각 제어 구조(조건문)의 모든 분기(true/false)가 최소 한 번 이상 실행되었는지 측정한다. 예를 들어, 'if' 문에서 'true'와 'false' 분기가 모두 실행되었는지 확인한다. 이는 에지 커버리지의 하위 집합이다.[5]

다음은 C 함수 예시이다.



int foo (int x, int y)

{

int z = 0;

if ((x > 0) && (y > 0))

{

z = x;

}

return z;

}



`foo(1,1)`과 `foo(0,1)`을 호출하면 분기 커버리지가 충족된다. 첫 번째 경우는 두 `if` 조건이 모두 참이 되어 `z = x;`가 실행되고, 두 번째 경우는 첫 번째 조건 `(x>0)`이 거짓이 되어 `z = x;`가 실행되지 않는다.[5]

단락 회로 평가를 하지 않는 파스칼 같은 프로그래밍 언어에서는 조건 커버리지가 분기 커버리지를 의미하지 않을 수 있다.[5]



if a and b then



위 파스칼 코드에서 조건 커버리지는 다음 두 가지 테스트로 충족 가능하다.

  • `a=true`, `b=false`
  • `a=false`, `b=true`


그러나 이 테스트들은 `if` 조건 자체를 만족시키지 못하므로 분기 커버리지를 충족하지 않는다.[5]

결함 주입은 예외 처리 코드의 모든 조건과 분기가 테스트에서 적절한 커버리지를 갖도록 보장하는 데 필요할 수 있다.[5]

분기 커버리지는 제어 구조상의 분기에서 각 방향이 테스트되었는지 여부로 판단하는 코드 커버리지 측정 기법 중 하나이다. 코드 커버리지 기법은 서로 관련되어 있는데, 예를 들어 경로 커버리지는 분기 커버리지, 문장 커버리지, 입구/출구 커버리지를 포함하며, 문장 커버리지가 분기 커버리지를 포함하는 것은 아니다.

다음 C 언어 코드를 통해 문장 커버리지와 분기 커버리지의 관계를 확인할 수 있다.

```c

void foo(int bar)

{

printf("This is ");

if (bar < 0)

{

printf("not ");

}

printf("a positive integer.\n");

return;

}

```

함수 "foo"를 "bar = -1"로 호출하면 문장 커버리지는 달성되지만, `if` 문의 `false` 분기가 실행되지 않으므로 분기 커버리지는 달성되지 않는다.

2. 1. 4. 조건 커버리지 (Condition Coverage)

조건 커버리지는 각 불리언 하위 표현식(predicate)이 참(true)과 거짓(false) 값으로 모두 평가되었는지 여부를 측정한다. 이를 술어 커버리지라고도 한다.[5]

예를 들어, 다음 C 함수를 고려할 수 있다.

```cpp

int foo (int x, int y)

{

int z = 0;

if ((x > 0) && (y > 0))

{

z = x;

}

return z;

}

```

조건 커버리지는 `foo(1,0)`, `foo(0,1)`, `foo(1,1)`을 호출하는 테스트로 충족된다. 이는 첫 번째 경우 `(x>0)`이 `true`로 평가되고, 두 번째 경우 `false`로 평가되기 때문이다. 동시에 첫 번째 경우는 `(y>0)`을 `false`로 만들고, 두 번째 경우는 `(y>0)`을 평가하지 않으며(불리언 연산자의 지연 평가 때문), 세 번째 경우는 `true`로 만든다.[5]

단락 회로 평가를 수행하지 않는 프로그래밍 언어에서 조건 커버리지는 반드시 분기 커버리지를 의미하지는 않는다. 예를 들어, 다음 파스칼 코드 조각을 고려할 수 있다.[5]

```pascal

if a and b then

```

조건 커버리지는 두 가지 테스트로 충족될 수 있다.[5]

  • `a=true`, `b=false`
  • `a=false`, `b=true`


그러나 이 테스트 세트는 분기 커버리지를 충족하지 않는다. 왜냐하면 어떠한 경우에도 `if` 조건을 충족하지 않기 때문이다.[5]

분기 조건의 각 항목에서 참과 거짓 모두가 테스트되었는지 여부로 조건 커버리지를 판단한다.[5]

2. 1. 5. 에지 커버리지 (Edge Coverage)

제어 흐름 그래프의 모든 에지가 실행되었는지 측정한다.[5]

2. 2. 고급 커버리지 기준

기본 커버리지 기준 외에 더 높은 수준의 안전성과 신뢰성이 요구되는 시스템에서는 고급 커버리지 기준이 사용된다.

'''조건/결정 커버리지'''는 결정 커버리지와 조건 커버리지를 모두 충족해야 한다. 안전 필수 애플리케이션(예: 항공 전자 소프트웨어)에서는 '''수정 조건/결정 커버리지(MC/DC)'''를 충족해야 하는 경우가 많다. MC/DC는 각 조건이 결정 결과에 독립적으로 영향을 미치도록 하여 조건/결정 기준을 확장한다.[6]

MC/DC를 만족하는 예시는 다음과 같다.

```pascal

if (a or b) and c then

```

위 코드는 아래의 테스트 집합으로 조건/결정 커버리지를 충족할 수는 있지만, 'b'와 'c'의 값에 따라 출력에 영향이 없을 수 있으므로 MC/DC는 충족하지 못한다.

abc
거짓거짓거짓



MC/DC를 충족하려면 다음 테스트 집합이 필요하다.

abc
거짓거짓
거짓
거짓거짓
거짓


2. 2. 1. 결정 커버리지 (Decision Coverage)

결정 커버리지는 함수 커버리지와 분기 커버리지를 결합한 것이다. 이 기준은 프로그램의 모든 진입점 및 종료점이 최소 한 번 호출되었고, 프로그램의 모든 결정이 가능한 모든 결과를 최소 한 번씩 수행해야 한다는 조건을 만족해야 한다.[6] 여기서 결정은 조건과 0개 이상의 불리언 연산자로 구성된 불리언 표현식을 의미한다. "결정 커버리지"라는 용어는 때때로 분기 커버리지와 같은 의미로 사용되기도 한다.[7]

2. 2. 2. 수정 조건/결정 커버리지 (Modified Condition/Decision Coverage, MC/DC)

'''조건/결정 커버리지'''는 결정 커버리지와 조건 커버리지가 모두 충족되어야 한다. 그러나 안전 필수 애플리케이션(예: 항공 전자 소프트웨어)의 경우 '''수정 조건/결정 커버리지(MC/DC)'''가 충족되어야 하는 경우가 많다.[6] 이 기준은 각 조건이 결정 결과에 독립적으로 영향을 미쳐야 한다는 요구 사항으로 조건/결정 기준을 확장한다.

예를 들어, 다음 코드를 고려해 보자.

```pascal

if (a or b) and c then

```

조건/결정 기준은 다음 테스트 집합으로 충족된다.

abc
거짓거짓거짓



그러나 위의 테스트 집합은 첫 번째 테스트에서 'b'의 값과 두 번째 테스트에서 'c'의 값이 출력에 영향을 미치지 않으므로 수정 조건/결정 커버리지를 충족하지 않는다. 따라서 MC/DC를 충족하려면 다음 테스트 집합이 필요하다.

abc
거짓거짓
거짓
거짓거짓
거짓


2. 2. 3. 다중 조건 커버리지 (Multiple Condition Coverage)

이 기준은 각 결정 내의 모든 조건 조합을 테스트해야 한다.[1] 예를 들어, 이전 섹션의 코드 조각은 다음의 8가지 테스트가 필요하다.

abc
거짓거짓거짓
거짓거짓
거짓거짓
거짓
거짓거짓
거짓
거짓


2. 2. 4. 매개변수 값 커버리지 (Parameter Value Coverage, PVC)

'''매개변수 값 커버리지'''(Parameter value coverage, PVC)는 매개변수를 사용하는 메서드에서 해당 매개변수의 모든 일반적인 값을 고려해야 한다고 요구한다. 즉, 매개변수에 대해 가능한 모든 일반적인 값을 테스트하는 것이다.[8] 예를 들어 문자열의 일반적인 값은 다음과 같다.

  • 1) null
  • 2) 빈 문자열
  • 3) 공백 (스페이스, 탭, 줄 바꿈)
  • 4) 유효한 문자열
  • 5) 유효하지 않은 문자열
  • 6) 단일 바이트 문자열
  • 7) 이중 바이트 문자열


또한 매우 긴 문자열을 사용하는 것도 적절할 수 있다. 각 가능한 매개변수 값을 테스트하지 않으면 버그가 발생할 수 있다. 이 중 하나만 테스트하면 각 라인이 커버되기 때문에 100% 코드 커버리지가 될 수 있지만, 7가지 옵션 중 하나만 테스트하면 PVC는 14.2%에 불과하다.

2. 2. 5. 기타 커버리지 기준

덜 자주 사용되는 커버리지 기준은 다음과 같다.

  • '''선형 코드 시퀀스 및 점프(LCSAJ) 커버리지''' (JJ-경로 커버리지): 모든 LCSAJ/JJ-경로가 실행되었는지를 측정한다.
  • '''경로 커버리지''': 코드의 주어진 부분에 대한 모든 가능한 경로가 실행되었는지를 측정한다.
  • '''진입/종료 커버리지''': 함수의 모든 가능한 호출과 반환이 실행되었는지를 측정한다.
  • '''루프 커버리지''': 모든 가능한 루프가 0번, 1번, 그리고 1번 이상 실행되었는지를 측정한다.
  • '''상태 커버리지''': 유한 상태 기계의 각 상태에 도달하고 탐색되었는지를 측정한다.
  • '''데이터 흐름 커버리지''': 각 변수 정의와 사용이 도달하고 탐색되었는지를 측정한다.


안전 필수 또는 신뢰성 애플리케이션은 종종 어떤 형태의 테스트 커버리지를 100% 달성해야 한다. 예를 들어, ECSS-E-ST-40C 표준은 4가지 서로 다른 중요도 레벨 중 2가지에 대해 100% 구문 및 결정 커버리지를 요구한다. 다른 레벨의 경우, 목표 커버리지 값은 공급업체와 고객 간의 협상에 따라 달라진다. 그러나 특정 목표 값, 특히 100%를 설정하는 것은 여러 가지 이유로 실무자들로부터 비판을 받아 왔다. 마틴 파울러는 "100%와 같은 것에 대해 의심을 품을 것입니다. 이는 커버리지 수치를 만족시키기 위해 테스트를 작성하지만, 자신이 무엇을 하고 있는지 생각하지 않는 것처럼 보입니다."라고 언급했다.

위의 커버리지 기준 중 일부는 서로 연결되어 있다. 예를 들어, 경로 커버리지는 결정, 구문 및 진입/종료 커버리지를 의미한다. 결정 커버리지는 모든 구문이 분기의 일부이기 때문에 구문 커버리지를 의미한다.

연속적인 n개의 결정(decision)을 갖는 모든 모듈은 최대 2^n개의 경로를 가질 수 있으며, 루프 구조는 무한히 많은 경로를 생성할 수 있기 때문에, 위에서 설명한 유형의 전체 경로 커버리지는 일반적으로 실용적이지 않거나 불가능하다. 많은 경로가 또한 실행 불가능할 수 있으며, 이는 해당 특정 경로가 실행되도록 할 수 있는 테스트 대상 프로그램에 대한 입력이 없다는 것을 의미한다. 그러나 실행 불가능한 경로를 식별하기 위한 범용 알고리즘은 불가능한 것으로 증명되었다(그러한 알고리즘은 정지 문제를 해결하는 데 사용될 수 있다). 기본 경로 테스트는 예를 들어 전체 경로 커버리지를 달성하지 않고도 전체 분기 커버리지를 달성하는 방법이다.

실용적인 경로 커버리지 테스트 방법은 대신 루프 실행 횟수만 다른 코드 경로의 클래스를 식별하려고 시도하며, "기본 경로" 커버리지를 달성하기 위해 테스터는 모든 경로 클래스를 커버해야 한다.

3. 커버리지 기준 간의 관계

일부 커버리지 기준은 서로 포함 관계를 가진다. 예를 들어, 경로 커버리지는 결정 커버리지, 구문 커버리지, 진입/종료 커버리지를 포함한다. 결정 커버리지는 모든 구문이 분기의 일부이기 때문에 구문 커버리지를 포함한다.

연속적으로 n개의 결정(decision)을 가지는 모든 모듈은 최대 2^n개의 경로를 가질 수 있으며, 루프 구조는 무한히 많은 경로를 생성할 수 있다. 많은 경로가 또한 실행 불가능할 수 있는데, 이는 해당 특정 경로가 실행되도록 할 수 있는 테스트 대상 프로그램에 대한 입력이 없다는 것을 의미한다. 그러나 실행 불가능한 경로를 식별하기 위한 범용 알고리즘은 불가능한 것으로 증명되었다(그러한 알고리즘은 정지 문제를 해결하는 데 사용될 수 있다). 기본 경로 테스트는 전체 경로 커버리지를 달성하지 않고도 전체 분기 커버리지를 달성하는 방법의 예시이다.

실용적인 경로 커버리지 테스트 방법은 루프 실행 횟수만 다른 코드 경로의 클래스를 식별하려고 시도하며, "기본 경로" 커버리지를 달성하기 위해 테스터는 모든 경로 클래스를 커버해야 한다.

4. 완전 경로 커버리지의 현실적 어려움

이론적으로, n개의 결정문을 가진 모듈은 최대 2n개의 경로를 가질 수 있고, 루프 구조는 무한한 경로를 생성할 수 있기 때문에, 모든 가능한 경로를 테스트하는 완전 경로 커버리지는 일반적으로 실용적이거나 불가능하다. 또한, 실행 불가능한 경로(해당 경로를 실행할 수 있는 입력 조합이 없는 경우)도 존재한다. 그러나 실행 불가능한 경로를 식별하기 위한 범용 알고리즘은 불가능한 것으로 증명되었다(그러한 알고리즘은 정지 문제를 해결하는 데 사용될 수 있다). 기본 경로 테스트는 전체 경로 커버리지를 달성하지 않고도 전체 분기 커버리지를 달성하는 방법의 예시이다.

실용적인 경로 커버리지 테스트 방법은 루프 실행 횟수만 다른 코드 경로의 클래스를 식별하고, "기본 경로" 커버리지를 달성하기 위해 모든 경로 클래스를 커버한다.

5. 산업 분야별 적용

코드 커버리지는 여러 산업 분야에서 소프트웨어의 품질과 안전성을 확인하는 데 중요한 역할을 한다. 특히, 안전이 매우 중요한 항공 및 자동차 산업에서는 필수적인 요소로 간주된다.


  • 항공 산업: DO-178B[17] 및 DO-178C[18]에서는 항공 전자 장비의 안전 인증을 위한 지침을 제공하며, 이 지침에는 테스트 커버리지가 중요한 고려 사항으로 포함된다.
  • 자동차 산업: ISO 26262[19] "도로 차량 - 기능 안전" 파트 6에서는 자동차 안전 표준에 따른 코드 커버리지 요구사항을 명시하고 있다.

5. 1. 항공 산업

항공 전자 장비의 안전 인증에는 테스트 커버리지가 중요한 고려 사항 중 하나이다. 항공 전자 장비가 미국 연방 항공국(FAA)에 의해 인증되는 지침은 DO-178B[17] 및 DO-178C[18]에 문서화되어 있다.

5. 2. 자동차 산업

자동차 안전 표준 ISO 26262 "도로 차량 - 기능 안전"의 파트 6에서도 코드 커버리지를 요구하고 있다.[19]

6. 코드 커버리지 도구

코드 커버리지 측정 및 분석에는 다양한 도구가 사용된다. 이러한 도구는 일반적으로 목표 소프트웨어를 특수한 옵션이나 라이브러리를 사용하여 빌드하고, 제어된 환경에서 실행하여 소스 코드의 함수 지점에 매핑되는 실행된 모든 함수를 추적한다. 이를 통해 일반적인 조건에서는 거의 접근되지 않는 소프트웨어 부분을 테스트하고, 가장 중요한 조건(함수 지점)이 테스트되었는지 확인할 수 있다.[17]

테스트 커버리지 도구는 실제 프로그램 외에 계산 및 로깅을 추가하여 응용 프로그램의 속도를 늦출 수 있다. 따라서 일반적으로 이러한 분석은 프로덕션 환경에서는 수행되지 않는다. 그러나 직접 테스트가 아닌 분석을 통해 어느 정도의 커버리지 매핑을 근사할 수 있는 소프트웨어 클래스도 있다.[17]

테스트 커버리지 도구를 사용할 때 주의할 점은, 일부 경쟁 조건이나 실시간 컴퓨팅에 민감한 작업은 테스트 환경에서 실행될 때 가려질 수 있다는 것이다. 반면, 이러한 결함 중 일부는 테스트 코드의 추가 오버헤드로 인해 더 쉽게 발견될 수도 있다.[17]

대부분의 전문 소프트웨어 개발자는 C1 및 C2 커버리지를 사용한다. C1은 구문 커버리지를, C2는 분기 또는 조건 커버리지를 나타낸다. C1과 C2를 조합하면 코드베이스 대부분의 구문을 커버할 수 있다. 구문 커버리지는 함수 커버리지도 포함하는데, 여기에는 진입 및 종료, 루프, 경로, 상태 흐름, 제어 흐름, 데이터 흐름 커버리지가 포함된다. 이러한 방법을 통해 대부분의 소프트웨어 프로젝트에서 거의 100%의 코드 커버리지를 달성할 수 있다.[16]

7. 한계점 및 비판

코드 커버리지 100%를 달성하는 것이 반드시 소프트웨어의 완벽한 품질을 보장하는 것은 아니다. 마틴 파울러(Martin Fowler)는 100% 커버리지 목표에 대해 의문을 제기하며, 테스트를 위한 테스트가 아닌 실제 결함을 발견하고 예방하는 데 중점을 두어야 한다고 지적했다.[16]

테스트 커버리지 도구는 프로그램 실행 속도를 늦출 수 있으며, 경쟁 조건이나 실시간 컴퓨팅과 관련된 문제는 테스트 환경에서 발견하기 어려울 수 있다.[16]

참조

[1] 서적 Testing for Continuous Delivery with Visual Studio 2012 https://msdn.microso[...] Microsoft 2016-06-16
[2] 웹사이트 Test Coverage with EclEmma http://realsearchgro[...] North Carolina State University 2016-06-16
[3] 간행물 Systematic mistake analysis of digital computer programs Association for Computing Machinery 1963-02
[4] 서적 Introduction to Software Testing Cambridge University Press
[5] 서적 The Art of Software Testing, 2nd edition Wiley
[6] 문서 What is a "Decision" in Application of Modified Condition/Decision Coverage (MC/DC) and Decision Coverage (DC)? http://www.faa.gov/a[...] Position Paper CAST-10 2002-06
[7] 문서 Types of Model Coverage. http://www.mathworks[...] MathWorks
[8] 웹사이트 Unit Testing with Parameter Value Coverage (PVC) http://www.rhyous.co[...]
[9] 논문 "On the relationship between two control-flow coverage criteria: all JJ-paths and MCDC" 2006
[10] 논문 "A Survey on Data-Flow Testing" 2017-03
[11] 문서 Space engineering - Software ECSS Secretariat, ESA-ESTEC 2009-03
[12] 간행물 "Is 100% Test Coverage a Reasonable Requirement? Lessons Learned from a Space Software Project" https://www.research[...] Springer 2017
[13] 웹사이트 TestCoverage. https://martinfowler[...] Martin Fowler's blog
[14] 서적 Computers, Software Engineering, and Digital Devices https://books.google[...] CRC Press
[15] 서적 The Compiler Design Handbook: Optimizations and Machine Code Generation CRC Press
[16] 서적 Software testing techniques, 2nd edition Dreamtech press
[17] 문서 Software Considerations in Airborne Systems and Equipment Certification, Radio Technical Commission for Aeronautics RTCA/DO-178B 1992-12-01
[18] 문서 Software Considerations in Airborne Systems and Equipment Certification, Radio Technical Commission for Aeronautics RTCA/DO-178C 2012-01
[19] 서적 ISO 26262-6:2011(en) Road vehicles -- Functional safety -- Part 6: Product development at the software level http://www.iso.org/i[...] International Standardization Organization



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com