在自动化测试过程中,有时会遇到某些测试用例的结果不稳定,例如受竞态条件、外部依赖或随机数据影响,导致偶发性失败。为了复现此类难以捉摸的问题,我们可以借助 pytest-repeat 插件对测试用例进行多次重复执行。
安装插件
通过 pip 安装 pytest-repeat:
pip install pytest-repeat
使用方式一:命令行参数
pytest-repeat 主要通过两个命令行参数来控制重复执行行为:
--count: 指定测试重复运行的次数(必填)。
--repeat-scope: 定义重复执行的维度范围(选填)。可选值有 function (默认)、class、module、session。例如,session 表示执行完所有用例一次后,再整体重复执行第二次。
基本命令格式:
pytest --count=3 --repeat-scope=function
或
pytest --count 3 --repeat-scope function
你也可以将这些参数永久添加到 pytest.ini 配置文件中,从而融入到你的日常Python自动化测试工作流:
[pytest]
addopts = -v --count 3 --repeat-scope function
下面通过示例展示不同 --repeat-scope 参数的效果。假设我们有两个简单的测试函数:
def test_b():
print("---test_b")
def test_a():
print("---test_a")
1. --repeat-scope=function (默认)
此模式下,每个测试函数会独立重复执行指定次数,再执行下一个函数。
pytest --count=3 --repeat-scope=function
运行结果摘要:执行顺序为 test_b (第1次) → test_b (第2次) → test_b (第3次) → test_a (第1次) → test_a (第2次) → test_a (第3次)。
如果不指定 --repeat-scope,默认行为与 --repeat-scope=function 一致。
pytest --count=3
运行结果:与上图完全一致。
2. --repeat-scope=module
此模式下,整个模块内的所有测试会作为一个整体,按顺序执行一轮,然后再重复整个模块的执行流程。
pytest --count=3 --repeat-scope=module
运行结果摘要:执行顺序为 test_b → test_a (第一轮) → test_b → test_a (第二轮) → test_b → test_a (第三轮)。
3. --repeat-scope=class
当测试用例组织在类中时,此模式会按类维度进行重复。我们调整一下示例代码:
class Test1:
def test_b(self):
print("---test_b")
def test_d(self):
print("---test_d")
class Test2:
def test_a(self):
print("---test_a")
def test_c(self):
print("---test_c")
使用命令:
pytest --count=2 --repeat-scope=class
运行结果摘要:执行顺序为 Test1::test_b → Test1::test_d (第一轮) → Test2::test_a → Test2::test_c (第一轮) → Test1::test_b → Test1::test_d (第二轮) → Test2::test_a → Test2::test_c (第二轮)。
4. --repeat-scope=session
这是最全局的维度,意味着整个测试会话(所有收集到的用例)会完整地执行一遍,然后再从头开始执行下一遍。
pytest --count=2 --repeat-scope=session
使用之前的两个测试类代码,运行结果摘要为:先按默认发现顺序执行完 Test1::test_b, Test1::test_d, Test2::test_a, Test2::test_c,然后再按完全相同的顺序执行第二遍。这在排查因测试环境状态累积导致的软件测试偶发问题时会非常有用。
使用方式二:装饰器
除了全局命令行控制,你还可以为单个测试函数使用 @pytest.mark.repeat(count) 装饰器来指定其重复执行次数。这种方式提供了更精细的控制。
import pytest
@pytest.mark.repeat(3)
def test_a():
print("---test_a")
def test_b():
print("---test_b")
运行测试后,只有 test_a 会被执行3次,而 test_b 仅执行1次。这种方法非常适合针对特定的、已知不稳定的用例进行重点验证,而无需改动运维/DevOps中使用的全局测试命令或配置。
结合命令行参数与装饰器,pytest-repeat 插件为自动化测试中的稳定性验证和问题复现提供了强大且灵活的解决方案。