pytest 的 request fixture:实现个性化测试需求

在之前深入理解pytest-repeat插件的工作原理一文中,我们看到pytest_repeat源码中有这样一段

  1. @pytest.fixture

  2. def __pytest_repeat_step_number(request):

  3.    marker = request.node.get_closest_marker("repeat")

  4.    count = marker and marker.args[0] or request.config.option.count

  5. ......

看到参数为request,我们知道fixture装饰的函数入参,只能是其他fixture,所以这里request一定也是fixture。那它到底怎么用呢?这篇文章将详细介绍,并通过实战项目加深理解。

request fixture

The request fixture is a special fixture providing information of the requesting test function.这是pytest官方文档的介绍,意思就是请求fixture是一个特殊的fixture,提供请求测试函数的信息。

源码直达,感兴趣的朋友可以查看源码FixtureRequest

文档直达

request.node

当前测试用例的节点对象,表示当前执行的测试用例。可以使用该对象获取测试用例的名称、文件路径、测试类等信息。

  1. import pytest

  2. @pytest.fixture

  3. def my_fixture(request):

  4.    node = request.node

  5.    print(f"Current test case: {node.name}")

  6.    print(f"Test file path: {node.fspath}")

  7.    print(f"Test class: {node.getparent}")

  8. def test_demo(my_fixture):

  9.    pass

输出结果为:

  1. Current test case: test_demo

  2. Test file path: /Users/pxl/test_dir/test_demo.py

  3. Test class: <bound method Node.getparent of <Function test_demo>>

fixture 使用了 request 参数,并通过 request.node 获取了当前测试用例的相关信息。具体来说,我们打印了当前测试用例的名称、文件路径和测试类名称。

request.config

前运行的配置对象,表示当前 Pytest 的配置信息。可以使用该对象获取命令行参数、配置文件设置等信息。

pytest.ini

  1. [pytest]

  2. markers =

  3.    p0: 冒烟

  4.    p1: 功能

 
  1. @pytest.fixture

  2. def my_fixture(request):

  3.    config = request.config

  4.    print(f"Command line arguments: {config.option}")

  5.    print(f"INI file options: {config.getini('markers')}")

该 fixture 使用了 request 参数,并通过 request.config 获取了当前 Pytest 的配置信息。具体来说,我们打印了命令行参数和配置文件中的一个选项。

request.param

当前 fixture 的参数,表示当前 fixture 的实例所需的参数值

  1. @pytest.fixture(params=[1, 2, 3])

  2. def my_fixture(request):

  3.    param_value = request.param

  4.    print(f"Current parameter value: {param_value}")

  5.    return param_value

该 fixture 使用了 request 参数,并通过 request.param 获取了当前实例所需的参数值。

request.fixturename

返回当前 fixture 的名称。

  1. @pytest.fixture

  2. def my_fixture(request):

  3.    fixture_name = request.fixturename

  4.    print(f"Current fixture name: {fixture_name}")

我们使用 request.fixturename 获取了当前 fixture 的名称,并将其打印出来.

request.fixturenames

返回当前测试函数所使用的所有 fixture 的名称列表

  1. @pytest.fixture

  2. def my_fixture(request):

  3.    pass

  4. def test_example(my_fixture, request):

  5.    fixture_names = request.fixturenames

  6.    print(f"Current fixture name: {fixture_names}")

我们使用 request.fixturename s获取了test_example使用的所有 fixture 的名称

request.cls

当前测试类的类对象。

  1. class TestClass:

  2.    @pytest.fixture

  3.    def my_fixture(self, request):

  4.        class_obj = request.cls

  5.        print(f"Current class object: {class_obj}")

使用 request.cls 获取了当前测试类的类对象,并将其打印出来。

request.addfinalizer(finalizer_func)

在 fixture 完成后执行指定的函数。

  1. @pytest.fixture

  2. def my_fixture(request):

  3.    def finalizer_func():

  4.        print("Finalizer function called")

  5.    request.addfinalizer(finalizer_func)

  6.    print("Fixture setup")

我们使用 request.addfinalizer() 方法注册了一个 finalizer 函数 finalizer_func。该函数将在 fixture 执行完毕后被调用,并打印一条消息。

request.applymarker(marker)

为当前测试用例或 fixture 应用指定的 marker。

  1. @pytest.fixture

  2. def my_fixture(request):

  3.    request.applymarker(pytest.mark.slow)

我们使用 request.applymarker() 方法为当前 fixture 添加了一个 pytest.mark.slow 的标记。这个标记可以被 Pytest 识别并用于特定的测试运行策略。

request.config.getoption(name)

获取命令行选项的值。

  1. @pytest.fixture

  2. def my_fixture(request):

  3.    my_option = request.config.getoption("--my_option")

  4.    print(f"Value of --my_option: {my_option}")

