前言
上一篇我们介绍了Pytest是如何进行参数化的,这一篇我们将给大家介绍的一些常用标记。
skip 和 xfail 标记
实际工作中,测试用例的执行可能会依赖于一些外部条件,例如:只能运行在某个特定的操作系统(Windows),或者我们本身期望它们测试失败,例如:被某个已知的Bug所阻塞;如果我们能为这些用例提前打上标记,那么pytest就相应地预处理它们,并提供一个更加准确的测试报告。
pytest 比较常用的标记有:
•skip:只有当某些条件得到满足时,才执行测试用例,否则跳过整个测试用例的执行;例如,在非Windows平台上跳过只支持Windows系统的用例;•xfail:因为一个确切的原因,我们知道这个用例会失败;例如,对某个未实现的功能的测试,或者阻塞于某个已知Bug的测试;
pytest默认不显示skip和xfail用例的详细信息,但我们可以通过 -r
选项来自定义这种行为:通常,我们使用一个字母作为一种类型的代表,具体的规则如下:
(f)ailed, (E)rror, (s)kipped, (x)failed, (X)passed, (p)assed, (P)assed with output, (a)ll except passed(p/P), or (A)ll
如显示结果为XFAIL、XPASS和SKIPPED的用例:
pytest -rsxX
skip 跳过测试用例执行
1.@pytest.mark.skip装饰器 跳过执行某个用例最简单的方式就是使用@pytest.mark.skip
装饰器,并且可以设置一个可选参数reason,表明跳过的原因
@pytest.mark.skip(reason="no way of currently testing this")
def test_the_unknown():
...
1.@pytest.mark.skipif装饰器 如果我们想有条件的跳过某些测试用例的执行,可以使用@pytest.mark.skipif装饰器
import sys,pytest
@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6 or higher")
def test_function():
...
在大型的测试项目中,可以在一个文件中定义所有的执行条件,需要时就引入到模块中
xxx.py
minversion = pytest.mark.skipif(sys.version_info < (3, 8),
reason='请使用 python 3.8 或者更高的版本。')
引用模块
from xxx import minversion
@minversion
def test_two():
pass
1.跳过测试类 在类上应用@pytest.mark.skip或@pytest.mark.skipif, 会作用于类中的每一个用例
import pytest
@pytest.mark.skip("作用于类中的每一个用例,所以 pytest 共收集到两个 SKIPPED 的用例。")
class TestMyClass():
def test_one(self):
assert True
def test_two(self):
assert True
1.跳过测试模块
import pytest
pytestmark = pytest.mark.skip('作用于模块中的每一个用例,所以 pytest 共收集到两个 SKIPPED 的用例。')
def test_one():
assert True
def test_two():
assert True
xfail 标记用例为预期失败的
1.我们可以使用@pytest.mark.xfail标记用例,表示期望这个用例执行失败;
用例会正常执行,只是失败时不再显示堆栈信息,最终的结果有两个:用例执行失败时(xfailed:符合预期的失败)、用例执行成功时(xpassed:不符合预期的成功)
@pytest.mark.xfail
def test_func():
assert func(5) == 6
if __name__ == '__main__':
pytest.main(['-s', 'test_para.py'])
1.我们也可以通过pytest.xfail方法在用例执行过程中直接标记用例结果为XFAIL,并跳过剩余的部分:
def test_func():
print('111')
pytest.xfail("it's not ok")
print(222)
============================= test session starts ==============================
platform darwin -- Python 3.7.3, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /Users/zhangcheng/Documents/project/7.18/test_py
collected 1 item
test_para.py 111
x
============================== 1 xfailed in 0.06s ==============================
1.xfail 它也可以接收一个python表达式,表明只有满足条件时才标记用例;
@pytest.mark.xfail(sys.version_info >= (3, 6), reason="python3.6 api changes")
def test_function():
...
1.结合pytest.param方法
import pytest
import sys
@pytest.mark.parametrize(
('n', 'expected'),
[(2, 1),
pytest.param(2, 1, marks=pytest.mark.xfail(), id='XPASS'),
pytest.param(0, 1, marks=pytest.mark.xfail(raises=ZeroDivisionError), id='XFAIL'),
pytest.param(1, 2, marks=pytest.mark.skip(reason='无效的参数,跳过执行')),
pytest.param(1, 2, marks=pytest.mark.skipif(sys.version_info <= (3, 8), reason='请使用3.8及以上版本的python。'))])
def test_params(n, expected):
assert 2 / n == expected
pytest -s -rsxXp test_para.py
====================================================== short test summary info ======================================================
SKIPPED [1] test_para.py:31: 无效的参数,跳过执行
SKIPPED [1] test_para.py:31: 请使用3.8及以上版本的python。
XFAIL test_para.py::test_params[XFAIL]
XPASS test_para.py::test_params[XPASS]
PASSED test_para.py::test_params[2-1]
生成测试报告
Pytest 也可以很方便的生成测试报告,但前提是要先安装pytest-html
插件。
1.安装 pytest-html 插件
pip install pytest-html
1.新建run.py (在新目录下):
if __name__ == '__main__':
pytest.main(['-s', '-v', '../test_case', '--html=../reports/report.html'])
好了,经过这5篇的讲解,Pytest 的常用方法已经介绍完毕,当然,大家在使用过程中肯定还会遇到许多细节问题,这就要求大家自己去尝试解决,加深理解,这样才能更好的掌握Pytest这一框架。
谢谢大家!
鲲鹏!
本文分享自微信公众号 - 软件测试架构师俱乐部(gh_03227f9a322f)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。