Pytest之skip、skipif、xfail
以下主要介绍pytest中skip
、skipif
、xfail
的用法。
mark基本介绍
mark概念
在pytest当中,给用例打标记,在运行时,通过标记名
来过滤测试用例。
使用mark的原因
在自动化过程中,我们可以能遇到问题,比如测试用例比较多,且不在一个层级,想将某些用例作为冒烟测试用例,要怎么处理。pytest提供了mark
功能,可以解决此问题。
mark分类
mark可分为2
类:
-
一类是
系统内置的mark
,不同的mark标记提供不同的功能。 -
二类是
自定义的mark
,该类mark主要用于给测试用例分门别类,使得运行测试时可以指定运行符合哪一类标记的测试用例。
内置mark
查看内置的mark,输入命令:pytest --markers
。
@pytest.mark.allure_label: allure label marker @pytest.mark.allure_link: allure link marker @pytest.mark.allure_display_name: allure test name marker @pytest.mark.allure_description: allure description @pytest.mark.allure_description_html: allure description html @pytest.mark.filterwarnings(warning): add a warning filter to the given test. see https://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings @pytest.mark.skip(reason=None): skip the given test function with an optional reason. Example: skip(reason="no way of currently testing this") skips the test. @pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see https://docs.pytest.org/en/latest/skipping.html @pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See https://docs.pytest.org/en/latest/skipping.html @pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see https://docs.pytest.org/en/latest/parametrize.html for more info and examples. @pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see https://docs.pytest.org/en/latest/fixture.html#usefixtures @pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. @pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible.
以下主要介绍skip、skipif、xfail这三种的用法。
skip
语法:@pytest.mark.skip(reason=None)
说明:跳过执行测试用例,可选参数reason,跳过的原因,会在执行结果中打印。
用法:在类、方法或函数上添加@pytest.mark.skip
。
类使用 @pytest.mark.skip
作用于类上,则类下面的所有方法都跳过测试。
现有如下类:
test_demo.py
class TestDemo(): def test_demo01(self): print("这是test_demo01") def test_demo02(self): print("这是test_demo02")
目前因为TestDemo类功能并未完成,想跳过用例执行,在类上方添加@pytest.mark.skip即可。
import pytest @pytest.mark.skip(reason="功能未实现,暂不执行") class TestDemo(): def test_demo01(self): print("这是test_demo01") def test_demo02(self): print("这是test_demo02")
运行结果如下:
方法使用@pytest.mark.skip
作用于方法上,则此方法跳过测试。
现在有如下类:
test_demo.py
class TestDemo(): def test_demo01(self): print("这是test_demo01") def test_demo02(self): print("这是test_demo02")
目前因为test_demo02方法功能并未完成,想跳过用例执行,在test_demo02方法上添加@pytest.mark.skip
即可。
import pytest class TestDemo(): def test_demo01(self): print("这是test_demo01") @pytest.mark.skip(reason="功能未实现,暂不执行") def test_demo02(self): print("这是test_demo02")
运行结果如下:
函数使用@pytest.mark.skip
现有如下函数:
test_demo.py
def test_demo01(): print("这是test_demo01") def test_demo02(): print("这是test_demo02")
目前因为test_demo02函数功能并未完成,想跳过用例执行,在函数上方添加@pytest.mark.skip
即可。
import pytest def test_demo01(): print("这是test_demo01") @pytest.mark.skip(reason="功能未实现,暂不执行") def test_demo02(): print("这是test_demo02")
执行结果如下:
补充:除了通过使用标签的方式,还可以在测试用例中调用pytest.skip()
方法来实现跳过,传入msg参数来说明跳过原因。
def test_demo01(): n = 1 while True: print("当前的的值为{}".format(n)) n += 1 if n == 4: pytest.skip("跳过的值为{}".format(n))
skipif
语法:@pytest.mark.skipif(self,condition, reason=None)
。
说明:跳过执行测试用例,condition参数为条件,可选参数reason,跳过的原因,会在执行结果中打印。
从之前的运行结果可以看出一些软件版本信息。
比如当前的python版本为3.6,要求python版本必须大于3.7,否则跳过测试。
import pytest import sys def test_demo01(): print("这是test_demo01") @pytest.mark.skipif(sys.version < '3.7', reason="python版本必须大于3.7") def test_demo02(): print("这是test_demo02")
运行结果如下:
xfail
应用场景:用例功能不完善或者用例执行失败,可以标记为xfail。
语法:@pytest.mark.xfail(self,condition=None, reason=None, raises=None, run=True, strict=False)
。
说明:期望测试用例是失败的,但是不会影响测试用例的的执行。如果测试用例执行失败的则结果是xfail(不会额外显示出错误信息);如果测试用例执行成功的则结果是xpass。
来个小例子实战下,用例断言失败,且标记为xfail。
test_demo.py
import pytest def test_demo01(): print("这是test_demo01") @pytest.mark.xfail() def test_demo02(): print("这是test_demo02") assert 1 == 2
运行结果为:
接下将用例断言成功,标记为xfail。
import pytest def test_demo01(): print("这是test_demo01") @pytest.mark.xfail() def test_demo02(): print("这是test_demo02") assert 1 == 1
运行结果为:
补充:
pytest中,pytest.xfail()方法也可以将用例标记为失败。
语法:pytest.xfail(reason: str = "")
。
举个小例子,比如断言时,断言失败,我们就标记为xfail。
import pytest class TestDemo(): def test_001(self): # 断言是否相等 except_result = 'hello' real_result = 'hello world' if except_result == real_result: print('断言成功') else: pytest.xfail('断言失败,标记为xfail') def test_002(self): # 断言包含或不包含 assert 'hello' in 'hello world' print('这是test_002')
运行结果为: