'hook'이란, 어떠한 액션 앞 또는 뒤에 추가로 어떠한 일을 하도록 하는 것을 의미합니다.
@pytest.hookimpl
데커레이터를 통해 hook 기능을 구현한 함수를 추가로 정의할 수 있습니다.
pytest 설정을 추가하는 hook 함수입니다.
아래는 테스트 결과를 출력하는 pytest html 파일의 파일명 및 경로를 설정하는 예시입니다.
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config):
if config.option.htmlpath:
config.option.htmlpath = time_func.put_datetime_in_filename(file_type='html', file=config.option.htmlpath, date_format="%y%m%d")
이전 게시글의 @pytest.mark.parametrize()
대신 metafunc fixture로 parametrize 를 사용하면, 여러 테스트 파일에서 사용되는 parametrized 된 변수를 선언할 수 있습니다.
PC/모바일환경 반응형 페이지에 대해서, PC/모바일환경에서 동일한 테스트함수를 수행하도록 하기 위한 예시입니다.
(테스트함수에서 이 device_type 값으로 pc/mobile을 받아와 PC환경/모바일환경에 맞게 화면 크기와 UserAgent를 조정하여 테스트를 수행할 수 있습니다.)
conftest.py
def pytest_generate_tests(metafunc):
if "device_type" in metafunc.fixturenames:
metafunc.parametrize("device_type", ['pc', 'mobile'], scope="session")
pytest 플러그인인 pytest-html, pytest-testrail 모두 테스트 함수 하나하나가 수행된 이후 테스트 결과를 HTML파일 또는 Testrail에 뿌려줘야하기 때문에 pytest_runtest_makereport라는 pytest에 내장된 hook 함수를 이용합니다.
pytest-html 플러그인의 pytest_runtest_makereport함수
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
if report.when == "call":
fixture_extras = getattr(item.config, "extras", [])
plugin_extras = getattr(report, "extra", [])
report.extra = fixture_extras + plugin_extras
pytest-testrail 플러그인의 pytest_runtest_makereport함수
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(self, item, call):
""" Collect result and associated testcases (TestRail) of an execution """
outcome = yield
rep = outcome.get_result()
defectids = None
if 'callspec' in dir(item):
test_parametrize = item.callspec.params
else:
test_parametrize = None
comment = rep.longrepr
if item.get_closest_marker(TESTRAIL_DEFECTS_PREFIX):
defectids = item.get_closest_marker(TESTRAIL_DEFECTS_PREFIX).kwargs.get('defect_ids')
if item.get_closest_marker(TESTRAIL_PREFIX):
testcaseids = item.get_closest_marker(TESTRAIL_PREFIX).kwargs.get('ids')
if rep.when == 'call' and testcaseids:
if defectids:
self.add_result(
clean_test_ids(testcaseids),
get_test_outcome(outcome.get_result().outcome),
comment=comment,
duration=rep.duration,
defects=str(clean_test_defects(defectids)).replace('[', '').replace(']', '').replace("'", ''),
test_parametrize=test_parametrize
)
else:
self.add_result(
clean_test_ids(testcaseids),
get_test_outcome(outcome.get_result().outcome),
comment=comment,
duration=rep.duration,
test_parametrize=test_parametrize
)
테스트 세션이 끝날 때 수행되는 hook 함수 입니다.