Pytest框架 — 12、Pytest的标记(三)(重复执行)
目录
1、前言
在自动化测试的时候我们可能会遇到某些原因,如模块不稳定等,出现一些测试失败,此时我们想要针对单个用例或者单个模块重复执行多次,以确定测试失败的真正原因。在Pytest
中可以通过插件pytest-repeat
来实现。
安装方式:pip install pytest-repeat
2、--count参数使用
(一)在命令行或者main
函数使用
pytest -s -v ./xxx.py --count=3
pytest.main(["-vs","xxx.py","--count=3"])
示例:
def test_1():
print("测试1")
assert True
def test_2():
print("测试2")
assert False
"""
执行结果
mark/repeat/repeat_count.py::test_1[1-3] 测试1
PASSED
mark/repeat/repeat_count.py::test_1[2-3] 测试1
PASSED
mark/repeat/repeat_count.py::test_1[3-3] 测试1
PASSED
mark/repeat/repeat_count.py::test_2[1-3] 测试2
FAILED
mark/repeat/repeat_count.py::test_2[2-3] 测试2
FAILED
mark/repeat/repeat_count.py::test_2[3-3] 测试2
FAILED
"""
(二)在全局配置文件中使用
在pytest.ini
配置文件中addopts
添加count
参数
[pytest]
addopts = -s -v --count 2
testpaths = scripts
python_files = test_*.py
python_classes = Test*
python_functions = test*
示例:
def test_1():
print("测试1")
assert True
def test_2():
print("测试2")
assert False
"""
执行结果
mark/repeat/repeat_count.py::test_1[1-2] 测试1
PASSED
mark/repeat/repeat_count.py::test_1[2-2] 测试1
PASSED
mark/repeat/repeat_count.py::test_2[1-2] 测试2
FAILED
mark/repeat/repeat_count.py::test_2[2-2] 测试2
FAILED
"""
3、--repeat-scope参数使用
从上面的示例中可以看到测试1先执行了3次,然后测试2再执行3次,有些时候我们想整体执行3次,这就需要用到--repeat-scope
参数。类似于fixture
的scope
也可以设置范围
session
:重复整个测试会话,即所有收集到的测试用例测试完成一次,再进行下一次测试module
:重复整个模块,即模块内所有收集到的测试用例测试完成一次,再进行下一次测试class
:重复所有类,即以每个类为集合所有测试用例测试完成一次,再进行下一次测试function
:默认范围,重复所有函数和方法,即一个测试函数或方法重复执行完毕,再对下一个测试函数重复执行
测试代码:
class TestClass_1:
def test_method_1(self):
print("类1测试方法1")
def test_method_2(self):
print("类1测试方法2")
class TestClass_2:
def test_method_1(self):
print("类2测试方法1")
def test_method_2(self):
print("类2测试方法2")
- 类级别执行
pytest -s -v xxx.py --count=2 --repeat_scope=class
"""
执行结果
mark/repeat/repeat_scope.py::TestClass_1::test_method_1[1-2] 类1测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_1::test_method_2[1-2] 类1测试方法2
PASSED
mark/repeat/repeat_scope.py::TestClass_1::test_method_1[2-2] 类1测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_1::test_method_2[2-2] 类1测试方法2
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_1[1-2] 类2测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_2[1-2] 类2测试方法2
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_1[2-2] 类2测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_2[2-2] 类2测试方法2
PASSED
"""
- 模块级别执行
pytest -s -v xxx.py --count=2 --repeat-scope=module
"""
执行结果
mark/repeat/repeat_scope.py::TestClass_1::test_method_1[1-2] 类1测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_1::test_method_2[1-2] 类1测试方法2
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_1[1-2] 类2测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_2[1-2] 类2测试方法2
PASSED
mark/repeat/repeat_scope.py::TestClass_1::test_method_1[2-2] 类1测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_1::test_method_2[2-2] 类1测试方法2
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_1[2-2] 类2测试方法1
PASSED
mark/repeat/repeat_scope.py::TestClass_2::test_method_2[2-2] 类2测试方法2
PASSED
"""
4、@pytest.mark.repeat(count)装饰器使用
还可以在测试代码中使用@pytest.mark.repeat(count)
装饰器来标记需要重复执行的测试。
import pytest
@pytest.mark.repeat(2)
def test_1():
print("测试函数1")
def test_2():
print("测试函数2")
class TestClass:
def test_1(self):
print("类中测试方法1")
@pytest.mark.repeat(3)
def test_2(self):
print("类中测试方法2")
"""
执行结果
mark/repeat/repeat_mark.py::test_1[1-2] 测试函数1
PASSED
mark/repeat/repeat_mark.py::test_1[2-2] 测试函数1
PASSED
mark/repeat/repeat_mark.py::test_2 测试函数2
PASSED
mark/repeat/repeat_mark.py::TestClass::test_1 类中测试方法1
PASSED
mark/repeat/repeat_mark.py::TestClass::test_2[1-3] 类中测试方法2
PASSED
mark/repeat/repeat_mark.py::TestClass::test_2[2-3] 类中测试方法2
PASSED
mark/repeat/repeat_mark.py::TestClass::test_2[3-3] 类中测试方法2
PASSED
"""
注意:使用装饰器标记的重复执行用例不受参数执行的影响,即当上面例子在执行时使用--count=5
,标记过的测试用例以装饰器标记次数为准,其他未标记的测试用例会执行5次。
5、结合参数x使重复执行在失败时停止
如果遇到间歇性bug,可以在命令中--count
与-x
结合使用,重复执行测试用例,直到测试失败停止。
pytest -vs -x xxx.py --count=100
这样将运行100次,一旦遇到失败就会停止。