用测试提供证据
已完成选择能检出错误行为的检查。审查生成的测试时,要像审查生成的实现一样认真。
检验理解生成的测试将授权函数模拟为始终允许访问。测试通过能证明什么?完成练习
你将学到什么
- 为每项重要要求匹配有意义的检查。
- 区分单元测试、集成测试和端到端测试提供的证据。
- 识别与实现重复同一错误假设的测试。
从要求开始
测试为具体判断提供证据。一次成功的测试运行,不能证明软件的所有属性。要求编写测试前,先明确重要行为,以及每项检查应发现的缺陷。
对于一个虚构的组织数据导出功能,主要要求是数据隔离。组织 A 的用户不得收到组织 B 的记录。只检查下载成功的测试,不能证明满足了这项要求。
要求智能体解释要求与断言之间的关系。这样可以在测试套件变大之前,更容易发现缺失案例。
选择合适的测试范围
单元测试可以快速检查小范围转换。集成测试可以检查组件如何协作。端到端测试可以通过已部署应用或有代表性的应用环境,检查重要的用户操作序列。
选择能够提供所需证据的最小范围。格式化函数不需要针对每个输入都执行完整浏览器测试。授权边界可能需要真实路由和数据访问路径。关键浏览器交互则需要有关实际渲染界面的证据。
| 判断 | 证据示例 |
|---|---|
| CSV 输出正确转义引号 | 在字段中包含引号的单元测试 |
| 其他组织不能读取导出结果 | 经过真实授权流程的集成测试 |
| 键盘用户可以启动导出 | 浏览器测试和人工键盘检查 |
| 导出失败时提供有用错误 | 在相关接口上检查失败路径 |
不存在适用于所有系统的固定测试类型比例。应根据需要发现的故障,以及维护检查的成本来选择。
避免共享同一个错误假设
智能体可能基于同一个误解编写实现和测试。两者可以彼此一致,而要求仍未满足。
假设实现按请求提供的组织 ID 筛选记录。测试为已登录用户和请求使用相同 ID,因此测试通过。缺失的案例是:用户请求另一个组织的 ID。
通过实际可信的身份和授权路径添加该案例。始终返回“允许”的模拟不能证明租户隔离,只能证明授权成功后的行为。
验证测试确实会失败
对于已知缺陷,在隔离分支中针对有缺陷的版本运行新增回归测试。确认它因预期原因失败。然后应用修复并再次运行。
如果测试因为无法加载测试夹具而失败,就还不能作为业务行为的证据。检查失败原因,不要只看退出码。
对于更广泛的修改,变异测试有助于评估特定代码变动是否会导致测试失败。它有成本,也不能代替要求审查。应在额外证据能够支持重要决策时使用。
让证据始终对应当前修改
针对最终修订版本运行相关检查。记录跳过的检查及原因。审查修正之后,早期提交的结果可能不再适用。
让测试易于理解。优先采用清楚的准备步骤和断言,而不是用大型辅助函数隐藏重要条件。如果重复检查增加维护成本,却不能发现不同故障,就移除它们。
审查者应能说明测试证实了什么,以及还有什么不确定。这种解释比庞大的测试数量更有用。
完成练习
选择一个生成的测试。说明它检查的要求。在隔离分支中临时引入相关缺陷。确认测试因预期原因失败,然后恢复代码。记录测试仍未覆盖的范围。
下载工作表(Markdown)取消勾选将删除此浏览器保存的全部进度。
进度保存在此浏览器中。无需账户,不追踪使用情况。
来源与延伸阅读
- Google Engineering Practices: Review tests for useful assertions ↗
- Google Testing Blog: Test scope and feedback ↗