pytest学习总结2.2 - 如何在测试中断言?

2.2 如何在测试中编写断言

2.2.1 assert 断言

Pytest允许您使用标准的Python断言来验证Python测试中的期望和值。例如,您可以编写以下内容:

def f():
    return 3

def test_function():
    assert f() == 4
C:\Users\Desktop\python>pytest test_assert1.py
========================================================================================================== test session starts ===========================================================================================================
platform win32 -- Python 3.8.0, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: C:\Users\X21201\Desktop\python
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:5: AssertionError
======================================================================================================== short test summary info =========================================================================================================
FAILED test_assert1.py::test_function - assert 3 == 4
=========================================================================================================== 1 failed in 0.06s ============================================================================================================

2.2.2 断言预期的异常

为了编写关于引发异常的断言,可以使用pytest.raises()作为上下文管理器,对于测试自己的代码故意提高的异常的情况, pytest.raises()可能会更好:

import pytest


def test_zero_division():
    with pytest.raises(ZeroDivisionError):
        1 / 0

如果你需要访问实际的异常信息,你可以使用:

import pytest
def test_recursion_depth():
    with pytest.raises(RuntimeError) as excinfo:
        def f():
            f()
        f()
    print(excinfo.value)
    print(excinfo.type)
    # print(excinfo.traceback)
    assert "maximum recursion" in str(excinfo.value)

您可以将匹配关键字参数传递给上下文管理器,以测试正则表达式在异常的字符串表示形式上是否匹配:

import pytest
def myfunc():
    raise ValueError("Exception 123 raised")
def test_match():
    with pytest.raises(ValueError, match=r".* 123 .*"):
        myfunc()

有一个最小的另一种形式pytest.raises() ,其中您传递一个函数,该函数将与给定的*args**kwargs一起执行,并断言引发了给定的异常:
pytest.raises(ExpectedException, func, *args, **kwargs)
也可以为pytest.mark.xfail指定一个“raises”参数,它检查测试是否以更具体的方式失败,而不是仅仅引发任何异常,将@pytest.mark.xfail与检查函数
一起使用可能对记录未固定的bug(测试描述了“应该”发生什么)会更好:

import pytest
@pytest.mark.xfail(raises=IndexError)
def test_f():
    f()

2.2.3 断言预期警告 【后续内容更新】

2.2.4 断言上下文

Pytest在遇到比较时,非常支持提供对上下文内容的断言。例如:

def test_set_comparison():
    set1 = set("1308")
    set2 = set("8035")
    assert set1 == set2
C:\Users\Desktop\python>pytest test_assert2.py
========================================================================================================== test session starts ===========================================================================================================
platform win32 -- Python 3.8.0, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: C:\Users\X21201\Desktop\python
collected 1 item                                                                                                                                                                                                                          

test_assert2.py F                                                                                                                                                                                                                   [100%]

================================================================================================================ FAILURES ================================================================================================================
__________________________________________________________________________________________________________ test_set_comparison ___________________________________________________________________________________________________________

    def test_set_comparison():
        set1 = set("1308")
        set2 = set("8035")
>       assert set1 == set2
E       AssertionError: assert {'0', '1', '3', '8'} == {'0', '3', '5', '8'}
E         Extra items in the left set:
E         '1'
E         Extra items in the right set:
E         '5'
E         Use -v to get the full diff

test_assert2.py:5: AssertionError
======================================================================================================== short test summary info =========================================================================================================
FAILED test_assert2.py::test_set_comparison - AssertionError: assert {'0', '1', '3', '8'} == {'0', '3', '5', '8'}
=========================================================================================================== 1 failed in 0.07s ============================================================================================================

2.2.5 为失败的断言定义您自己的解释

通过实现pytest_assertrepr_compare钩子,可以添加您自己的详细解释:

# 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
# # 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:", f" vals: {left.val} != {right.val}", ]

2.2.6 断言的详细内容

要报告关于失败的断言的详细信息,可以通过在运行它们之前重写断言语句来实现。重写的断言语句将内省信息放到断言失败消息中,Pytest只重写由其测试收集过程直接发现的测试模块
因此,支持模块中断言本身的测试模块不会被重写。
(1)断言重写磁盘上的缓存文件
Pytest将把重写后的模块写回磁盘以进行缓存。您可以通过将其添加到conftest.py文件的顶部来禁用此行为(例如,以避免在大量移动文件的项目中留下陈旧的.pyc文件):

# content of conftest.py
import sys

sys.dont_write_bytecode = True

(2)禁用断言重写
pytest通过使用导入钩子来编写新的pyc文件来重写导入时的测试模块。大多数情况下,这是透明的。但是,如果您自己使用进口机器,进口钩可能会干扰
禁用所有模块的重写:–assert=plain
通过将字符串添加到其文档字符串中,来禁用对特定模块的重写: PYTEST_DONT_REWRITE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿_焦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值