pytest的断言管理

1、什么是断言

pytest的断言使用python中的assert函数。断言内容为一个表达式,只要表达式的最终结果为True,那么断言通过,用例执行成功,否则用例执行失败。

2、断言的分类与使用

pytest使用python的assert函数,支持显示常见的python子表达式的值,包括:调用、属性、比较、二进制和一元运算符。
也就是说,python语言有多少种判断,assert就有多少种断言,包括断言函数返回值是否相等、断言表达式执行后的结果是否正确、各种不同比较运算符的断言、比较各种数据类型(字符串、列表、字典、集合)不同的断言。

2.1 验证函数返回值是否相等

断言函数返回了某个值:

def test():
	return 3

# 断言test()函数返回值是否等于4
det test_f():
	assert test() == 4

2.2 表达式断言

通过表达式运算后的结果进行真假判断。

a = 5
# 如果值是偶数,断言成功;如果是奇数,则断言失败
def test_exp():
	assert a%2 == 0

2.3 比较类型断言

2.3.1 相同数据类型的比较断言

比较类型断言包括相等、不等、包含、不包含、真、假等判断,以及长列表中的详细断言。

# 比较
def test_1():
	assert 1<3
	assert 100>90
	assert 10==10

# 真假
def test_true():
	assert (100>90) is True

# 包含
def test_in_dict():
	assert "test" in "test teacher"

# 不包含
def test_in_dict():
	assert "hello" not in "test teacher"

总结:

assert xx:判断xx为真
assert not xx:判断xx不为真
assert a in b:判断b包含a
assert a==b:判断a等于b
assert a!=b:判断a不等于b

2.3.2 不同数据类型的比较断言

对于不同数据类型进行比较断言时,直接使用assert语句,可能会导致错误或者不直观的测试结果。

例如:一个整数和一个字符串,直接使用assert,会提示TypeError

那么针对这种情况,如何处理呢?以下有4种处理方式:

2.3.2.1 使用pytest.raises捕获异常
import pytest
 
def test_compare_different_types():
    with pytest.raises(TypeError):
        assert 1 == "1"  # 直接比较整数和字符串
2.3.2.2 使用pytestassert扩展

从pytest 6.0版本开始,引入了几个用于类型检查的断言,例如assert.is_instance()assert.is_not_instance(),这使得类型检查更加直观和灵活。

def test_compare_types():
    value = 1
    assert isinstance(value, int)  # 使用内置的isinstance检查类型
2.3.2.3 自定义比较函数
def compare_types(expected, actual):
    if not isinstance(expected, type(actual)):
        raise TypeError(f"Expected type {type(expected)}, but got {type(actual)}")
    return expected == actual
 
def test_custom_compare():
    assert compare_types(1, "1")  # 自定义比较函数抛出TypeError
2.3.2.4 使用第三方库

还有一些第三方库,如hypothesis,提供了强大的数据生成和属性测试功能,可以用来测试不同类型的数据。

from hypothesis import given, strategies as st
import pytest
 
@given(st.integers(), st.text())
def test_hypothesis_type_comparison(x, y):
    with pytest.raises(TypeError):
        assert x == y  # 使用Hypothesis测试不同类型的数据比较

总结:

选择哪种方法取决于你的具体需求和测试场景。
对于简单的类型检查和预期异常捕获,使用pytest.raises或内置的isinstance()通常是足够的。
对于更复杂的测试逻辑,自定义函数或使用第三方库可能更合适。

2.4 触发一个指定异常的断言

在pytest中,如果你想要测试某个代码块是否抛出了指定类型的异常,你可以使用pytest的内置断言raises
这个断言允许你指定一个异常类,并确保当你的测试运行时,该代码块确实抛出了你指定的异常类型。
示例1:测试代码块是否抛出异常

import pytest

# 假设有一个函数
def devide(x, y):
	return x/y

 # 验证函数是否在y为0时抛出ZeroDivisionError
def test_divide_by_zero():
    with pytest.raises(ZeroDivisionError):
        divide(1, 0)

示例2:测试代码块抛出指定异常并捕获异常对象

def test_divide_by_zero_and_capture_exception():
    with pytest.raises(ZeroDivisionError) as e:
        divide(1, 0)
    assert str(e.value) == "division by zero"  # 根据Python版本的不同,错误消息可能不同

示例3:测试代码块抛出不同类型的异常
如果想要测试代码块抛出不同类型的异常,可以通过传递一个元组给raises来实现

def test_divide_and_capture_multiple_exceptions():
# 如果divide('a', 'b')抛出了ZeroDivisionError或TypeError中的任何一种,测试就会通过
    with pytest.raises((ZeroDivisionError, TypeError)):
        divide('a', 'b')  # 这会引发TypeError,因为不能将字符串用作除数