我们使用 request.config.getoption() 方法获取了命令行选项 --my_option 的值,并将其打印出来。

request.module

当前测试用例所属的模块对象

  1. def my_fixture(request):

  2.    module_obj = request.module

  3.    print(f"Current module object: {module_obj}")

我们使用 request.module 获取了当前测试用例所属的模块对象,并将其打印出来

request.param_index

参数化 fixture 的参数索引

  1. @pytest.fixture(params=[1, 2, 3])

  2. def my_fixture(request):

  3.    param_value = request.param

  4.    param_index = request.param_index

  5.    print(f"Current parameter value: {param_value}")

  6.    print(f"Current parameter index: {param_index}")

  7.    return param_value

我们对带有参数的 my_fixture fixture 进行了参数化。使用 request.param_index 可以获取当前参数在参数列表中的索引,并将其打印出来。

request.keywords

当前测试用例的关键字集合

  1. @pytest.fixture

  2. def my_fixture(request):

  3.    keywords = request.keywords

  4.    print(f"Current test keywords: {keywords}")

我们使用 request.keywords 获取了当前测试用例的关键字集合,并将其打印出来

request.getfixturevalue(fixturename)

获取已注册的 fixture 对象的值

  1. import pytest

  2. @pytest.fixture

  3. def my_fixture():

  4.    return "Hello, Fixture!"

  5. def test_example(request):

  6.    fixture_value = request.getfixturevalue("my_fixture")

  7.    assert fixture_value == "Hello, Fixture!"

实战

到这里request fixture的常用属性和方法应该了解差不多了。更多属性和方法,可以参考官方文档。

接下来我们就利用request属性实现数据库环境的切换。看实现代码

conftest.py

  1. def pytest_addoption(parser):

  2.    parser.addoption("--test", action="store_true", help="Run tests in test mode")

  3. @pytest.fixture(scope="session")

  4. def config_parser(request):

  5.    class Clazz(object):

  6.        config = ConfigParser()

  7.        config.read(config_path)

  8.        section = 'test' if request.config.getoption("--test") else 'prod'

  9.        log.info(f"section: {config.sections()}")

  10.        db_host = config.get(section, 'host')

  11.        db_port = config.get(section, 'port')

  12.        db_username = config.get(section, 'username')

  13.        db_password = config.get(section, 'password')

  14.        db_database = config.get(section, 'database')

  15.        api_url = config.get(section, 'url')

  16.    return Clazz

  17. @pytest.fixture(scope="session")

  18. def db_connection(config_parser):

  19.    db_conn = MySQLDB(

  20.        config_parser.db_host,

  21.        int(config_parser.db_port),

  22.        config_parser.db_username,

  23.        config_parser.db_password,

  24.        config_parser.db_database

  25.   )

  26.    yield db_conn

  27.    db_conn.close()

  1. config_parser 是一个会话级别的 fixture,它返回一个配置解析器对象。这个配置解析器对象可以读取配置文件,并根据传入的命令行参数 --test 来确定读取哪个配置文件的特定部分(测试环境或生产环境)。具体流程如下:

    a. 首先,在 pytest_addoption 函数中,通过调用 parser.addoption() 方法来添加一个命令行选项 --test,它的作用是告诉 pytest 在测试模式下运行。

    b. 在 config_parser fixture 中,我们首先创建了一个名为 Clazz 的类,它包含了从配置文件中读取的各个配置项的值。

    c. 根据传入的 --test 参数值,决定使用测试环境还是生产环境的配置。如果 --test 参数被指定,则使用配置文件中的 test 部分,否则使用 prod 部分。

    d. 通过 config.get() 方法获取具体的配置项的值,例如 db_hostdb_portdb_username 等。

    e. 最后,将 Clazz 类作为返回值,供其他测试代码使用。

  2. db_connection 是一个会话级别的 fixture,它返回一个数据库连接对象。这个对象在测试期间可以被使用,并在测试完成后进行关闭。具体流程如下:

    a. 在 db_connection fixture 中,我们创建了一个 MySQLDB 对象,将从 config_parser fixture 中获取的数据库连接参数传入。

    b. 使用 yield 语句将数据库连接对象返回给测试代码。yield 使得这个 fixture 可以在测试期间提供数据库连接,而在测试完成后继续执行下面的代码。

    c. 在 yield 之后的代码将在测试完成后执行,这里使用 db_conn.close() 来关闭数据库连接。

可以看到我们正是使用request.config.getoption这个方法来 获取命令行选项的值。

这段代码展示了如何使用 pytest 的 fixture 来管理测试环境和资源的初始化和清理。通过使用会话级别的 fixture,可以确保在整个测试会话期间只进行一次配置解析和数据库连接操作,避免重复的开销和不必要的操作。

后续

到这里我们有攻克了一个知识点request,不仅介绍了它的基本用法,也介绍了笔者在工作中真实使用场景。多加尝试,才能印象深刻。

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群: 320231853,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/651253.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

