테스트 클래스 및 메서드
Pytest에서는 테스트 함수 작성 외에도 클래스를 사용할 수 있습니다. 앞서 언급했듯이 상속이 필요하지 않으며 테스트 클래스는 몇 가지 간단한 규칙을 따릅니다. 클래스를 사용하면 유연성과 재사용성이 향상됩니다. 다음에 보듯이 Pytest는 방해가 되지 않도록 하며 특정 방식으로 테스트를 작성하도록 강요하지 않습니다.
함수와 마찬가지로 assert
문을 사용하여 어설션을 작성할 수 있습니다.
테스트 클래스 빌드
실제 시나리오를 사용하여 테스트 클래스가 어떻게 도움이 되는지 알아보겠습니다. 다음 함수는 지정된 파일의 내용에 “yes”가 포함되어 있는지 확인합니다. 포함되어 있으면 True
를 반환합니다. 파일이 없거나 파일 내용에 “no”가 포함되어 있으면 False
를 반환합니다. 이 시나리오는 파일 시스템을 사용하여 완료를 나타내는 비동기 작업에서 일반적입니다.
함수의 형태는 다음과 같습니다.
import os
def is_done(path):
if not os.path.exists(path):
return False
with open(path) as _f:
contents = _f.read()
if "yes" in contents.lower():
return True
elif "no" in contents.lower():
return False
다음은 test_files.py라는 파일에 포함된 두 개의 테스트(각 조건에 대해 하나씩)가 있는 클래스입니다.
class TestIsDone:
def test_yes(self):
with open("/tmp/test_file", "w") as _f:
_f.write("yes")
assert is_done("/tmp/test_file") is True
def test_no(self):
with open("/tmp/test_file", "w") as _f:
_f.write("no")
assert is_done("/tmp/test_file") is False
주의
예제에 사용하기 더 쉽기 때문에 테스트 메서드는 임시 테스트 파일에 대해 /tmp 경로를 사용합니다. 그러나 임시 파일을 사용해야 하는 경우 파일을 안전하게 만들고 제거할 수 있는 tempfile
등의 라이브러리를 사용하는 것이 좋습니다. 모든 시스템에 /tmp 디렉터리가 있는 것은 아니며 해당 위치는 운영 체제에 따라 일시적이지 않을 수 있습니다.
세부 정보 표시를 늘리기 위해 -v
플래그를 사용하여 테스트를 실행하면 테스트 통과가 표시됩니다.
pytest -v test_files.py
============================= test session starts ==============================
Python 3.9.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
cachedir: .pytest_cache
rootdir: /private/
collected 2 items
test_files.py::TestIsDone::test_yes PASSED [ 50%]
test_files.py::TestIsDone::test_no PASSED [100%]
============================== 2 passed in 0.00s ===============================
테스트가 통과되고 있지만 반복적인 것처럼 보이고 테스트가 완료된 후에도 파일을 남깁니다. 이를 개선할 수 있는 방법을 알아보기 전에 다음 섹션에서 도우미 메서드를 살펴보겠습니다.
도우미 메서드
테스트 클래스에는 테스트 실행을 설정 및 해체하는 데 사용할 수 있는 몇 가지 방법이 있습니다. Pytest는 정의된 경우 자동으로 실행합니다. 이러한 메서드를 사용하려면 특정 순서와 동작이 있음을 알아야 합니다.
setup
: 클래스의 각 테스트 전에 한 번 실행teardown
: 클래스의 각 테스트 후에 한 번 실행setup_class
: 클래스의 모든 테스트 전에 한 번 실행teardown_class
: 클래스의 모든 테스트 후에 한 번 실행
테스트에서 유사한(또는 동일한) 리소스가 작동해야 하는 경우 설치 메서드를 쓰는 데 유용합니다. 이상적으로는 테스트가 완료된 후 리소스가 남아 있으면 안 되므로 이러한 상황에서는 해체 메서드가 테스트 정리에 도움이 될 수 있습니다.
정리
각 테스트 후 파일을 정리하는 업데이트된 테스트 클래스를 살펴보겠습니다.
class TestIsDone:
def teardown(self):
if os.path.exists("/tmp/test_file"):
os.remove("/tmp/test_file")
def test_yes(self):
with open("/tmp/test_file", "w") as _f:
_f.write("yes")
assert is_done("/tmp/test_file") is True
def test_no(self):
with open("/tmp/test_file", "w") as _f:
_f.write("no")
assert is_done("/tmp/test_file") is False
teardown()
메서드를 사용했으므로 이 테스트 클래스는 더 이상 /tmp/test_file을 남기지 않습니다.
설정
이 클래스에서 수행할 수 있는 또 다른 개선 사항은 파일을 가리키는 변수를 추가하는 것입니다. 이제 파일이 6개 위치에서 선언되었으므로 경로를 변경하면 해당 모든 위치에서 변경됩니다. 이 예제에서는 경로 변수를 선언하는 setup()
메서드를 추가한 클래스의 형태를 보여 줍니다.
class TestIsDone:
def setup(self):
self.tmp_file = "/tmp/test_file"
def teardown(self):
if os.path.exists(self.tmp_file):
os.remove(self.tmp_file)
def test_yes(self):
with open(self.tmp_file, "w") as _f:
_f.write("yes")
assert is_done(self.tmp_file) is True
def test_no(self):
with open(self.tmp_file, "w") as _f:
_f.write("no")
assert is_done(self.tmp_file) is False
사용자 지정 도우미 메서드
클래스에서 사용자 지정 도우미 메서드를 만들 수 있습니다. 이러한 메서드는 이름 test
를 접두사로 지정해서는 안 되며 설치 또는 정리 메서드로 이름을 지정할 수 없습니다. TestIsDone
클래스에서는 사용자 지정 도우미에서 임시 파일 만들기를 자동화할 수 있습니다. 해당 사용자 지정 도우미 메서드는 다음 예제와 같습니다.
def write_tmp_file(self, content):
with open(self.tmp_file, "w") as _f:
_f.write(content)
Pytest는 write_tmp_file()
메서드를 자동으로 실행하지 않으며, 다른 메서드에서 이를 직접 호출하여 파일에 쓰는 것과 같은 반복적인 작업에 소요되는 시간을 줄일 수 있습니다.
사용자 지정 도우미를 사용하도록 테스트 메서드를 업데이트한 후 이 예제의 전체 클래스는 다음과 같이 표시됩니다.
class TestIsDone:
def setup(self):
self.tmp_file = "/tmp/test_file"
def teardown(self):
if os.path.exists(self.tmp_file):
os.remove(self.tmp_file)
def write_tmp_file(self, content):
with open(self.tmp_file, "w") as _f:
_f.write(content)
def test_yes(self):
self.write_tmp_file("yes")
assert is_done(self.tmp_file) is True
def test_no(self):
self.write_tmp_file("no")
assert is_done(self.tmp_file) is False
함수 대신 클래스를 사용해야 하는 경우
함수 대신 클래스를 사용해야 하는 시기에 대한 엄격한 규칙은 없습니다. 항상 작업 중인 현재 프로젝트 및 팀의 규칙을 따르는 것이 좋습니다. 다음은 클래스 사용 시기를 결정하는 데 도움이 되는 몇 가지 일반적인 질문입니다.
- 테스트에 유사한 설정 또는 정리 도우미 코드가 필요한가요?
- 테스트를 함께 그룹화하는 것이 논리적으로 괜찮나요?
- 테스트 도구 모음에 일부 테스트가 있나요?
- 일반적인 도우미 함수 집합을 사용할 경우 테스트에 도움이 되었나요?