注意:

1、确保测试的函数名以test_开头
2、使用with pytest.raises(),确保代码确实会抛出异常。如果代码没有抛出异常,而测试通过,则需要重新检查你的代码逻辑或者测试用例编写逻辑

3、为失败断言添加自定义说明

使用pytest测试时候,有时候标准的断言assert 可能不足以清晰地说明为什么测试失败,为提供更详细的失败信息,可以通过以下几种方式来增加断言。

3.1 使用pytest.fail()

pytest.fail()运行在直接测试红抛出失败,同时可以添加自定义的失败信息。

import pytest

def test():
	if is_false:
		pytest.fail("自定义的失败信息")

3.2 使用assert 并提供额外的信息

python3.5开始,assert语句支持一个可选的消息参数,这可以在断言失败时提供额外信息。

def test():
	assert condition, "自定义的失败信息"

3.3 使用pytestfail fixture

在pytest中定义一个fail的fixture,并在其中使用pytest.fail()来抛出自定义失败的信息。

import pytest

@pytest.fixture
def fail():
	return pytest.fail

def test(fail):
	if is_false:
		fail("自定义的失败信息")

3.4 使用pytestraises 上下文管理器

使用raises 上下文管理器,可以在某个代码块上抛出异常

def test_example():
    with pytest.raises(Exception, match="自定义的异常信息"):
        some_code_that_should_raise()

3.5 使用pytestassert 替代品pytest.raises和match参数

在某个代码块抛出特定类型的异常,可以使用pytest.raises和match参数。

def test_example():
    with pytest.raises(ValueError, match="自定义的错误信息"):
        raise ValueError("自定义的错误信息")

总结:

1、对于简单的断言失败,使用assert 消息参数或者 pytest.fail()
2、处理复杂的异常或验证,使用pytest.raises和match参数会更合适

4、Assert各种类型断言

在Python的pytest测试框架中,有多种方式可以断言(assert)不同类型的条件,以确保代码的正确性。

4.1 基本断言

最基本和常用的断言是assert语句,它用于检查表达式是否为True。

def test_basic_assert():
    x = 5
    assert x == 5, "x should be 5"

4.2 类型断言

可以使用isinstance()函数来检查一个对象的类型。

def test_type_assert():
    x = 5
    assert isinstance(x, int), "x should be an integer"

4.3 集合和列表的断言

对于集合和列表,可以使用in来检查元素是否存在,使用==来比较集合或列表的内容。

def test_collection_assert():
    my_list = [1, 2, 3]
    assert 2 in my_list, "2 should be in the list"
    assert my_list == [1, 2, 3], "The list should be [1, 2, 3]"

4.4 使用pytest内置的断言重写

pytest提供了一些内置的断言重写,使得断言更加丰富和易于理解。

assert与pytest.raises()结合使用来测试异常

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

assert与pytest.approx()结合使用来测试浮点数近似相等

def test_approx():
    assert pytest.approx(1.00001) == 1.0  # 可以容忍一定的浮点数误差

4.5 使用第三方库如numpy的断言工具

如果你在使用numpy数组,可以使用numpy.testing模块中的断言函数。

import numpy as np
from numpy.testing import assert_array_equal, assert_allclose
 
def test_numpy_assert():
    a = np.array([1, 2, 3])
    b = np.array([1, 2, 3])
    assert_array_equal(a, b)  # 检查数组内容是否完全相等
    assert_allclose(a, b)  # 检查数组内容是否在容差范围内近似相等(用于浮点数)

4.6 使用unittest风格的断言(如果需要)

虽然pytest有自己的断言方式,但你也可以在测试函数中使用unittest的断言方法,前提是导入它们。

import unittest
import pytest  # 同时使用pytest框架的好处是无需单独导入unittest模块的断言方法,因为pytest已经提供了类似的机制。但如果你确实需要,可以这样做:
from unittest import TestCase  # 注意:通常不需要这样做,因为pytest有自己的断言方式。这里只是为了展示如何导入。
 
class TestExample(TestCase):  # 使用unittest的风格编写测试类(不常用)
    def test_something(self):
        self.assertEqual(1, 1)  # 使用unittest的assertEqual方法进行断言(通常不推荐)

1、推荐使用pytest自己的断言方式,因为它们更简洁、更易于阅读和理解。例如,使用assert x == y而不是self.assertEqual(x, y)。这样可以使测试代码更加简洁和一致。
2、如果使用第三方库如numpy,则可以使用该库提供的断言工具。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值