文章目录
- Pytest assert 简介
- assert 应用场景
- assert 测试结果
- assert 基本用法
- Pytest raises 简介
- raises 用途和作用
- raises 与 try 的区别
- python代码中使用try
- 在测试用例中使用try
- 使用pytest.raises()
Pytest assert 简介
断言(Assertion)
是编程中的一个基本概念,用于验证程序中的某个条件是否为真。在单元测试中,断言是验证代码行为是否符合预期的主要手段。如果断言的条件不满足(即为假),则测试失败,通常会导致程序抛出
AssertionError
异常。在
pytest
测试框架中,assert
是进行断言的核心机制;它依赖于Python
内置的assert
关键字。
当assert
语句中的表达式求值为False
时,测试将失败,并且程序执行将立即停止,assert
语句之后的代码将不会被执行。
assert 应用场景
pytest的assert断言在各种测试场景中都有广泛应用,包括但不限于:
- 函数或方法的返回值验证;
- 数据结构或对象状态的验证;
- 异常处理的验证;
- 接口的响应验证;
- 数据库操作结果的验证等。
assert 测试结果
当
pytest
执行测试用例时,它会根据assert
断言的结果来判断测试是否通过。
- 如果断言成功,则测试通过;
- 如果断言失败,则测试失败,终止后续代码的执行,并显示相应的错误信息。
assert 基本用法
使用语法:
assert
表达式assert
表达式, 描述- 如果断言失败,描述作为AssertionError的内容展示
示例代码
def add(x, y):
return x + y
def test_case_01():
print("进入测试函数")
assert add(2, 3) == 5
print("断言成功")
def test_case_02():
print("进入测试函数")
assert add(2, 3) == 10
print("断言失败") # 不会被执行
def test_case_03():
print("进入测试函数")
# 带描述性错误消息的用法
assert add(2, 3) == 10, "结果与预期不符"
print("断言失败") # 不会被执行
执行结果
Pytest raises 简介
pytest.raises()
是一个内建于pytest
测试框架中的上下文管理器;它允许我们在编写单元测试时断言某个特定的异常会被抛出。
当代码块中抛出了预期的异常时,
pytest.raises()
会捕获该异常,并且测试会继续进行。如果没有抛出异常,或者抛出了不同类型的异常,测试将会失败。
raises 用途和作用
- 断言异常类型:我们可以使用
pytest.raises()
来断言某个函数或方法会抛出特定类型的异常。- 获取异常细节:通过
pytest.raises()
,我们可以访问被捕获的异常实例,从而获取异常的详细信息,比如异常类型、异常信息(message)等。- 匹配异常信息:
pytest.raises()
支持使用match
参数来指定一个正则表达式,该表达式用于匹配异常信息。如果异常信息符合该正则表达式,测试会通过。- 异常处理后的代码不会执行:当
pytest.raises()
捕获到异常后,该异常之后的代码块将不会执行。这与标准的try...except
块的行为是一致的。
raises 与 try 的区别
直接使用 try…except 捕捉异常的区别:
- 断言性:
pytest.raises()
是一个断言,它明确指出了测试失败的条件,即没有抛出预期的异常或抛出了错误的异常类型。而try...except
只是简单地捕获异常,并不直接表明测试是否通过。- 报告:
pytest
会自动报告哪些测试失败,并显示失败的原因,包括未抛出的异常或异常类型不匹配等。而使用try...except
,你可能需要手动添加更多的逻辑来报告测试状态。- 可读性:
pytest.raises()
的语法更加清晰,它直接指出了期望抛出的异常类型,以及可能的异常信息。而try...except
需要更多的上下文来理解测试的意图。- 灵活性:
pytest.raises()
提供了更多的选项,比如match
参数可以用来匹配异常信息。而try...except
则需要额外的逻辑来处理这些信息。- 集成性:
pytest.raises()
与pytest
测试框架完美集成,你可以利用pytest
的其他功能,如参数化测试、测试固件(fixtures)等。而try...except
只是一个 Python 的基础语法结构,没有与测试框架的深度集成。
python代码中使用try
示例代码
print("测试开始")
try:
a = int(input("请输入被除数:"))
b = int(input("请输入除数:"))
res = a / b
print(f"res={res}")
except ValueError as e1:
print("格式异常:", e1)
except ZeroDivisionError as e2:
print("被除数异常:", e2)
except ArithmeticError as e3:
print("算数异常:", e3)
except Exception as e4:
print("意外异常:", e4)
print("测试完成")
执行结果
在测试用例中使用try
示例代码
def test_case_01():
print("测试开始")
try:
a = int(input("请输入被除数:"))
b = int(input("请输入除数:"))
res = a / b
print(f"res={res}")
except ValueError as e1:
print("格式异常:", e1)
except ZeroDivisionError as e2:
print("被除数异常:", e2)
except ArithmeticError as e3:
print("算数异常:", e3)
except Exception as e4:
print("意外异常:", e4)
print("测试完成")
执行结果
使用pytest.raises()
示例代码
import pytest
# 捕捉指定异常:哪怕with下面的代码发生了ZeroDivisionError类型的异常,整个用例不会认为是异常用例,认为是正常的
def test_case_01():
with pytest.raises(ZeroDivisionError):
res = 10 / 0
print('结果:', res) # 上述代码抛出异常后,不会继续执行后续代码
# 捕捉多个异常,如果实际代码中抛出的异常是其中一个则认为测试用例通过
def test_case_02():
with pytest.raises(expected_exception=(ValueError, ZeroDivisionError)):
raise ZeroDivisionError("除数为0")
# 利用match参数使用正则表达式
def test_case_03():
with pytest.raises(ValueError, match='自定义错误'):
raise ValueError("自定义错误:xxxx发生了意外")
# 利用match参数使用正则表达式,如果异常信息中包含xxxx则认为测试用例通过
def test_case_04():
with pytest.raises(ValueError, match=r'.*xxxx.*'):
raise ValueError("自定义错误:xxxx发生了意外")
# 没有预期的异常就报错,同时,后面的代码不会被执行
def test_case_05():
with pytest.raises(ZeroDivisionError):
print("这句代码会被执行")
raise ValueError("数据异常")
print("这句代码不会被执行")
# 获取捕获的异常的细节(异常类型, 异常信息)
def test_case_06():
with pytest.raises(ValueError) as exc_info:
raise ValueError("数据异常")
assert exc_info.type is ValueError
assert exc_info.value.args[0] == "数据异常xxx"
执行结果