테스트 카드는 문법보다 실패를 자동으로 잡아내는가를 먼저 보는 게 맞습니다.
test_ 함수, assert, fixture, parametrize, monkeypatch, tmp_path, fixture의 yield를 각각 어떤 질문에 쓰는지 나눠 읽는 편이 좋습니다.
빠른 흐름
# test_math.py
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3문법
기본형은 test_ 함수와 assert부터 보면 됩니다.
def test_add():
assert add(1, 2) == 3기본 테스트
가장 기본은 test_ 함수 + assert
unittest 스타일보다 pytest가 빨리 읽히는 이유는, 테스트 함수와 일반 assert만으로도 시작할 수 있기 때문입니다.
def test_upper():
assert "cat".upper() == "CAT"복잡한 상속 구조나 보일러플레이트 없이도 테스트 의도가 바로 보인다는 점이 큰 장점입니다.
공통 준비
준비 코드가 반복되면 fixture
테스트마다 같은 데이터나 객체를 준비해야 하면 fixture로 분리합니다. 이렇게 하면 테스트 본문은 검증에 집중할 수 있습니다.
import pytest
@pytest.fixture
def user():
return {"name": "Mina", "age": 26}
def test_user_name(user):
assert user["name"] == "Mina"즉 fixture는 "반복 준비 코드 정리"라는 질문에 대한 답입니다.
같은 규칙을 여러 입력에 검사하면 parametrize
입력/출력 조합이 여러 개라면 테스트 함수를 복붙하기보다 @pytest.mark.parametrize가 더 낫습니다.
import pytest
@pytest.mark.parametrize("value, expected", [(1, 2), (2, 3), (3, 4)])
def test_increment(value, expected):
assert value + 1 == expected즉 "규칙 하나를 여러 사례에 적용한다"는 구조가 분명해집니다.
테스트 격리
파일과 환경 의존성은 pytest fixture로 제어한다
실제 파일 시스템이나 환경 변수, 외부 함수를 테스트 중에 그대로 건드리면 불안정해지기 쉽습니다. pytest는 이런 상황을 위한 내장 fixture를 제공합니다.
def test_timeout_from_env(monkeypatch):
monkeypatch.setenv("TIMEOUT", "60")
def test_write_file(tmp_path):
output = tmp_path / "result.txt"
output.write_text("done")monkeypatch: 환경 변수, 함수, 속성 교체tmp_path: 테스트 전용 임시 디렉터리
teardown이 필요하면 fixture에서 yield
연결이나 자원처럼 끝나고 정리가 필요하면 fixture 안에서 yield 앞을 setup, 뒤를 teardown으로 씁니다.
즉 pytest도 결국 준비/검증/정리 흐름을 더 읽기 쉽게 만드는 도구라고 보면 됩니다.
import pytest
@pytest.fixture
def opened_file(tmp_path):
path = tmp_path / "sample.txt"
path.write_text("hello", encoding="utf-8")
file = path.open("r", encoding="utf-8")
yield file
file.close()
def test_opened_file(opened_file):
assert opened_file.read() == "hello"파일이나 DB 연결처럼 teardown이 필요한 자원은 fixture 안에서 yield 패턴으로 분리해 두면 테스트 본문이 훨씬 읽기 쉬워집니다.
주의할 점
테스트가 print 출력만 하고 검증을 안 하면 실패를 잡지 못합니다. 테스트의 핵심은 관찰이 아니라 단정(assert)입니다.
# ❌ 결과를 출력만 함
def test_add():
print(1 + 2)
# ✅ 기대값을 단정
def test_add():
assert 1 + 2 == 3
# ❌ 실제 작업 디렉터리에 파일을 써서 테스트가 서로 간섭
def test_write_file():
with open("result.txt", "w", encoding="utf-8") as file:
file.write("done")
# ✅ pytest가 준 임시 경로를 사용
def test_write_file(tmp_path):
output = tmp_path / "result.txt"
output.write_text("done", encoding="utf-8")
assert output.read_text(encoding="utf-8") == "done"참고 링크
2 sources