在pytest框架中,断言是测试的核心部分。与传统的unittest不同,pytest直接使用Python的assert
语句,并结合智能的错误信息提示,简化了断言的使用
1. 基本断言
直接用assert
语句进行条件判断:
def test_basic():
a = 5
b = 3 + 2
assert a == b # 判断相等
assert a != 6 # 判断不等
assert "hello" in "hello world" # 判断包含
assert not False # 判断布尔值
assert hasattr([], "append") # 判断对象是否有属性
当断言失败时,pytest会输出具体的值差异(如5 != 6
)。
2. 异常断言
使用pytest.raises
捕获并验证代码是否抛出预期异常:
import pytest
def test_exception():
with pytest.raises(ZeroDivisionError):
1 / 0 # 预期抛出ZeroDivisionError
# 捕获异常并检查错误信息
with pytest.raises(ValueError) as excinfo:
int("invalid")
assert "invalid literal" in str(excinfo.value)
3. 浮点数近似比较
使用pytest.approx
处理浮点数精度问题:
def test_float():
assert 0.1 + 0.2 == pytest.approx(0.3) # 默认相对容差
assert 1.001 == pytest.approx(1, abs=0.01) # 指定绝对容差
4. 集合与容器断言
验证列表、字典等容器的内容:
def test_collections():
my_list = [1, 2, 3]
assert 2 in my_list # 包含元素
assert 4 not in my_list # 不包含元素
assert my_list == [1, 2, 3] # 顺序严格匹配
assert set(my_list) == {3, 2, 1} # 忽略顺序(需转为集合)
my_dict = {"name": "Alice", "age": 30}
assert "name" in my_dict # 检查键是否存在
assert my_dict["age"] == 30 # 检查键对应的值
5. 类型与身份断言
验证对象类型或身份:
def test_type():
obj = []
assert isinstance(obj, list) # 类型检查
assert obj is not None # 非空检查
6. 警告断言
使用pytest.warns
检查代码是否触发警告:
import warnings
import pytest
def test_warning():
with pytest.warns(UserWarning):
warnings.warn("Deprecated feature", UserWarning)
7. 文件与目录断言
通过标准库验证文件系统:
import os
def test_file_exists(tmp_path):
file_path = tmp_path / "test.txt"
file_path.write_text("content")
assert os.path.exists(file_path) # 检查文件是否存在
8. 多重断言(需插件)
使用pytest-assume
插件执行多个断言(即使部分失败):
pip install pytest-assume
def test_multiple_assertions():
pytest.assume(1 == 1)
pytest.assume(2 > 3) # 即使失败,后续代码仍执行
pytest.assume("a" in "abc")
优势说明
- 智能错误提示:pytest会自动输出断言失败的详细上下文(如变量值、差异对比)。
- 灵活性:普通
assert
语句覆盖大多数场景,无需记忆特定断言方法。 - 扩展性:通过插件(如
pytest-assume
)可增强断言功能。