Pytest 框架执行用例流程浅谈

这篇具有很好参考价值的文章主要介绍了Pytest 框架执行用例流程浅谈。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景:

  根据以下简单的代码示例,我们将从源码的角度分析其中的关键加载执行步骤,对pytest整体流程架构有个初步学习。

代码示例:

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函数。

```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。

```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来结束记录日志信息,并生成日志报告。

 

```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,表示开始循环执行测试用例。
- Pytest会遍历Session对象中的items列表,依次取出每个Item对象,并调用hook函数pytest_runtest_protocol,表示开始执行单个测试用例的协议。
- Pytest会调用hook函数pytest_runtest_logstart,表示开始记录单个测试用例的日志信息。
- Pytest会调用hook函数pytest_runtest_setup,表示开始执行单个测试用例的前置操作(例如setup函数或方法)。
- Pytest会调用hook函数pytest_runtest_call,表示开始执行单个测试用例的主体部分(例如测试函数或方法)。
- Pytest会调用hook函数pytest_runtest_teardown,表示开始执行单个测试用例的后置操作(例如teardown函数或方法)。
- Pytest会调用hook函数pytest_runtest_logfinish,表示结束记录单个测试用例的日志信息,并生成日志报告。
- Pytest会调用hook函数pytest_runtest_makereport,表示根据单个测试用例的执行结果,生成测试报告(包括setup、call和teardown三个阶段的报告)。
- Pytest会重复上述步骤,直到所有的Item对象都被执行完毕。
- Pytest会调用hook函数pytest_sessionfinish,表示测试会话结束,并生成最终的测试报告(包括所有Item对象的报告)。
- Pytest会调用hook函数pytest_terminal_summary,表示在终端输出最终的测试结果和统计信息。文章来源地址https://www.toymoban.com/news/detail-680233.html

到了这里,关于Pytest 框架执行用例流程浅谈的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • pytest自动化测试指定执行测试用例

    1、在控制台执行 打开cmd,进入项目目录 指定执行某个模块  pytest testcasesLogisticsPlatformCarSourcetest_CarSourceList.py 指定执行某个目录及其子目录的所有测试文件  pytest testcasesLogisticsPlatformCarSource 指定执行某个模块的某个类的某个测试用例   pytest testcasesLogisticsPlatformHome_p

    2024年02月15日
    浏览(27)
  • pytest(一):基础功能(执行用例、allure报告、数据驱动)

    pytest是python语言中一款强大的单元测试框架,用来管理和组织测试用例,可应用在单元测试、自动化测试工作中。  官网:(https://docs.pytest.org/en/7.2.x/) 文章主要以unittest为参考分析pytest pytest主要作用是编写测试用例、收集用例、执行用例、生成测试结果文件(html、xml) unittest: 模

    2024年02月12日
    浏览(34)
  • pytest框架快速进阶篇-pytest前置和pytest后置,skipif跳过用例

     一、 Pytest的前置和后置方法 1.Pytest可以集成unittest实现前置和后置 注意:setUpClass和tearDownClass需要用@classmethod装饰器装饰。 2.Pytest前置和后置 注意:setup、teardown、setup_class、teardown_class都是小写! 二、跳过用例 使用方法:   @pytest.mark.skipif(21,reason=\\\'当条件不True时跳过\\\') 使用

    2024年02月13日
    浏览(37)
  • 测试框架pytest教程(2)-用例依赖库-pytest-dependency

    对于 pytest 的用例依赖管理,可以使用  pytest-dependency  插件。该插件提供了更多的依赖管理功能,使你能够更灵活地定义和控制测试用例之间的依赖关系。 Using pytest-dependency — pytest-dependency 0.5.1 documentation 安装 pytest-dependency 插件: 依赖方法和被依赖方法都需要使用装饰器

    2024年02月11日
    浏览(25)
  • Pytest框架测试用例规则和运行方式

    目录 一、默认的测试用例规则 二、测试用例执行顺序 三、测试用例运行方式 3.1.主函数模式 3.1.1.主函数模式:4种运行方式  3.1.2.文件框架如下图  3.2.命令行模式 3.2.1.命令行模式:4种运行方式  3.2.2.第2种运行方式框架 3.3.通过读取配置文件pytest.ini运行 3.3.1.pytest.ini 文件注

    2024年02月11日
    浏览(42)
  • 测试不够快?试试这招!让pytest多进程/多线程执行测试用例,轻松提升测试效率!

    目录 :导读 前言: 多进程执行用例之pytest-xdist pytest-xdist分布式测试的原理: pytest-xdist分布式测试的流程: 多线程执行用例之pytest-parallel 常用参数配置 pytest-parallel与pytest-xdist对比说明: 结语 大家好!我是不二。 相信很多测试工程师都会遇到一个问题,那就是测试用例的执

    2024年02月06日
    浏览(48)
  • 测试框架pytest教程(5)运行失败用例-rerun failed tests

    运行这个文件,2个失败,48个通过。 要运行上次失败的测试用例,可以使用 --lf (或 --last-failed )选项来告诉pytest只运行上次运行时失败的测试。 命令行示例: 或者在pytest配置文件(比如pytest.ini)中设置: 这样,pytest会检测上次运行时失败的测试用例,并只运行这些失败

    2024年02月11日
    浏览(30)
  • 接口自动化测试框架(pytest+allure+aiohttp+ 用例自动生成)

    近期准备优先做接口测试的覆盖,为此需要开发一个测试框架,经过思考,这次依然想做点儿不一样的东西。 接口测试是比较讲究效率的,测试人员会希望很快能得到结果反馈,然而接口的数量一般都很多,而且会越来越多,所以提高执行效率很有必要 接口测试的用例其实

    2024年02月07日
    浏览(45)
  • 接口自动化测试框架开发(pytest+allure+aiohttp+ 用例自动生成)

    近期准备优先做接口测试的覆盖,为此需要开发一个测试框架,经过思考,这次依然想做点儿不一样的东西。 接口测试是比较讲究效率的,测试人员会希望很快能得到结果反馈,然而接口的数量一般都很多,而且会越来越多,所以提高执行效率很有必要 接口测试的用例其实

    2024年01月23日
    浏览(39)
  • 接口自动化测试框架开发 (pytest+allure+aiohttp+ 用例自动生成)

    目录 前言: 第一部分(整个过程都要求是异步非阻塞的) 读取 yaml 测试用例 http 请求测试接口 收集测试数据 第二部分 动态生成 pytest 认可的测试用例 后续(yml 测试文件自动生成) 前言: 开发一个接口自动化测试框架是一个很好的方式,可以提高测试效率和准确性。在这

    2024年02月16日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包