programming4 MIN READ

[소프트웨어 테스트] 03. 구조적 테스트와 코드 커버리지

[소프트웨어 테스트] 03. 구조적 테스트와 코드 커버리지

소프트웨어 테스트 시리즈의 글입니다.

구조적테스트 = 소스코드의 구조를 사용하여 테스트를 도출.
코드커버리지는 어떻게 사용해야 유용한 지표일까?

3.1 코드 커버리지, 올바른 방법

요즘은 코드커버리지 툴이 잘 되어있어서 실행하면 테스트코드가 어느 코드라인을 테스트 하지 않앗는지 알수있음. if문의경우 특정 분기가 실행되었는지 아닌지도 확인 가능.

3.2 구조적 테스트 간략히 살펴보기

  1. 명세기반 테스트 수행
  2. 구현사항(코드)읽기
  3. 코드 커버리지 도구 수행
  4. 테스트가 수행되지 않은 코드 확인
  5. 이해하기
  6. 테스트 가치 결정하기
  7. 자동화된 테스트테케이스 구현하기
  8. 추가로 고안할 흥미로운 테스트 찾아보기 ⇒ 즉, 구조적테스트는 명세기반 테스트로 고안한 테스트스위트를 보강하는 역할 명세기반과 마찬가지로 반복적임.

3.3 코드 커버리지 기준

코드 수행여부를 결정할때 얼마나 엄격하게 따질지 결정해야함

3.3.1 코드 줄 커버리지

어떤식으로든 해당 라인을 실행하면ok

3.3.2 분기 커버리지

분기 지시문(if, for, while 등) 이 어떻게 평가되는지에 따라 프로그램을 다르게 동작한다는 점을 고려. 플로우차트 그렸을때 분기문의 모든 간선을 수행했다면 분기커버리지 100%를 의미.

3.3.3 조건+분기 커버리지

조건+분기 커버리지는 분기뿐 아니라 분기문의 각 조건도 고려.

3.3.4 경로 커버리지

프로글매이 수행할 수 있는 모든 실행 경로를 수행. 달성 불가능한 경우도 종종 있고, 기본적으로 비용이 너무 많이듬.

3.4 복잡한 조건과 MC/DC 커버리지 기준

테스트 스위트 구축을 위한 노력, 비용은 최소화 / 찾아낼수잇는 버그는 최대화 하려면? 조건/의사결정 커버리지(MC/DC: modified condition / decision coverage) 적용 조건의 조합들을 살펴보고, 중요한 조합만 찾아서 테스트. 특정 조건이 다른 조건과는 상관 없이 전체 의사결정 결과에 영향을 미칠수 있는 조건만으로 구성. → 조건갯수(N) + 1 개 케이스로 유의미한 테스트 가능.

3.5 반복문과 유사구조 처리하기

반복 경계 적합 기준을 적용.

  • 반복문 0번 케이스
  • 반복문 1번 케이스
  • 반복문 n번 케이스 필요한경우 n번케이스를 두개이상 만드는것을 두려워하지말자

3.6 기준 포함과 선택

경로 커버리지 > MC/DC > 분기+조건 커버리지 > 분기커버리지 , 조건 커버리지 > 명령/코드줄 커버리지 순으로 빡세다 결국 얼마나 빡센 기준을 선택할지는 트레이드 오프이므로 선택은 우리의몫

3.8 경계 테스트와 구조적 테스트

접점 및 거점을 찾아내고 테스트를 수행하는 개념은 구조적 테스트에 잘 들어맞는다

3.9 구조적 테스트만 적용 → 충분X

물론 명세기반+구조적테스트까지 적용하면 꽤 효과적이지만 흥미로운 케이스들을 놓칠수있음. 명세에 지식을 더한 흥미로운 테스트들을 항상 고려해야함

3.10 현업에서의 구조적 테스트

3.10.1 사람들이 코드커버리지를 왜 싫어할까

의미없는 테스트만으로도 코드커버리지100퍼 달성은 가능. 하지만 명세기반+구조적 테스트를 수행하고 코드커버리지로 부족한 테스트를 찾는데 사용한다면 효과적으로 사용 가능. 우리가 목표로 할 ㅁ마법같은 커버리지 기준은 찾지 못했지만 많은 논문에서 코드커버리지를 지지함 일단 커버리지가 낮다면 제대로 테스트되지 않은것은 확실.

3.10.2 커버리지 100%의 의미

수치달성은 우리의 목표가 아님.. 코드 줄 커버리지, 분기 커버리지, 조건+분기 커버리지 각자 다를 수 잇으니 용어를 제대로 파악하자

3.10.3 어떤 커버리지 기준을 사용할것인가

구조적테스트 = 명세기반 테스트를 보완하기 위함 특정 if문에는 분기 커버리지, 다른 복잡한 if문에는 MC/DC를 사용하는 등 실용적 방법으로 접근해보자.

3.10.4 표현식이 복잡하다면 MC/DC

복잡한 식을 나누는것이 불가능할때는 MC/DC 추천 단 엉성하게 설계된 표현식을 단순화할수있을지 살펴보는게 우선.

3.10.5 그 외 커버리지 기준

구조적 테스트에 접근하는 또다른 방법은 데이터 흐름을 살펴보는것. 데이터가 어떻게 흐르는지 조사하고 변수를 건드린 경로를 테스트할수있도록 하는것.

3.10.6 수행하지 말아야할 것

단순 커버리지를 올리기 위한 무의미한 테스트. 게터, 세터 대상의 테스트. 등은 하지말자.

모든 코드는 다른 방식으로 증명될때까지 수행되어야함.

3.11 돌연변이 테스트

커버리지만으로는 테스트 스위트의 품질을 알수없음 돌연변이 테스트 : 존재하는 코드에 일부러 버그를 주입해 테스트 스위트가 깨지는지 검사. 깨지지 않으면 오히려 문제인것.

  • 유능한 프로그래머 가설 : 단순 오류를 고쳐가며 점점 정확한 프로그램이 되어감
  • 커플링 효과 : 복잡한 버그는 작은 버그가 모여 발생함

파이테스트 같은 툴에서는 아래와 같이 돌연변이 테스트 수행

  • 조건부 경계 대체
  • 증분 (ex. i++ → i—)
  • 음수반전
  • 산술연산자 교체
  • 강제 true 반환
  • 조건 제거 if(true)

테스트 비용은 비싸지만 종종 유익함. 민감한 시스템에 적용 추천.