pytest fixtures测试函数参数化

Pytest会在以下几个级别启用测试参数化:

  • pytest.fixture(),可以对fixture函数进行参数化。
  • @pytest.mark.parametrize,可以在测试函数或类中定义多组参数和fixture。
  • pytest_generate_tests,可以自定义参数化方案或扩展。

一、@pytest.mark.parametrize:参数化测试函数

1. 常规用法

对测试函数的参数进行参数化,直接使用内置的装饰器pytest.mark.parameterized即可。

import pytest
@pytest.mark.parametrize("test_input,expected", [("3 5", 8), ("2 4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

从代码里可以看出,在装饰器里定义了三个不同的元组。我们把("test_input,expected", [("3 5", 8), ("2 4", 6), ("6*9", 42)])
拆开看:

  • "test_input,expected":这个字符串里定义了2个参数,test_input和expected。
  • ("3 5", 8), ("2 4", 6), ("6*9", 42):这里3个元组,没个元组里有2个元素,依次序分别对应test_input和expected。
  • 3个元组外层的[]:列表里就是参数化具体的传参了,因为里面传了3个不同的元组,所以测试函数test_eval会分别执行3次。
============================= test session starts =============================
platform win32 -- Python 3.9.4, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: D:\PycharmProjects\wms-api\interface, configfile: pytest.inicollected 3 items
test_module1.py ..F
demo\test_module1.py:3 (test_eval[6*9-42])
54 != 42
Expected :42
Actual   :54
 <Click to see difference>
test_input = '6*9', expected = 42
    @pytest.mark.parametrize("test_input,expected", [("3 5", 8), ("2 4", 6), ("6*9", 42)])
    def test_eval(test_input, expected):
>       assert eval(test_input) == expected
E       AssertionError: assert 54 == 42
E           where 54 = eval('6*9')
test_module1.py:6: AssertionError

运行结果可以看到最后一次失败了,因为第三次运行测试函数取的参数是 ("6*9", 42),54不等于42,所以断言失败。

2. 在参数化中标记单个测试实例

在参数化中标记单个测试实例,比如之前提到过的mark.xfail,这个可以标记测试函数为失败。那么在参数化中,如果想让其中的某个参数运行
的时候测试失败,就可以这样用:

import pytest
@pytest.mark.parametrize(
    "test_input,expected",
    [("3 5", 8), ("2 4", 6), pytest.param("6*9", 42, marks=pytest.mark.xfail)],
)
def test_eval(test_input, expected):
    assert eval(test_input) == expected

运行一下:

test_module1.py                                                       [100%]
======================== 2 passed, 1 xfailed in 0.05s =========================..x

3. 多个参数化组合,笛卡尔积

如果在测试函数上加了多个参数化装饰器,那么得到的参数组合是一个笛卡尔积:

import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
    print("\nx:", x)
    print("y:", y)

应该会组合成4组数据x=0/y=2, x=1/y=2, x=0/y=3, 和x=1/y=3,测试函数执行4次:

test_module1.py .
x: 0
y: 2
.
x: 1
y: 2
.
x: 0
y: 3
.
x: 1
y: 3
                                                     [100%]
============================== 4 passed in 0.01s ==============================

二、用钩子函数pytest_generate_tests example拓展

如果有些场景需要动态的确定参数或者fixture的使用范围,那么可以使用pytest_generate_tests这个钩子函数,该函数会在收集测试函数时候被调用。

通过传入的metafunc对象,可以检查请求测试函数的上下文,还可以进一步的调用metafunc.parameterize()来实现参数化。

举例,有个测试函数需要接受输入的字符串作为参数,而且通过pytest命令行获取到,那么就要编写一个获取参数的fixture函数来给测试函数调用。

# content of test_strings.py
def test_valid_string(stringinput):
    assert stringinput.isalpha()

新建conftest.py文件,fixture函数写在这里:

# content of conftest.py
def pytest_addoption(parser):
    parser.addoption(
        "--stringinput",
        action="append",
        default=[],
        help="list of stringinputs to pass to test functions",
    )
def pytest_generate_tests(metafunc):
    if "stringinput" in metafunc.fixturenames:
        metafunc.parametrize("stringinput", metafunc.config.getoption("stringinput"))

现在用命令行方式来运行这个测试函数:

pytest -q --stringinput="hello" --stringinput="world" test_strings.py

会运行2次。

D:\PycharmProjects\wms-api\interface\demo>pytest -q --stringinput="hello" --stringinput="world" test_strings.py
..                                                                                                                                                                     [100%]
2 passed in 0.01s

再换个输入参数,让测试函数失败:

pytest -q --stringinput="!" test_strings.py

FAILED test_strings.py::test_valid_string[!] - AssertionError: assert False1 failed in 0.04s

如果没有字符串输入,那么测试函数它将被跳过。因为metafunc.parameterize()被调用时&#xff0c;传过去的是一个列表:

pytest -q -rs test_strings.py

SKIPPED [1] test_strings.py: got empty parameter set ['stringinput'], function test_valid_string at $REGENDOC_TMPDIR/test_strings.py:2
1 skipped in 0.12s

注意,在调用metafunc时, 如果使用不同的参数集进行多次参数化,这些参数集上的所有参数名称都不能重复,否则将会报错。

总结

文中讲到的3种用法,实际应用中第一种最常见,第二种次之,至于第三种,可以作为一些用法启发,更多关于pytest fixtures测试函数参数化的资料请关注Devmax其它相关文章!

pytest fixtures函数及测试函数的参数化解读的更多相关文章

  1. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. pytest生成简单自定义测试结果的html报告

    这篇文章主要为大家介绍了pytest生成简单自定义测试结果html报告,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. Pytest测试报告工具Allure的高级用法

    这篇文章介绍了Pytest测试报告工具Allure的高级用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. 全网非常详细的pytest配置文件

    本文主要介绍了全网非常详细的pytest配置文件,pytest的主配置文件,可以改变pytest的默认行为,有很多可配置的选项,感兴趣的可以了解一下

  5. pytest官方文档解读fixtures调用fixtures及fixture复用性

    这篇文章主要为大家介绍了pytest官方文档解读fixtures调用fixtures及fixture复用性,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  6. 使用Django+Pytest搭建在线自动化测试平台

    最近由于公司的发展安排本人实现公司项目的自动化测试,下面这篇文章主要给大家介绍了关于如何Django + Pytest搭建在线自动化测试平台的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

  7. Pytest运行及其控制台输出信息

    这篇文章主要介绍了Pytest运行及其控制台输出信息,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

  8. Python测试框架pytest核心库pluggy详解

    这篇文章主要为大家介绍了Python测试框架pytest核心库pluggy使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. pytest解读fixtures中yield与addfinalizer区别

    这篇文章主要为大家介绍了pytest官方解读fixtures中yield与addfinalizer区别,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. 详解pytest分布式执行插件 pytest-xdist 的高级用法

    这篇文章主要介绍了pytest分布式执行插件 pytest-xdist 的高级用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部