编写断言
使用assert编写断言
pytest允许你使用python标准的assert表达式写断言;
例如,你可以这样做:
# test_sample.pydef func(x): return x + 1def test_sample(): assert func(3) == 5
如果这个断言失败,你会看到func(3)实际的返回值:
/d/Personal Files/Python/pytest-chinese-doc/src (5.1.2)λ pytest test_sample.py================================================= test session starts =================================================platform win32 -- Python 3.7.3, pytest-5.1.2, py-1.8.0, pluggy-0.12.0rootdir: D:\Personal Files\Python\pytest-chinese-doc\src, inifile: pytest.inicollected 1 itemtest_sample.py F [100%]====================================================== FAILURES ======================================================= _____________________________________________________ test_sample _____________________________________________________ def test_sample():> assert func(3) == 5E assert 4 == 5E + where 4 = func(3)test_sample.py:28: AssertionError================================================== 1 failed in 0.05s ==================================================
pytest支持显示常见的python子表达式的值,包括:调用、属性、比较、二进制和一元运算符等(参考pytest支持的python失败时报告的演示);
这允许你在没有模版代码参考的情况下,可以使用的python的数据结构,而无须担心丢失自省的问题;
同时,你也可以为断言指定了一条说明信息,用于失败时的情况说明:
assert a % 2 == 0, "value was odd, should be even"
编写触发期望异常的断言
你可以使用pytest.raises()作为上下文管理器,来编写一个触发期望异常的断言:
import pytestdef myfunc(): raise ValueError("Exception 123 raised")def test_match(): with pytest.raises(ValueError): myfunc()
当用例没有返回ValueError或者没有异常返回时,断言判断失败;
如果你希望同时访问异常的属性,可以这样:
import pytestdef myfunc(): raise ValueError("Exception 123 raised")def test_match(): with pytest.raises(ValueError) as excinfo: myfunc() assert '123' in str(excinfo.value)
其中,excinfo是ExceptionInfo的一个实例,它封装了异常的信息;常用的属性包括:.type、.value和.traceback;
注意:在上下文管理器的作用域中,raises代码必须是最后一行,否则,其后面的代码将不会执行;所以,如果上述例子改成:
def test_match(): with pytest.raises(ValueError) as excinfo: myfunc() assert '456' in str(excinfo.value)
则测试将永远成功,因为assert '456' in str(excinfo.value)并不会执行;
你也可以给pytest.raises()传递一个关键字参数match,来测试异常的字符串表示str(excinfo.value)是否符合给定的正则表达式(和unittest中的TestCase.assertRaisesRegexp方法类似):
import pytestdef myfunc(): raise ValueError("Exception 123 raised")def test_match(): with pytest.raises((ValueError, RuntimeError), match=r'.* 123 .*'): myfunc()
pytest实际调用的是re.search()方法来做上述检查;并且,pytest.raises()也支持检查多个期望异常(以元组的形式传递参数),我们只需要触发其中任意一个;