本文系《pytest源码剖析》系列内容
35. session
插件路径:_pytest.main.Session
本插件是main的子插件,建议同步参阅《pytest的内置插件盘点3:main》
实现的 hook
调用的 hook
无
定义的 fixture
无
插件功能
搜集所有conftest.py文件,将其接入 pytest 插件管理器
维护 pytest 退出状态:shouldfail 、 shouldstop
执行用例收集,保存所有的用例结果
检查失败次数达到-x参数值,则退出 pytest
代码片段
class Session(nodes.FSCollector): Interrupted = Interrupted Failed = Failed # Set on the session by runner.pytest_sessionstart. _setupstate: SetupState # Set on the session by fixtures.pytest_sessionstart. _fixturemanager: FixtureManager exitstatus: Union[int, ExitCode] def wrap_session( config: Config, doit: Callable[[Config, "Session"], Optional[Union[int, ExitCode]]]) -> Union[int, ExitCode]: """Skeleton command line program.""" session = Session.from_config(config) session.exitstatus = ExitCode.OK initstate = 0 try: try: config._do_configure() initstate = 1 config.hook.pytest_sessionstart(session=session) initstate = 2 session.exitstatus = doit(config, session) or 0 except UsageError: session.exitstatus = ExitCode.USAGE_ERROR raise except Failed: session.exitstatus = ExitCode.TESTS_FAILED
Session 作为 FSCollector 子类,拥有收集用例的能力
Session 的属性会作为退出 pytest 的关键信息
pytest 执行时以 config+session 为参数,由 session 属性存储结果
简评
session在 pytest 中有多种含义:
在用例收集过程中,session 表示比包还大的单位,即整个工作目录
Session > Package > Module > Class > Item
在 fixture 作用范围的定义中,session 的含义类似,也可以视为全局
session > package > module > class > function
在用例执行过程中,session 表示的是从用例执行开始到执行结束
pytest_configure [hook] --> 加载配置 pytest_sessionstart [hook] ----> 准备执行 pytest_collection [hook] ----> 收集用例 pytest_runtestloop [hook] ----> 执行用例 pytest_sessionfinish [hook] ----> 执行结束
...
session 插件为 pytest 提供了两个重要的功能:
作为用例收集起点,收集用例
作为 pytest 执行的终点,存储结果
这让我想到了一个词:状态机
在回顾 main 插件时,看到一个函数wrap_session,用法如下
可以看到,pytest 在根据参数做某事时,需要两个对象:
config:管理类
doit:要调用的函数,如 main、cacheshow
session 既不是参数,也不是返回值,而是在做事的时候被临时创建的
它携带着大量的信息和收集用例的能力,陪伴 config 穿插于各个 hook,直至函数调用结束,释放配置
...
session 收集用例时分成两个步骤:
从目录中收集文件:collect_one_node
从文件中收集用例:session.genitems
最终的收集结果只有 Item(对函数用例的包装对象),既不包含文件,也不包含类
...
存储在session 中的执行结果有以下几种:
OK:测试通过
TESTS_FAILED:测试失败
INTERRUPTED:测试中断
INTERNAL_ERROR:内部错误
USAGE_ERROR:用法错误
NO_TESTS_COLLECTED:未找到用例
领取专属 10元无门槛券
私享最新 技术干货