Pytest Hook 기능

Sangyeon·2021년 11월 7일
0

Pytest

목록 보기
5/12
post-thumbnail

'hook'이란, 어떠한 액션 앞 또는 뒤에 추가로 어떠한 일을 하도록 하는 것을 의미합니다.
@pytest.hookimpl 데커레이터를 통해 hook 기능을 구현한 함수를 추가로 정의할 수 있습니다.

pytest_configure

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_generate_tests

이전 게시글@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_runtest_makereport

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
                    )

pytest_sessionfinish

테스트 세션이 끝날 때 수행되는 hook 함수 입니다.

Reference

profile
I'm a constant learner.

0개의 댓글