IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 参数化装置和测试方法 -> 正文阅读

[开发测试]参数化装置和测试方法

pytest 在多个级别启用测试参数化:

  • pytest.fixture() 允许参数化装置方法。
  • @pytest.mark.parametrize 允许在测试函数或类中定义多组参数和装置。
  • pytest_generate_tests 允许定义自定义参数化方案或扩展。

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

内置的 pytest.mark.parametrize 装饰器可以对测试函数的参数进行参数化。下面是一个测试函数的典型示例,该函数执行检查某个输入是否会导致预期输出:

# content of test_expectation.py
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

在这里,@parametrize 装饰器定义了三个不同的 (test_input,expected) 元组,以便 test_eval 函数将依次使用它们运行 3 次:

$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR
collected 3 items

test_expectation.py ..F                                              [100%]

================================= FAILURES =================================
____________________________ test_eval[6*9-42] _____________________________

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_expectation.py:6: AssertionError
========================= short test summary info ==========================
FAILED test_expectation.py::test_eval[6*9-42] - AssertionError: assert 54...
======================= 1 failed, 2 passed in 0.12s ========================

Note: 参数值按原样传递给测试(没有任何副本)。 例如,如果您将列表或字典作为参数值传递,并且测试用例代码对其进行了更改,则更改将反映在后续的测试用例调用中。

Note:默认情况下,pytest 会转义 unicode 字符串中用于参数化的任何非 ascii 字符,因为它有几个缺点。但是,如果您想在参数化中使用 unicode 字符串并在终端中按原样(非转义)查看它们,请在 pytest.ini 中使用此选项:

[pytest]
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True

但是请记住,这可能会导致不必要的副作用甚至错误,具体取决于所使用的操作系统和当前安装的插件,因此请自行承担风险。

如本示例中设计的那样,只有一对输入/输出值无法通过简单的测试功能。和通常使用测试函数参数一样,您可以在跟踪信息中看到输入和输出值。

请注意,您还可以在类或模块上使用参数化标记(请参阅使用属性标记测试函数),这将使用参数集调用多个函数。

也可以在参数化中标记单个测试实例,例如使用内置的 mark.xfail:

# content of test_expectation.py
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

让我们执行它:

$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR
collected 3 items

test_expectation.py ..x                                              [100%]

======================= 2 passed, 1 xfailed in 0.12s =======================

之前导致失败的一个参数集现在显示为“xfailed”(预期失败)测试。

如果提供给参数化的值导致空列表 - 例如,如果它们是由某个函数动态生成的 - pytest 的行为由 empty_parameter_set_mark 选项定义。

要获得多个参数化参数的所有组合,您可以堆叠参数化装饰器:

import pytest


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

这将在参数设置为 x=0/y=2、x=1/y=2、x=0/y=3 和 x=1/y=3 的情况下运行测试,按照装饰器的顺序耗尽参数.

基本 pytest_generate_tests 示例

有时您可能想要实现自己的参数化方案或实现一些动态来确定装置的参数或范围。为此,您可以使用在收集测试函数时调用?pytest_generate_tests 钩子。通过传入的 metafunc 对象,您可以检查请求的测试上下文,最重要的是,您可以调用 metafunc.parametrize() 来进行参数化。

例如,假设我们想要通过新的 pytest 命令行选项设置字符串输入来运行测试。让我们首先编写一个接受 stringinput 装置函数作为参数的简单测试:

# content of test_strings.py


def test_valid_string(stringinput):
    assert stringinput.isalpha()

现在我们添加一个 conftest.py 文件,其中包含添加的命令行选项和测试函数的参数化:

# 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"))

如果我们现在传递两个 stringinput 值,我们的测试将运行两次:

$ pytest -q --stringinput="hello" --stringinput="world" test_strings.py
..                                                                   [100%]
2 passed in 0.12s

让我们也运行一个会导致测试失败的字符串输入:

$ pytest -q --stringinput="!" test_strings.py
F                                                                    [100%]
================================= FAILURES =================================
___________________________ test_valid_string[!] ___________________________

stringinput = '!'

    def test_valid_string(stringinput):
>       assert stringinput.isalpha()
E       AssertionError: assert False
E        +  where False = <built-in method isalpha of str object at 0xdeadbeef>()
E        +    where <built-in method isalpha of str object at 0xdeadbeef> = '!'.isalpha

test_strings.py:4: AssertionError
========================= short test summary info ==========================
FAILED test_strings.py::test_valid_string[!] - AssertionError: assert False
1 failed in 0.12s

正如预期的那样,我们的测试用例失败了

如果您不指定 stringinput 它将被跳过,因为 metafunc.parametrize() 将使用空参数列表调用:

$ pytest -q -rs test_strings.py
s                                                                    [100%]
========================= short test summary info ==========================
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.parametrize 时,这些集合中的所有参数名称不能重复,否则将引发错误。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-27 12:10:10  更:2021-08-27 12:11:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 13:39:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码