[【原文链接】】(http://blog.redrose2100.com/article/180)
一、直接使用python中的assert断言语句
(1)pytest 中可以直接使用python的assert断言语句进行断言
如:
# content of test_assert1.py
def f():
return 3
def test_function():
assert f() == 4
执行结果如下:
$ pytest test_assert1.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
test_assert1.py F [100%]
================================= FAILURES =================================
______________________________ test_function _______________________________
def test_function():
> assert f() == 4
E assert 3 == 4
E + where 3 = f()
test_assert1.py:6: AssertionError
========================= short test summary info ==========================
FAILED test_assert1.py::test_function - assert 3 == 4
============================ 1 failed in 0.12s =============================
二、assert 可以自定义断言信息
test_demo.py代码如下:
def test_func():
a=10
assert a==1, f"a的值应该等于1,当前为:{a}"
执行结果如下,当断言错误时,可以显示自定义信息
$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item
test_demo.py F
=============================================================================== FAILURES ===============================================================================
______________________________________________________________________________ test_func _______________________________________________________________________________
def test_func():
a=10
> assert a==1, f"a的值应该等于1,当前为:{a}"
E AssertionError: a的值应该等于1,当前为:10
E assert 10 == 1
test_demo.py:3: AssertionError
======================================================================= short test summary info ========================================================================
FAILED test_demo.py::test_func - AssertionError: a的值应该等于1,当前为:10
========================================================================== 1 failed in 0.11s ===========================================================================
三、对异常进行断言
(1)对异常类型进行断言
test_demo.py内容如下:
import pytest
def test_zero_division():
with pytest.raises(ZeroDivisionError):
a=1 / 0
执行结果如下,即对异常断言正确
$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item
test_demo.py .
========================================================================== 1 passed in 0.03s ===========================================================================
(2)对异常信息进行断言
test_demo.py内容如下:
import pytest
def test_recursion_depth():
with pytest.raises(RuntimeError) as excinfo:
def f():
f()
f()
assert "maximum recursion" in str(excinfo.value)
执行结果如下:
$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item
test_demo.py .
========================================================================== 1 passed in 0.02s ===========================================================================
(3)通过如下方式可以同时断言异常类型以及异常信息的内容,同时,match可以直接使用正则匹配
import pytest
def myfunc():
raise ValueError("Exception 123 raised")
def test_match():
with pytest.raises(ValueError, match=r".* 123 .*"):
myfunc()
执行结果如下:
$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item
test_demo.py .
========================================================================== 1 passed in 0.02s ===========================================================================
(4)还可以通过pytest.raise对一个函数进行检查可能出现的异常,如下格式,会执行func函数,并将args和*kwargs传入func函数,然后判断此时func中报出的异常是否与第一个参数异常一致,如果一致就通过,如果不一致就失败
pytest.raises(ExpectedException, func, args, *kwargs)
test_demo.py内容如下:
import pytest
def myfunc(a,b):
c=a/b
def test_01():
pytest.raises(ZeroDivisionError,myfunc,1,0)
def test_02():
pytest.raises(TypeError,myfunc,1,"hello")
执行结果如下:
$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 2 items
test_demo.py ..
========================================================================== 2 passed in 0.02s ===========================================================================
四、标记用例失败
当功能尚未实现等场景下,可以通过xfail指定用例为xpass状态,如下,表示这个用例不会去执行,直接标记为xpass状态
import pytest
@pytest.mark.xfail(reason="功能尚未实现")
def test_func():
assert 1==2
执行结果如下:
$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item
test_demo.py x
========================================================================== 1 xfailed in 0.06s ==========================================================================
五、重写比较运算断言异常信息
可以通过在conftest.py中重写pytest_assertrepr_compare来自定义断言字符串打印
如下,重写了等号判断的断言信息
# content of conftest.py
from test_foocompare import Foo
def pytest_assertrepr_compare(op, left, right):
if isinstance(left, Foo) and isinstance(right, Foo) and op == "==":
return [
"Comparing Foo instances:",
" vals: {} != {}".format(left.val, right.val),
]
测试脚本
# content of test_foocompare.py
class Foo:
def __init__(self, val):
self.val = val
def __eq__(self, other):
return self.val == other.val
def test_compare():
f1 = Foo(1)
f2 = Foo(2)
assert f1 == f2
执行结果如下:
$ pytest -q test_foocompare.py
F [100%]
================================= FAILURES =================================
_______________________________ test_compare _______________________________
def test_compare():
f1 = Foo(1)
f2 = Foo(2)
> assert f1 == f2
E assert Comparing Foo instances:
E vals: 1 != 2
test_foocompare.py:12: AssertionError
========================= short test summary info ==========================
FAILED test_foocompare.py::test_compare - assert Comparing Foo instances:
1 failed in 0.12s