파이썬212번5 MIN
pytest 기초: assert 한 줄로 쓰는 테스트
평범한 함수와 내장 assert만으로 테스트를 작성하는 pytest의 철학, 풍부한 실패 메시지, 실행과 선택 방법까지 완전 정복합니다.
이 글은 PALDYN Tech Blog의 글입니다.원문 보기
지난 글에서 표준 라이브러리 unittest로 테스트의 기본기를 익혔다. 클래스를 만들고 assertEqual 같은 전용 메서드를 쓰는 방식이었는데, 막상 써 보면 검증 한 줄을 적기 위해 외워야 할 메서드가 꽤 많다고 느껴진다. 파이썬 생태계에서 사실상 표준으로 자리 잡은 pytest는 이 부담을 거의 없앤다. 평범한 함수와 파이썬 내장 assert 문만으로 테스트를 쓰게 해 주면서도, 실패했을 때는 unittest보다 더 친절한 정보를 보여 준다.
함수 하나가 테스트 하나
pytest에서는 클래스도, 상속도 필요 없다. test_로 시작하는 그냥 함수를 만들고 그 안에서 assert로 검증하면 끝이다. 먼저 pip install pytest로 설치한다.
# test_math.py
def add(a, b):
return a + b
def test_add_positive():
assert add(2, 3) == 5
def test_add_negative():
assert add(-1, -1) == -2
unittest였다면 class TestMath(unittest.TestCase)로 감싸고 self.assertEqual(...)을 호출해야 했을 코드가, pytest에서는 모듈 수준 함수와 assert 한 줄로 줄어든다. 군더더기가 사라지니 "이 테스트가 무엇을 검증하는가"가 한눈에 들어온다.
평범한 assert인데 메시지는 풍부하다
파이썬의 기본 assert x == y는 실패하면 그저 AssertionError만 던진다. 어떤 값이었는지는 알려 주지 않는다. 그런데 pytest는 테스트를 실행하기 전에 코드를 다시 써서(assertion rewriting), assert가 실패하면 양쪽 값을 자세히 풀어 보여 준다.
def test_add_positive():
> assert add(2, 3) == 6
E assert 5 == 6
E + where 5 = add(2, 3)
test_math.py:5: AssertionError
add(2, 3)이 5였는데 6을 기대했다는 사실, 그 5가 add(2, 3)의 결과라는 점까지 친절하게 나온다. 별도 메서드를 외울 필요 없이 ==, in, <, is 같은 익숙한 연산자를 그대로 쓰면서도 풍부한 진단을 얻는 것이 pytest의 큰 매력이다.
예외를 검증하기: pytest.raises
특정 코드가 예외를 던져야 하는 상황은 pytest.raises를 with 블록으로 쓴다. unittest의 assertRaises와 모양이 비슷하다.
import pytest
def divide(a, b):
if b == 0:
raise ValueError("0으로 나눌 수 없습니다")
return a / b
def test_divide_by_zero():
with pytest.raises(ValueError) as exc_info:
divide(10, 0)
assert "0으로" in str(exc_info.value)
블록 안의 코드가 ValueError를 던지지 않으면 그 테스트는 실패한다. as exc_info로 잡은 예외 객체를 꺼내, 메시지 내용까지 추가로 검증할 수 있다.
실행과 선택
pytest라고만 입력하면 현재 디렉터리에서 테스트 파일을 알아서 찾아 모두 실행한다. 실행 흐름은 크게 세 단계다.
자주 쓰는 옵션 몇 가지만 알면 일상 작업이 편해진다.
pytest -v # 테스트별 결과를 자세히
pytest -q # 조용히, 요약만
pytest test_math.py # 특정 파일만
pytest -k "add" # 이름에 add가 든 테스트만
pytest -x # 첫 실패에서 즉시 중단
pytest --lf # 지난번 실패한 것만 다시
특히 -k로 이름 일부만 매칭해 원하는 테스트만 골라 돌리거나, 고치는 중이라면 --lf(last failed)로 실패한 것만 빠르게 반복하는 패턴이 디버깅 속도를 크게 높여 준다.
pytest는 적은 양의 코드로 테스트를 쓰게 해 주는 데서 그치지 않는다. fixture, parametrize, 풍부한 플러그인 생태계까지 더해지면 테스트 작성이 훨씬 즐거워진다. 다음 글에서는 그 첫 단추인 fixture로, 테스트가 필요로 하는 준비물을 깔끔하게 주입하는 법을 살펴본다.
지난 글: unittest 기초: 표준 라이브러리로 시작하는 테스트
다음 글: pytest fixture: 테스트 준비물을 우아하게 주입하기
읽어주셔서 감사합니다. 😊

