python 테스트 커버리지

‍한승운·2022년 9월 4일
0

python

목록 보기
13/13
post-thumbnail

테스트 커버리지(Test Coverage)

테스트 커버리지란?

  • 소프트웨어의 테스트 케이스가 얼마나 충족되었는지를 나타내는 지표 중 하나

  • 테스트를 진행하였을 때 ‘코드 자체가 얼마나 실행되었느냐’는 것이고, 이는 수치를 통해 확인할 수 있다.

    • 즉, 소스 코드를 기반으로 수행하는 화이트 박스 테스트

화이트 박스 테스트와 블랙 박스 테스트

블랙 박스 테스트 (Black-box test)

  • 소프트웨어의 내부 구조와 작동 원리를 모르는 상태에서 동작을 검사하는 방식이다.
  • 올바른 입력과 올바르지 않는 입력을 입력하여 올바른 출력이 나오는지 테스트하는 기법
  • 사용자 관점의 테스트 방식

화이트 박스 테스트(White-box test)

  • 응용 프로그램의 내부 구조와 동작을 검사하는 테스트방식
  • 소프트웨어 내부 소스 코드를 테스트하는 기법
  • 개발자 관점의 단위 테스트 방법

측정하는 기준

구문 (Statement)

라인(Line) 커버리지라고 부르기도 한다.

코드 한 줄이 한번 이상 실행된다면 충족된다.

예시)

def foo(x: int){
  print("start line") # 1번
  if (x > 0){  # 2번
    print("middle line") # 3번
  } 
  print("last line")  # 4번
}
  • x=-1 를 테스트 데이터로 사용할 경우,
    • if 조건문을 통과하지 못하기 떄문에, 3번 코드는 실행되지 못함.
    • 총 4개의 라인중에, 1,2,4번의 라인만 실행됨으로 구문 커버리지는 3/4 = 75% 가 된다.

조건(Condition)

모든 조건식의 내부 조건이 true/false을 가지게 되면 충족된다.
내부 조건이란, 조건식 내부의 각각 조건을 의미한다.

def foo(x: int, y:int){
  print("start line") # 1번
  if (x > 0 and y < 0){  # 2번
    print("middle line") # 3번
  } 
  print("last line")  # 4번
}
  • 조건 커버리지를 만족하는 테스트 케이스
    • x, y = (1,1), (-1,-1)
      • 즉, x >0 조건에도 true/false를 만족,
        y<0 조건에도 true/false 를 만족
    • 하지만, 테스트 케이스의 if문을 false만을 반환
  • 조건 커버리지를 기준으로 테스트를 진행할 경우, 구문 커버리지와 결정 커버리지를 만족하는 경우가 존재할 수 있음

결정(Decision)

브랜치(Branch) 커버리지라고 부르기도 합니다.

def foo(x: int, y:int){
  print("start line") # 1번
  if (x > 0 and y < 0){  # 2번
    print("middle line") # 3번
  } 
  print("last line")  # 4번
}
  • 모든 조건식이 true/false 를 가지게 되면 충족된다.

  • if 조건에 대해 모두 true/false를 가질 수 있는 테스트 케이스

    • x, y = (1, -1), (-1, 1)
      • 첫번째의 경우, x>0 과 y<0 모두 true
      • 두번째의 경우, x<0 에서 이미 false
    • 모든 조건식에 대해 true/false를 반환하므로 결정 커버리지를 충족

코드 커버리지의 중요성

  • 테스트 코드는 발생할 수 있는 모든 시나리오에 대해서 작성되어야 함
    • 이를 통해 휴먼 에러를 최대한 방지

가장 많이 사용되는 코드 커버리지

  • 구문 커버리지가 가장 대표적으로 사용되고 있다.

    • 그 이유는, 조건 커버리지나 브랜치 커버리지의 경우 실행에 대한 테스트 보다는 로직의 시나리오에 대한 테스트에 더 가깝다고 볼 수 있다.

      • 즉, 조건문이 존재하지 않는 경우 그 코드는 커버리지 대상에서 아예 제외되어, 해당 코드들을 테스트를 하지 않게된다.
    • 그러나, 구문 커버리지를 만족한다면, 모든 코드를 테스트 코드가 커버했다고 볼 수 있고,

      • 이는, 모든 시나리오를 테스트한다는 보장은 할 수 없지만,
        어떤 코드가 실행되더라도 해당 코드는 문제가 없다는 보장은 할 수 있다.
    • 이 이유로 구문 커버리지를 더 많이 사용한다.

코드 커버리지 도구

pytest-cov

  • Github : https://github.com/pytest-dev/pytest-cov

  • 설치 방법

    • pip install pytest-cov
  • 실행

  • 실행 옵션

    • --cov=PATH
      • 해당 PATH의 coverage 를 측정한다.
    • --cov-report=type
      • type 종류
        • term
        • term-missing
        • annotate
        • html
        • xml
  • pytest에서 사용하는 방법

    • pytest --create-db --cov-report term --cov=.

Mypy, pyflake8 - 코드 정적 분석 도구

  • 정적 프로그램 분석이란?
    • 실제 실행 없이 컴퓨터 소프트웨어를 분석하는 것
    • 즉, 실행하지 않은 상태에서 소스 코드나 컴파일된 코드를 이용해 프로그램을 분석함
  • 정적 분석의 한계
    • 정적 분석은 소스 코드의 모든 부분을 확인할 수 있지만, 실행 환경에서의 상태를 정확히 알수 없기 때문에 실행할 때에만 알 수 있는 데이터가 필요한 경우 정확히 분석할 수 없다.
  • pyflake8 ( 라이브러리 여러 묶은 wrapper 형태 )
    • PyFlakes - 코드의 에러 체크 ( Fxxx 형태의 pyflakes 실행 결과 )
      • ex) import 되었지만 사용하지 않는 라이브러리
      • ex) 정의되어있지 않은 이름
    • pycodestyle - PEP8 에 준거하여 코드 스타일이 되어 있는지를 체크 ( Exxx, Wxxx 형태의 pycodestyle 실행 결과)
    • Ned Batchedler's McCabe script : 순환 복잡도를 체크 ( Fxxx 형태의 pyflakes 실행 결과 )
  • mypy
    • Python 에서 개발하는 공식 Type Checker

여담

  • 우리 팀의 프로젝트의 테스트 커버리지를 테스트 해봤더니 경이로운 95% 를 달성하였다.
---------- coverage: platform darwin, python 3.9.13-final-0 ----------
Name                                                                                              Stmts   Miss  Cover
---------------------------------------------------------------------------------------------------------------------
...
---------------------------------------------------------------------------------------------------------------------
TOTAL                                                                                             49487   2655    95%
profile
함께 성장하고 싶은 백엔드 개발자

0개의 댓글