Pytest测试执行全流程解析:从配置到会话结束的6个关键阶段
本文深入解析Pytest测试执行的六个核心阶段:配置初始化、会话启动、用例收集、测试运行、会话结束及配置卸载。重点剖析pytest_collection、pytest_runtestloop等关键钩子的调用时机与参数,结合代码实例说明测试项生成、筛选及报告生成的内部机制,帮助开发者掌握Pytest底层逻辑以优化测试框架。
Pytest测试执行的六个核心阶段概览
Pytest的整个测试执行过程可以划分为以下6个主要阶段:
阶段一:配置初始化(pytest_configure)
1、pytest_configure
此阶段负责插件加载与conftest.py文件的配置初始化,并创建测试会话(session)对象。
阶段二:会话启动(pytest_sessionstart)
2、pytest_sessionstart
在会话创建完成后、用例收集开始前执行。该阶段会调用pytest_report_header向终端打印环境信息,包括插件版本、Python解释器版本及操作系统平台等。
阶段三:用例收集与生成(pytest_collection)
3、pytest_collection
此阶段负责测试用例的收集以及测试输入数据的生成,同时可能包含根据keywords参数和marker标记筛选测试用例的过程。该过程涉及多次generate item的调用,主要关注以下钩子函数的执行:
pytest_generate_tests(metafunc):用于生成具体的测试项(items);
pytest_make_parametrize_id(config, val, argname):根据@pytest.mark.parametrize装饰器生成对应的参数化标识;
pytest_collection_modifyitems(session, config, items):在所有测试项收集完毕后调用,通常用于对测试用例进行重新排序或二次过滤;
pytest_deselected(items):当测试用例被关键字或marker过滤掉时触发调用;
注意:通过::语法筛选测试用例的操作是在生成测试用例阶段完成的,而非在deselected钩子中执行。
阶段四:测试运行与报告(pytest_runtestloop)
4、pytest_runtestloop
此阶段执行经过筛选的测试用例,具体逻辑在pytest_runtest_protocol中完成,涵盖setup、call、teardown及日志打印过程。主要关注以下调用:
pytest_runtest_logstart(nodeid, location):当开始执行一个新的测试项时调用;
注:官方文档表述较为模糊,实际并非在setup/call/teardown各阶段分别调用一次,而是指在测试开始前打印一次启动日志;
pytest_runtest_logfinish(nodeid, location):当结束执行一个测试项时调用。 注:同上,指在测试结束后打印一次结束日志;
pytest_runtest_setup(item):在pytest_runtest_call执行之前调用,用于执行前置设置;
pytest_runtest_call(item):执行实际的测试逻辑过程;
pytest_runtest_teardow(item, nextitem):在pytest_runtest_call执行之后调用,用于执行后置清理;
pytest_fixture_setup(fixturedef, request):执行Fixture的setup过程(是否执行取决于Fixture是否需要创建);
pytest_fixture_post_finalizer(fixturedef, request):执行Fixture的teardown过程(如果存在);
pytest_runtest_makereport(item, call):返回与给定item和call对应的_pytest.runner.TestReport对象。这里的call object通常不直接接触,具体用法可参考_pytest/runner.py中的实现;
pytest_runtest_logreport(report):在测试的setup/call/teardown阶段report更新后分别被调用,可通过when属性区分不同阶段;
pytest_report_teststatus(report, config):返回各个测试阶段的结果,可通过when属性区分不同阶段;
阶段五:会话结束(pytest_sessionfinish)
5、pytest_sessionfinish
所有测试执行完毕后、返回退出状态码之前的阶段。此阶段会调用pytest_terminal_summary向终端打印总结信息,如pass、fail、error的数量统计等。
def pytest_terminal_summary(terminalreporter, exitstatus, config):
'''收集测试结果'''
print(terminalreporter.stats)
print("total:", terminalreporter._numcollected)
print('passed:', len([i for i in terminalreporter.stats.get('passed', []) if i.when != 'teardown']))
print('failed:', len([i for i in terminalreporter.stats.get('failed', []) if i.when != 'teardown']))
print('error:', len([i for i in terminalreporter.stats.get('error', []) if i.when != 'teardown']))
print('skipped:', len([i for i in terminalreporter.stats.get('skipped', []) if i.when != 'teardown']))
# terminalreporter._sessionstarttime 会话开始时间
duration = time.time() - terminalreporter._sessionstarttime
print('total times:', duration, 'seconds')
阶段六:配置卸载(pytest_unconfigure)
6、pytest_unconfigure
会话结束以后,整个进程退出之前的阶段,负责资源清理和配置卸载。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













