Pytest权威教程13-Fixture方法及测试用例的参数化
Fixture方法及测试用例的参数化
Pytest在多个级别启用测试参数化:
pytest.fixture()允许一个[参数化Fixture方法。- @pytest.mark.parametrize允许在测试函数或类中定义多组参数和Fixture。
- pytest_generate_tests允许用户定义自定义参数化方案或扩展。
@pytest.mark.parametrize:参数化测试函数
2.2版中的新函数。
版本2.4中的更改:一些改进。
内置的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函数依次使用它们运行三次:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y,pytest-4.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
==================== 1 failed,2 passed in 0.12 seconds ====================
注意: 默认情况下,pytest会转义unicode字符串中用于参数化的任何非ascii字符,因为它有几个缺点。但是,如果你想在参数化中使用unicode字符串并在终端中按原样(非转义)查看它们,请在以下位置使用此选项
pytest.ini:
(译者注:需要pytest>=5.0.0, 数据或ids中的中文才能正常显示)
[pytest]
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
但请记住,这可能会导致不必要的副作用甚至是错误,具体取决于所使用的操作系统和当前安装的插件,因此使用它需要你自担风险。
如本例所示,只有一对输入/输出值无法通过简单的测试用例。和通常的测试函数参数一样,你可以在traceback中看到input和output值。
请注意,你还可以在类或模块上使用参数化标记(请参阅[使用属性标记测试函数),这将使用参数集调用多个函数。
也可以在参数化中标记单个测试实例,例如使用内置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-4.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.12 seconds ====================
之前导致失败的一个参数集现在显示为“xfailed(预期失败)”测试。
如果提供的值parametrize导致空列表 - 例如,如果它们是由某个函数动态生成的 - 则pytest的行为由该empty_parameter_set_mark选项定义。
要获得多个参数化参数的所有组合,你可以堆叠parametrize装饰器:
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例子
有时你可能希望实现自己的参数化方案或实现一些动力来确定Fixture的参数或范围。为此,你可以使用pytest_generate_tests在收集测试函数时调用的钩子。通过传入的metafunc对象,你可以检查请求的测试上下文,最重要的是,你可以调用metafunc.parametrize()以引起参数化。
例如,假设我们想要运行一个测试,我们想通过一个新的pytest命令行选项设置字符串输入。让我们首先编写一个接受stringinputfixture函数参数的简单测试:
# 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.12 seconds
让我们运行一个stringinput导致测试失败:
$ 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
1 failed in 0.12 seconds
正如所料,我们的测试用例失败。
如果你没有指定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.12 seconds
注意:
metafunc.parametrize使用不同的参数集多次调用时,这些集合中的所有参数名称都不能重复,否则将引发错误。
更多示例
有关更多示例,你可能需要查看更多参数化示例。
Pytest权威教程13-Fixture方法及测试用例的参数化的更多相关文章
- Pytest权威教程06-使用Marks标记测试用例
目录 使用Marks标记测试用例 在未知标记上引发异常: -strict 标记改造和迭代 返回: Pytest权威教程 使用Marks标记测试用例 通过使用pytest.mark你可以轻松地在测试用例 ...
- Pytest权威教程(官方教程翻译)
Pytest权威教程01-安装及入门 Pytest权威教程02-Pytest 使用及调用方法 Pytest权威教程03-原有TestSuite的执行方法 Pytest权威教程04-断言的编写和报告 P ...
- Pytest权威教程02-Pytest 使用及调用方法
目录 Pytest 使用及调用方法 使用python -m pytest调用pytest 可能出现的执行退出code 获取版本路径.命令行选项及环境变量相关帮助 第1(N)次失败后停止测试 指定及选择 ...
- Pytest权威教程19-编写钩子(Hooks)方法函数
目录 编写钩子(Hooks)函数 钩子函数验证和执行 firstresult: 遇到第一个有效(非None)结果返回 hookwrapper:在其他钩子函数周围执行 钩子(Hooks)函数排序/调用示 ...
- Pytest权威教程12-跳过(Skip)及预期失败(xFail): 处理不能成功的测试用例
目录 跳过(Skip)及预期失败(xFail): 处理不能成功的测试用例 Skip跳过用例 xFail:将测试函数标记为预期失败 Skip/xFail参数设置 返回: Pytest权威教程 跳过(Sk ...
- Pytest权威教程03-原有TestSuite的执行方法
目录 原有TestSuite的执行方法 使用pytest运行已存在的测试套件(test suite) 返回: Pytest权威教程 原有TestSuite的执行方法 Pytest可以与大多数现有的测试 ...
- Pytest权威教程21-API参考-05-对象(Objects)
目录 对象(Objects) CallInfo Class Collector Config ExceptionInfo FixtureDef FSCollector Function Item Ma ...
- Pytest权威教程21-API参考-03-夹具(Fixtures)
目录 夹具(Fixtures) @ pytest.fixture config.cache的 capsys capsysbinary capfd capfdbinary doctest_namespa ...
- Pytest权威教程01-安装及入门
目录 安装及入门 安装 Pytest 创建你的第一个测试用例 执行多条测试用例 断言抛出了指定异常 使用类组织多条测试用例 函数测试中请求使用独立的临时目录 进一步阅读 返回: Pytest权威教程 ...
随机推荐
- .NET Window服务启动又马上停止,报错IO.FileNotFoundException
最近公司需要开发一个Window服务推送系统,读取MongoDB写入消息队列,推送到各终端平台 但是在开发完成,最后的部署阶段,选中服务右击启动 看似正常,服务显示已启动(但实质已经被终止,因为Win ...
- web项目服务器安装及配置(虚拟机centOS7)
一.安装VMware(如需) 1.首先下载VMware虚拟机,地址: https://www.vmware.com/products/workstation-pro/workstation-pro-e ...
- 使用ranger替代资源浏览器
使用方法参考,这个是比较高校的: http://www.mikewootc.com/wiki/linux/usage/ranger_file_manager.html
- unity4.3.4firedrillonline项目首次整合问题总结
零.资源导入后把所有资源模型拖到场景中去,并reset Transform,使场景展现原有样子. 一.资源导入之后发现项目场景是黑的,添加灯光之后场景中大部分仍然是黑的(并没有光照的效果) 可能原因: ...
- Vue路由传参的几种方式
原 Vue路由传参的几种方式 2018年07月28日 23:52:40 广积粮缓称王 阅读数 12613 前言:顾名思义,vue路由传参是指嵌套路由时父路由向子路由传递参数,否则操作无效.传参方式 ...
- 无法将文件“E:\NetWorkPace\Permission\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.xml”复制到“bin\EntityFramework.xml”。对路径“bin\EntityFramework.xml”的访问被拒绝。
无法将文件“E:\NetWorkPace\Permission\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.xml”复制到“bin ...
- Linux命令——modprobe
参考:5 UNIX / Linux modprobe Command Examples Linux modprobe command 简介 modprobe用于向Linux Kernel添加 或 移除 ...
- Exchange 退信550 5.1.11 RESOLVER.ADR.ExRecipNotFound
问题描述: 在Exchange 2013环境下,某客户将一个用户的邮箱test@abc.com禁用,过了几天又想连接该邮箱,但是却没有找到禁用的邮箱,然后客户就Enable-MailBox重新创建了一 ...
- 公用表表达式(CTE) with as
在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式(Common Table ...
- python高级特性-迭代器
凡是可作用于for循环的对象都是Iterable类型: 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列: 集合数据类型如list.dict.str等是Itera ...