Python assert 练习:用断言测试函数
断言是你对程序做出的声明。声明为假时,Python 会抛出 AssertionError 并停止当前路径。只要不把它和输入校验混为一谈,assert 就是很好的教学和测试工具。
写出预期结果
assert add(2, 3) == 5 把预期变成可执行代码。实现变化时,检查会在确切的行失败。每个断言只关注一个行为,失败原因就更容易诊断。
def add(a, b):
return a + b
assert add(2, 3) == 5
print("ok")一个清楚的声明
加上说明差距的消息
断言失败时会显示逗号后的消息。写清预期值,必要时也写实际输入。避免只写 failed 之类的消息,它只是重复异常已经表达的内容。
def double(n):
return n * 2
try:
assert double(3) == 7, "double(3) should be 6"
except AssertionError as error:
print(error)有用的失败消息
捕获失败来研究它
AssertionError 是普通异常,小示例可以捕获它并打印消息。真实测试中应让失败传给测试运行器。把失败藏起来,就失去了检查的意义。
try:
assert 1 == 2, "one is not two"
except AssertionError as error:
print(error)查看失败,而不是掩盖它
同时测试正常值和边界值
对 2 和 3 正常的函数,遇到 0、空列表或负数仍可能出错。每组小测试至少加一个边界情况。断言让这些情况成为代码的一部分,而不是一句注释。
def total(values):
return sum(values)
assert total([]) == 0
assert total([1, 2, 3]) == 6
print("boundary and normal cases pass")加入一个边界情况
知道 assert 不适合什么
不要用 assert 校验密码、权限或用户输入。Python 的 -O 参数会移除 assert 语句,用这种方式写的安全检查可能直接消失。校验时应抛出 ValueError 或自定义异常。
def positive(n):
if n <= 0:
raise ValueError("n must be positive")
return n
print(positive(3))校验应该写在 if 里
你的练习清单
- 测试和内部不变量使用 assert。
- 加上说明预期行为的消息。
- 至少测试一个边界情况。
- 只有研究失败时才捕获 AssertionError。
- 用户输入校验用明确异常,不要用 assert。
常见问题
assert 可以被禁用吗?
可以。用 -O 运行 Python 会移除 assert 语句,所以不能用它保护安全或必需校验。
assert 抛出什么异常?
AssertionError。可选消息会成为异常文本。
每个函数都应该写断言吗?
不需要。把断言放在假设重要、失败必须明显的地方,尤其是测试和内部辅助函数。
练习断言
12 道题,覆盖 assert、消息、AssertionError、边界情况和输入校验。
继续阅读: