Search
🌍

pytest는 파라미터화 테스트 보일러플레이트를 제거한다.

프로젝트
🚀 prev note
♻️ prev note
🚀 next note
♻️ next note
15 more properties
소프트웨어 테스트에서 같은 로직에 다양한 입력값을 적용해 보는 테스트를 파라미터화 테스트(parametrize test)라고 한다. Python에서 라이브러리 없이 파라미터화 테스트를 작성해 본다면 다음과 같이 작성할 수 있다.
def test_eval_manually(): test_cases = [ ("3+5", 8), ("2+4", 6), ("6*9", 54), ] for test_input, expected in test_cases: assert eval(test_input) == expected
Python
복사
이 방식은 단순하지만 여러 단점이 있다.
1.
첫 번째 테스트 케이스가 실패하면 나머지 케이스는 실행되지 않는다.
2.
테스트 과정 중 실패한 경우에도 어떤 입력값에서 실패했는지 명확하게 보여주지 못한다.
Python 내장 테스트 프레임워크인 unittest를 사용하면 이 문제를 약간 개선할 수 있다. unittest의 subTest 컨텍스트 매니저를 사용하면 파라미터화 테스트를 다음과 같이 구현할 수 있다:
import unittest class TestStringMethods(unittest.TestCase): def test_upper(self): test_cases = [ ("foo", "FOO"), ("bar", "BAR"), ("baz", "BAZ") ] for input_str, expected in test_cases: with self.subTest(input=input_str): self.assertEqual(input_str.upper(), expected)
Python
복사
unittest의 subTest는 하나의 테스트 케이스가 실패해도 나머지 케이스를 계속 실행하고, 각 케이스의 입력값을 오류 보고서에 포함시킨다는 장점이 있다. 하지만 여전히 개발자는 반복문을 직접 작성해야 하며, 테스트 데이터와 로직이 혼합되어 있다. 또한 각 테스트 케이스는 독립적인 테스트로 간주되지 않고 하나의 테스트 메소드 내에서 실행되는 서브테스트로 취급된다. 결과적으로 unittest는 파라미터화 테스트의 보일러플레이트를 완전히 제거하지 못한다.
pytest는 이런 문제를 @pytest.mark.parametrize 데코레이터를 통해 해결한다. 같은 테스트를 pytest로 구현하면 다음과 같이 간결해진다:
import pytest @pytest.mark.parametrize("input_str,expected", [ ("foo", "FOO"), ("bar", "BAR"), ("baz", "BAZ") ]) def test_upper(input_str, expected): assert input_str.upper() == expected
Python
복사
pytest의 접근 방식은 여러 가지 뚜렷한 장점이 있다. 첫째, 반복문과 같은 보일러플레이트 코드가 완전히 제거되었다. 둘째, 각 테스트 케이스는 완전히 독립적인 테스트로 처리되어 개별적으로 실행되고 보고된다. 셋째, 테스트 데이터와 테스트 로직이 명확하게 분리되어 가독성이 향상된다.
parse me : 언젠가 이 글에 쓰이면 좋을 것 같은 재료을 보관해 두는 영역입니다.
1.
None
from : 과거의 어떤 원자적 생각이 이 생각을 만들었는지 연결하고 설명합니다.
1.
supplementary : 어떤 새로운 생각이 이 문서에 작성된 생각을 뒷받침하는지 연결합니다.
1.
None
opposite : 어떤 새로운 생각이 이 문서에 작성된 생각과 대조되는지 연결합니다.
1.
None
to : 이 문서에 작성된 생각이 어떤 생각으로 발전되거나 이어지는지를 작성하는 영역입니다.
1.
None
ref : 생각에 참고한 자료입니다.
1.
None