Unit Test

GreenBean·2021년 12월 1일
0
post-thumbnail

Unit Test

  • 유닛 테스트(Unit Test)는 프로그램 구현할 때 유닛 단위로 테스트를 진행하는 것을 의미
    • 여기서 유닛이란 보통 함수 단위라고 생각하면 됨
    • 프로그램은 결국 데이터와 이를 처리하는 함수로 구성되는데 각 함수를 충분히 테스트하면 전체 프로그램에서 문제가 발생하는 것을 최소화할 수 있기 때문에 함수를 구현한 후 함수의 입력과 예상되는 출력을 비교함으로써 함수를 테스트
  • 또한, 유닛 테스트는 코드를 수정하는 리팩터링 과정에서도 유용하게 사용
    • 리팩터링이란 기능은 그대로 둔채로 코드의 구조 등을 변경하는 것을 의미하는데 기존에 잘 동작하던 프로그램을 정확히 이해해서 구조를 변경하는 것은 쉬운 일이 아님
    • 따라서 리팩터링을 수행하기 앞서 유닛 테스트 코드가 있다면 코드를 수정한 후 유닛 테스트의 통과 여부를 통해 좀 더 빨리 수정에 따른 문제들을 찾을 수 있음

pytest

  • 파이썬 유닛 테스트에서는 주로 두 가지 모듈이 사용됨
    • unnittest 모듈은 표준 라이브러리(Standard library)로 파이썬 설치시 기본적으로 설치됨
    • 이와 달리 pytest는 추가로 설치해야 하는 모듈
      • pip 명령 : pip install pytest

pytest 사용해보기

# 예시 함수
def average(a):
    return sum(a) / len(a)
  • 위 함수가 제대로 구현됐는지 확인하기 위하여 테스트 코드를 추가
    • 테스트 코드가 포함된 test_mymath.py를 프로젝트에 추가
# 테스트 코드
from mymath import *

def test_average():
    assert average([1, 2, 3]) == 2
  • 터미털에서 pytest를 입력
    • 조금 더 결과를 자세히 출력하려면 -v 옵션을 사용
      • pytest -v
    • 다음과 같이 자동으로 test_라는 접두사(Prefix)로 시작하는 파일 또는 _test라는 접미사(Suffix)로 끝나는 파일을 찾아서 테스트 코드를 실행하고 그 결과를 화면에 출력

Tip! 여러가지 실행 방법

  • 특정 테스트 파일만 실행
    • pytest [파일명]
      • 예시 : pytest test.py
  • 테스트 모음의 서브셋 실행
    • 테스트명의 부분 문자열 일치로 테스트 실행하기
      • pytest -k [테스트명]
        • 예시 : pytest -k bye
        • 테스트명에 bye가 들어갔다면 pytest -k bye로 실행시킬 수 있음
    • 마커 기반으로 묶인 테스트 실행하기
      • 테스트 함수에 마크 데코레이터를 사용
        • @pytest.mark.[마커명]
        • 예시
          @pytest.mark.bye
          test_bye():
              assert True
      • test -m [마커명]
        • 예시 : test -m bye

fixture

  • fixture란 테스팅을 하는데 있어서 필요한 부분들을 혹은 조건들을 미리 준비 해놓은 리소스 혹은 코드들
    • 그 값은 어떤 객체가 될 수도 있고 환경이 될 수도 있고 DB가 될 수도 있음
    • DB가 필요해서 어떤 내용들을 테스트 할 때만 DB에 넣어서 확인을 한다던가 특정 파일을 테스팅 할 때 필요하다면 특정 파일들이 그 fixture라고 볼 수 있음
  • fixture는 적용된 각 테스트 함수 직전에 실행되는 함수
    • DB 연결, 테스트 할 URL, 일련의 데이터 입력 같은 테스트에 데이터를 전할 때 사용
    • 그러므로 매 테스트마다 같은 코드를 실행하는 대신 테스트들에 fixture를 붙이면 fixture는 실행되고 데이터를 반환할 것

fixture 사용해보기

  • @pytest.fixture
    • 테스트 함수는 fixture 이름을 인자에 넣어서 사용할 수 있음
import pytest

@pytest.fixture
def something():
    return 'bye'

@pytest.mark.bye
def test_say_something(something):
    assert something == 'bye'
  • 테스트 파일 내에 fixture를 넣으면 다른 테스트 파일에서 쓸 수가 없음
    • 범용적으로 사용하려면 conftest.py에 작성해야 함

Tip! conftest.py

  • fixture 함수들을 이 파일에 작성하면 여러 테스트 파일들에서 접근 가능
    • conftest.py 파일을 생성하고 fixture들을 작성
    • 여러 테스트 파일에서 fixture 이름을 인자로 넣어주면 사용 가능
  • test는 동일 파일 내에서 fixture를 찾고 없으면 conftest에서 찾아서 fixture 실행

parameterize

  • 동일 메서드에 대해서 여러 값을 테스트하기 위해 사용
    • @pytest.mark.parameterize("[변수명]", [(n, m)])
import pytest

@pytest.mark.parametrize("n, result", [(1, 2), (2, 4)])
def test_parameterize(n, result):
    assert n * 2 == result

N번의 테스트 실패 후 테스트 정지

  • 실행 시 pytest --maxfail = [N번]
  • 또는 pytest.ini 안에 아래와 같이 작성
[pytest]
addopts=--maxfail=[N번]

테스트 분산 실행

  • 테스트 개수가 늘어나다보면 순차적으로 실행하는 되는 것을 보는 것이 매우 답답
    • CPU 수를 늘려서 테스트가 분산 실행되도록 함
  • 설치 : pip install pytest-xdist
  • 실행 시 pytest -n [CPU 수 지정]
  • 또는 pytest.ini 안에 아래와 같이 작성
[pytest]
addopts = -n[CPU 수 지정]
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글