pytest
提供 用例发现、用例筛选、用例执行、用例报告、第三方插件等功能。
官方文档:pytest: helps you write better programs
安装
pip install pytest
使用
使用 pytest 来创建用例、执行用例。
创建用例
- 创建 test_ 开头的
.py
文件 - 创建 test_ 开头的函数
- 在函数中使用 assert 进行断言
pytest 发现测试的规则
- 如果未指定
testpaths
,则从当前目录开始收集。命令行参数可以用于目录、文件名或节点 ID 的任意组合。 - 默认会对目录进行递归查找,除非配置了
norecursedirs
。 - 会发现
test_*.py
或者*_test.py
命令格式的 python 文件。 - 顶层
test
前缀的函数(注意可以不用下划线)。 - 没有
__init__
方法的且以Test
为前缀的类的test
前缀的方法。
def test_api():
assert 1 == '1'
执行用例
打开终端,输入:
pytest
或者在 python
文件中执行 pytest.main()
断言方法
assert 表达式
pytest 支持通过 assert 表达式直接进行断言操作,pytest 会对断言进行内省,使得报告信息更加详细。
断言会出现异常
使用 with
语句,执行 pytest.raises
函数:
with pytest.raises(预期异常) [as 异常变量]:
pass # 会抛出异常的语句
配置
pytest 支持使用 -h 参数显示可选的配置项。
也支持使用 pytest.ini
或者 .pytest.ini
进行配置。
配置格式如下:Configuration file formats
addopts = -ra -q
常用选项
-v
: 增加详细程度-q
: 减少冗长-r(chars)
: 指定要显示的额外测试摘要信息,默认是(fE,失败和错误)f
|x
:失败E
:错误s
:跳过的X
|p
:通过的P
:通过的,并输出标准输出内容ap
|aP
:排除通过的A
:全部
--no-header
: 不显示头部的环境信息--no-summary
: 不显示测试结果摘要
fixture(固件)
官方文档:How to use fixtures
fixture
是一种用于在测试函数执行前设置环境或数据的机制。 可以在多个测试之间共享相同的配置或数据,从而避免重复代码并提高测试效率。 fixture
可以是函数、类或者模块级别的,并且可以通过参数化来处理不同的输入情况。 也可以使用 conftest.py
专门存放 fixture
。
通过使用 @pytest.fixture
装饰器来定义一个 fixture
,然后在测试函数中使用 fixture_name
作为参数来访问它。
参数
scope
:定义固件的作用域(**默认值:function **),官方文档:Fixture Scopesfunction
:函数,所有使用到的测试函数在执行前都会先重新执行一次(包括重试的测试函数)。class
:类,在类内部第一个使用到的测试函数执行时会执行一次,其它的不再执行,在类的最后一个用例执行的销毁。module
:模块session
:会话
autouse
:是否自动使用(默认值:False),即默认情况下,如果没有使用则不会执行 fixture 函数。name
:指定固件的名称(默认值:函数名)params
:参数化,每一个参数会执行一次,通过request.param
获取当前的参数值。ids
:配合 params 使用,指定 params 的别名。
⚠️ 注意
- 使用
pytest-rerunfailures
插件时,兼容性较差,scope 配置会失效。 - 使用
pytest-xdist
插件时,要注意指定合适的方法模式。如使用loadscope
使得 scope 配置为 class 的 fixture 生效。
pytest 支持 xunit 格式的初始化设置
官方文档:How to implement xunit-style set-up
模块:setup_module
、teardown_module
类:setup_class
、teardown_class
方法:setup_method
、teardown_method
函数:setup_function
、teardown_function
添加后置操作
pytest 的 fixture 添加后置操作只需要在函数内部使用一个 yield 关键字即可。
可以使用 yield
关键字代替 return
返回数据。
多个 yield 关键字会报错
fixture function has more than one 'yield'
内置 fixture
官方文档:Built-in fixtures
request
提供有关执行测试功能的信息。
官方文档:reference
tmp_path(临时目录)
为每个测试函数唯一的临时目录提供一个 pathlib.Path
对象。
扩展使用
用例数据分离
插件
官方文档:How to install and use plugins
pytest-html
用于生成 HTML 格式的测试报告。
安装
pip install pytest-html
使用
pytest-html
插件的使用非常简单,只需要配置 --html(生成的 html 存放位置) 选项即可。
配置报告标题
在 conftest.py
文件中添加:
# 在将标题添加到报告之前调用
def pytest_html_report_title(report):
report.title = "report title"
pytest-rerunfailures
可以重新运行测试以消除间歇性故障。
安装
pip install pytest-rerunfailures
使用
使用 --reruns
直接指定重试次数。
失败的 fixture 或 setup_class 也将被重新执行。
可选配置
--reruns-delay
:配置每次重试的时间间隔(单位为秒),默认是立即执行--only-rerun
:配置要进行重试的错误,可多次传递,eg:--only-rerun=AssertionError --only-return=ValueError
--rerun-except
:配置只有出现的错误不是提供的错误的才会重试(也支持多次传递),可以通过assert
表示AssertionError
针对单个用例配置
可在测试用例上添加 @pytest.mark.flaky
支持 reruns
、reruns_delay
、only_rerun
、rerun_expect
、condition
参数。
eg:
reruns=5
:最多重试 5 次。reruns_delay=1
:间隔 1 秒一次。rerun_except=AssertionError
:只有不是AssertionError
错误才会重试。only_rerun=["AssertionError", "ValueError"]
:只有AssertionError
和ValueError
错误才会重试。condition="sys.platform.startswith('win32')"
、condition=sys.platform.startswith("win32")
:只有 win32 平台才重试。
⚠️ 注意
- 注意默认情况下 pytest 是一个个测试用例执行的,一个用例重试完成后才会执行执行其它测试用例。 可考虑使用下面的
pytest-xdist
插件。 - 🧰
rerunfailures
插件和 fixture 不兼容!!!
pytest-xdist
pytest-xdist
插件使用新的测试执行模式扩展了 pytest
,最常用的是将测试分布在多个 CPU 上以加速测试执行。
安装
pip install pytest-xdist
使用
使用 -n
直接指定使用的线程数,还支持支持 auto
和 logical
。
auto
:尝试检测物理 CPU 计数。如果无法确定物理 CPU 计数,则回退到 1。logical
:尝试检测逻辑 CPU 计数(需要psutil
,否则回退到使用auto
)。
分发方式
通过 --dist
选项指定分发方式。
load
:默认分发方式,将待处理的测试发送给任何可用的 worker,不保证任何顺序。 可配合(--maxschedchunk
) 选项使用,指定每一次提交到worker
的测试用例数,默认没有限制。loadscope
:按模块和类进行分发,类分发优先级高于模块。loadfile
:按文件进行分发。loadgroup
:通过@pytest.mark.xdist_group(name="group_name")
指定分组进行分发。worksteal
:和 load 类似,分发方式为先平均分配,当一个worker
执行完成所有的用例后,去窃取其它剩余用例大于 2 的worker
的用例。no
:正常的 pytest 模式,不进行分发。
在多个进程中共享数据
官方文档:Making session-scoped fixtures execute only once
allure-pytest
创建精美而清晰的测试报告。
安装
下载对应环境的 allure
安装包。 下载地址
pip install allure-pytest
使用
pytest-html
插件的使用非常简单,只需要配置 --alluredir
(生成的报告存放目录) 选项即可。
然后执行 allure serve 生成的报告存放目录
⚠️ 参数化时 Allure history id 的计算规则
Allure 在计算 history id 时没有使用 ids 参数返回值,而是通过调用 repr
方法获取对象的规范字符串表示形式, 也就是说如果使用的是自定类进行参数化时,要确保 history id 正确计算,需要重写 __repr__
方法。