TT Lab
开始
学习 学习路径 课程

测试工具实战

用边界值测试发现真实缺陷

在 TT Lab 中继续学习

目标

对费用函数的正确实现和八种有缺陷的实现,运行同一组 pytest 测试。

为什么重要

一次正常请求成功,并不能保证边界值和故障恢复也没有问题。本实验先为每个函数的契约编写小型实现或测试,再通过真实运行把它们串起来。评分不会只看代码是否存在或报告中的措辞,而是检查结果、异常和保存的状态。请保留前面步骤的代码,继续进行下一步。

步骤

  1. 在 /root/work/test-boundaries-lab/test_service.py 中编写 pytest 测试,断言 price(0) 恰好为 0。只调用函数,或只检查结果是否为 int,都不够。第一次准备使用下面的命令。
mkdir -p /root/work/test-boundaries-lab
cp /opt/fixtures/practice_depth/test-boundaries-lab/* /root/work/test-boundaries-lab/
cd /root/work/test-boundaries-lab
  1. 在 /root/work/test-boundaries-lab/test_service.py 中测试 price(1) 的金额是否为 350。保留原有的 0 件测试。
  2. 在 /root/work/test-boundaries-lab/test_service.py 中测试 price(9) 是否为 3150。必须能检出从 9 件起就错误打折的实现。
  3. 在 /root/work/test-boundaries-lab/test_service.py 中测试 price(10) 是否为 3000。用它抓住“10 件时不打折”的 > 条件错误。
  4. 在 /root/work/test-boundaries-lab/test_service.py 中测试 price(11) 是否为 3300。用它检出把整个折扣区间固定返回 3000 韩元的实现。
  5. 在 /root/work/test-boundaries-lab/test_service.py 中用 pytest.raises 确认 price(100) 为 30000,且 price(101) 抛出 ValueError。
  6. 在 /root/work/test-boundaries-lab/test_service.py 中测试 price(-1) 是否抛出 ValueError。不要把返回负数费用当作正常处理。
  7. 在 /root/work/test-boundaries-lab/test_service.py 中添加参数化测试,确认 True、False、1.0、'1'、None 全部抛出 TypeError。尤其要抓住把 bool 当作 int 接受的缺陷。

参考

拦住空订单的最低费用

在 /root/work/test-boundaries-lab/test_service.py 中编写 pytest 测试,断言 price(0) 恰好为 0。只调用函数,或只检查结果是否为 int,都不够。第一次准备使用下面的命令。

mkdir -p /root/work/test-boundaries-lab
cp /opt/fixtures/practice_depth/test-boundaries-lab/* /root/work/test-boundaries-lab/
cd /root/work/test-boundaries-lab

想一想那种“连空订单也收取 350 韩元”的缺陷。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/01-contract.sh 直接复现。保存文件后再运行一次。

确认最小的有效数量

在 /root/work/test-boundaries-lab/test_service.py 中测试 price(1) 的金额是否为 350。保留原有的 0 件测试。

只检查“价格为正数”,会放过收取 400 韩元的 bug。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/02-contract.sh 直接复现。保存文件后再运行一次。

抓住折扣之前的边界

在 /root/work/test-boundaries-lab/test_service.py 中测试 price(9) 是否为 3150。必须能检出从 9 件起就错误打折的实现。

折扣开始之前的那个值,与普通的中间值起的作用不同。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/03-contract.sh 直接复现。保存文件后再运行一次。

包含折扣的起点

在 /root/work/test-boundaries-lab/test_service.py 中测试 price(10) 是否为 3000。用它抓住“10 件时不打折”的 > 条件错误。

重新读一遍策略表,看看这个条件是否应当在边界上为真。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/04-contract.sh 直接复现。保存文件后再运行一次。

不要把折扣金额当成常量

在 /root/work/test-boundaries-lab/test_service.py 中测试 price(11) 是否为 3300。用它检出把整个折扣区间固定返回 3000 韩元的实现。

只检查边界上的一个点,折扣区间的斜率即使错了也发现不了。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/05-contract.sh 直接复现。保存文件后再运行一次。

同时验证上限的内外两侧

在 /root/work/test-boundaries-lab/test_service.py 中用 pytest.raises 确认 price(100) 为 30000,且 price(101) 抛出 ValueError。

把最大的合法值和紧随其后的非法值当作一对来处理。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/06-contract.sh 直接复现。保存文件后再运行一次。

不要把负数输入变成成功

在 /root/work/test-boundaries-lab/test_service.py 中测试 price(-1) 是否抛出 ValueError。不要把返回负数费用当作正常处理。

如果在 try/except 里什么都不做,即使没有抛出异常,测试也可能通过。请使用 pytest.raises。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/07-contract.sh 直接复现。保存文件后再运行一次。

拒绝 bool 和形似数字的字符串

在 /root/work/test-boundaries-lab/test_service.py 中添加参数化测试,确认 True、False、1.0、'1'、None 全部抛出 TypeError。尤其要抓住把 bool 当作 int 接受的缺陷。

要包含能体现 type(x) 与 isinstance(x, int) 差异的输入。测试必须调用公开函数,而不是实现源码。

评分可以用 bash /opt/lab/checks/test-boundaries-lab/08-contract.sh 直接复现。保存文件后再运行一次。