Pytest 框架执行用例流程浅谈_pytest框架运行用例

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

import pytest def test_add(): assert 1 + 1 =``= 2 def test_sub(): assert 2 - 1 =``= 1

通过 pytest test_example.py 运行此代码示例后,会触发pytest的入口函数main(),这个函数定义在src/pytest/__main__.py中,它的作用是创建一个PytestConfig对象,并调用其

do_configure()和do_main()方法。PytestConfig对象是pytest的核心配置类,它负责解析命令行参数、读取配置文件、注册插件、创建Session对象等。PytestConfig对象定义在

src/_pytest/config/__init__.py中,它继承了pluggy.HookimplMarker类,也就是说它可以作为一个插件管理器,调用各种hook函数。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36````python # src/pytest/main.py def main(): # 创建PytestConfig对象 config=` `PytestConfig()` `# 调用config.do_configure()方法` `config.do_configure()` `# 调用config.do_main()方法` `config.do_main()` `````````python` `# src/_pytest/config/__init__.py` `class` `PytestConfig(pluggy.HookimplMarker):` `def` `__init__(self):` `# 解析命令行参数` `self.parse_args()` `# 读取配置文件` `self.read_config_files()` `# 注册插件` `self.register_plugins()` `# 创建Session对象` `self.session=` `Session(self)`   `def` `do_configure(self):` `# 调用hook函数pytest_configure` `self.hook.pytest_configure(config=self)`   `def` `do_main(self):` `# 调用hook函数pytest_sessionstart` `self.hook.pytest_sessionstart(session=self.session)` `# 调用Session对象的main()方法` `self``.session.main()` `````

Session对象是pytest的核心上下文类,它负责管理整个测试过程的信息,包括收集测试用例、执行测试用例、生成测试报告等。Session对象定义在src/_pytest/main.py中,它继承了

Collector类,也就是说它可以作为一个测试用例收集器。Session对象的main()方法是执行测试用例的主要入口,它会调用perform_collect()方法来收集测试用例,并返回一个列表items;然后

调用runtestloop()方法来循环执行items中的每个Item对象;最后调用hook函数pytest_sessionfinish来结束测试会话,并返回一个退出码exitstatus。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41````python # src/_pytest/main.py class Session(Collector): def init(self, config): # 初始化一些属性和状态信息 def main(self): # 调用perform_collect()方法收集测试用例,并返回items列表 items=` `self.perform_collect()` `# 调用runtestloop()方法循环执行items中的每个Item对象,并返回退出码exitstatus` `exitstatus=` `self.runtestloop(items)` `# 调用hook函数pytest_sessionfinish来结束测试会话,并返回退出码exitstatus` `self.hook.pytest_sessionfinish(session=self, exitstatus=exitstatus)` `return` `exitstatus`   `def` `perform_collect(self):` `# 调用hook函数pytest_collectstart表示开始收集测试用例` `self.hook.pytest_collectstart(collector=self)` `# 调用自身的collect()方法来递归遍历指定的测试文件或目录,并返回一个列表items` `items=` `self.collect()` `# 调用hook函数pytest_collectreport表示收集测试用例结束,并生成收集报告` `self.hook.pytest_collectreport(report=CollectReport(self,“passed”, items))` `# 调用hook函数pytest_collection_modifyitems允许对收集到的Item对象进行修改` `self.hook.pytest_collection_modifyitems(session=self, config=self.config, items=items)` `# 调用hook函数pytest_deselected表示从收集到的Item对象中筛选出需要执行的Item对象` `self.hook.pytest_deselected(items=self.deselected)` `# 调用hook函数pytest_collection_finish表示收集和筛选测试用例完成,并返回最终要执行的Item对象列表` `self.hook.pytest_collection_finish(session=self)` `return` `items`   `def` `runtestloop(self, items):` `# 调用hook函数pytest_runtestloop表示开始循环执行测试用例` `self.hook.pytest_runtestloop(session=self)` `# 遍历items列表,依次取出每个Item对象` `for` `item``in` `items:` `# 调用Item对象的runtestprotocol()方法来执行单个测试用例的协议` `item.runtestprotocol()` `# 返回退出码0表示成功` `return` `0` `````

Item对象是pytest的核心测试类,它负责封装和执行单个测试用例的信息,包括名称、位置、参数化信息、标记信息等。Item对象定义在src/_pytest/python.py中,它继承了Node类,也

就是说它可以作为一个测试节点。Item对象的runtestprotocol()方法是执行单个测试用例的主要入口,它会调用hook函数pytest_runtest_logstart来开始记录日志信息;然后调用runtest()方法

来执行测试用例的前置、主体和后置部分;最后调用hook函数pytest_runtest_logfinish来结束记录日志信息,并生成日志报告。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44````python # src/_pytest/python.py class Item(Node): def init(self, name, parent, config, session): # 初始化一些属性和状态信息 def runtestprotocol(self): # 调用hook函数pytest_runtest_logstart表示开始记录日志信息 self.ihook.pytest_runtest_logstart(nodeid=self.nodeid, location=self.location)` `# 调用runtest()方法来执行测试用例的前置、主体和后置部分,并返回一个列表reports` `reports=` `self.runtest()` `# 调用hook函数pytest_runtest_logfinish表示结束记录日志信息,并生成日志报告` `self.ihook.pytest_runtest_logfinish(nodeid=self.nodeid, location=self.location)` `return` `reports`   `def` `runtest(self):` `# 创建一个空列表reports` `reports=` `[]` `# 调用_setup()方法来执行测试用例的前置操作,并将返回的报告添加到reports列表中` `reports.append(self._setup())` `# 如果前置操作没有失败或跳过,则调用_call()方法来执行测试用例的主体部分,并将返回的报告添加到reports列表中` `if` `reports[-1].passed:` `reports.append(self._call())` `# 调用_teardown()方法来执行测试用例的后置操作,并将返回的报告添加到reports列表中` `reports.append(self._teardown())` `# 返回reports列表` `return` `reports`   `def` `_setup(self):` `# 调用hook函数pytest_runtest_setup表示开始执行前置操作,并返回一个报告setup_report` `setup_report=` `self.ihook.pytest_runtest_setup(item=self)` `return` `setup_report`   `def` `_call(self):` `# 调用hook函数pytest_runtest_call表示开始执行主体部分,并返回一个报告call_report` `call_report=` `self.ihook.pytest_runtest_call(item=self)` `return` `call_report`   `def` `_teardown(self):` `# 调用hook函数pytest_runtest_teardown表示开始执行后置操作,并返回一个报告teardown_report` `teardown_report=` `self.ihook.pytest_runtest_teardown(item=self``)` `return` `teardown_report` `````
总结:

Pytest的加载流程大致如下:

  • Pytest首先会解析命令行参数,确定要执行的测试文件、测试目录、测试类、测试函数等,以及一些配置选项。
  • Pytest会根据配置文件(pytest.ini、setup.cfg、tox.ini等)和命令行参数,创建一个Config对象,用于存储配置信息。
  • Pytest会创建一个Session对象,用于管理整个测试过程的上下文信息,包括收集测试用例、执行测试用例、生成测试报告等。
  • Pytest会调用hook函数pytest_sessionstart,表示测试会话开始。
  • Pytest会调用hook函数pytest_collectstart,表示开始收集测试用例。
  • Pytest会根据Config对象中的信息,递归遍历指定的测试文件或目录,寻找符合pytest约定的测试用例(以test_开头的函数或方法,以Test开头的类等)。
  • Pytest会将找到的测试用例封装成Item对象,并添加到Session对象的items列表中。Item对象包含了测试用例的名称、位置、参数化信息、标记信息等。
  • Pytest会调用hook函数pytest_collectreport,表示收集测试用例结束,并生成收集报告。
  • Pytest会调用hook函数pytest_collection_modifyitems,允许对收集到的Item对象进行修改,例如重新排序、添加或删除标记等。
  • Pytest会调用hook函数pytest_deselected,表示从收集到的Item对象中筛选出需要执行的Item对象,并将不需要执行的Item对象放入Session对象的deselected列表中。
  • Pytest会调用hook函数pytest_collection_finish,表示收集和筛选测试用例完成,并返回最终要执行的Item对象列表。
  • Pytest会根据是否使用多进程或多线程模式,创建相应的WorkerController对象,用于管理多个Worker对象。Worker对象负责执行具体的测试用例,并将结果返回给WorkerController对象。
  • Pytest会调用hook函数pytest_runtestloop,表示开始循环执行测试用例。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

需要这份系统化的资料的朋友,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值