类与对象(四)

目录 1.构造函数 1.1初始化列表 1.2 隐式类型转换 2.静态成员 2.1 静态成员变量 2.2静态成员函数 3.友元 3.1 友元函数 3.2 友元类 4.内部类 5.匿名对象 6.拷贝对象时的一些编译器优化 1.构造函数 1.1初始化列表 我们在将构造函数的时候讲过构造函数是对一个对象整体的…

大模型_ ChatGLM-Med推理及微调部署

文章目录 ChatGLM-Med是什么数据集构建推理部署python环境切换到安装好的conda环境下载github数据切换目录在infer.py修改模型路径启动推理解决infer.py报错修改后再次启动推理完成 微调部署安装evaluate包修改模型路径启动微调 ChatGLM-Med是什么 经过中文医学指令精调/指令微…

【算法一则】【动态规划】求二维数组可组成的最大正方形

题目 在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内&#xff0c;找到只包含 ‘1’ 的最大正方形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0","0"],["1","0&…

[华为OD] 给航天器一侧加装长方形或正方形的太阳能板 100

给航天器一侧加装长方形或正方形的太阳能板&#xff08;图中的红色斜线区域&#xff09;&#xff0c;需要先安装两个支 柱&#xff08;图中的黑色竖条&#xff09;&#xff0c;再在支柱的中间部分固定太阳能板。但航天器不同位置的支柱长度 不同&#xff0c;太阳能板的安装面…

Games101-动画与模拟(基本概念、质点弹簧系统、运动学)

动画&#xff1a;把物体变成活的&#xff0c;让它动起来 更关注的是美学。早期的动画是画出来的&#xff0c;并不关心对不对&#xff0c;符不符合物理&#xff0c;只要看起来对 图形学里对动画理解为对于建模或几何的拓展。动画无非就是在不同的时间或不同的帧有不同的几何形状…

如何组织一场品牌都爱的快闪活动?

现在懂营销的品牌都爱开“快闪店”&#xff0c;据不完全统计&#xff0c;仅上半年就有超过100个品牌开设了快闪店。 不仅是服装、餐饮、美妆等适合玩快闪的品牌&#xff0c;还有像泡泡玛特、元气森林、钟薛高等新消费品牌也是重要的参与者。 快闪店其实是一种舶来品&#xff…

PS学习笔记-抠图相关

选好颜色后&#xff0c;altdelete更换画布颜色、填充前景色 按住shift键自由缩放图片&#xff0c;调好后双击鼠标即可完成&#xff0c;或者点击工具栏的 对勾 在某图层下 CTRLT 变换图片&#xff0c;调好后双击鼠标即可完成&#xff0c;或者点击工具栏的 对勾 CTRLJ复制图…

Shell脚本学习记录

0.理解Linux文件权限 0.1 Linux安全性 用户的权限是通过创建用户时分配的用户ID(UID)来追踪的&#xff0c;UID是个数值&#xff0c;每个用户都有一个唯一的UID 0.1.1 /etc/passwd文件 Linux系统使用一个专门的文件/etc/passwd来匹配登录名与对应的UID值&#xff0c;该文件包…

Jira搭建过程

看到很多小伙伴对jira有兴趣,我们今天就来分享一下jira的搭建吧 首先要明白jira是什么? 看来搭建jira也是我们测试人员需要具备的技能之一了.下面是详细的大家步骤: 1.系统环境准备 Centos 7.5 Mysql 5.6 Java1.8 2.软件安装包 atlassian-jira-software-7.13.0-x64.bin …

大模型应用开发之准备篇(OpenAI的plugins、GPTs与RAG、Agent)

今天这个章节是为了接下来我们使用大模型做应用开发做准备。 大家陆续在很多文章中可能已经看到过了很多概念&#xff0c;比如plugins、GPTs、Agent&#xff0c;这里面自ChatGPT3.5爆火以来&#xff0c;有众多的AI创业公司从不同的切入点在做&#xff0c;OpenAI公司也在不断推…

抖音小程序-小玩法(学习笔记)

现在非常流行小程序&#xff0c;当然自媒体直播也是现在最流行的&#xff0c;当我们看直播时可能看到各种的互动玩法&#xff0c;接下来我以一个开发者的角度&#xff0c;来玩玩怎么写一些小玩法 很多时候在没有玩过的东西来说最好的办法就是看用户手册,程序也一样&#xff0c;…

数据结构-二叉树-堆(二)

一、建堆的时间复杂度问题 1、除了向上调整建堆&#xff0c;我们还可以向下调整建堆。不能在根上直接开始向下调整。这里的条件就是左右子树必须都是大堆或者小堆。我们可以倒着往前走&#xff0c;可以从最后一个叶子开始调整。但是从叶子开始调整没有意义。所以我们可以从倒数…