把所有验证都塞进端到端测试,定位失败会很慢;只测 ViewModel,又可能漏掉真实按钮不可点击、错误文本被遮挡等 UI 问题。测试层次应按故障边界选择。
三层各有责任
仓储单元测试验证缓存优先、错误映射、离线队列与版本冲突,使用可控的假时钟和假网络。Widget 测试验证“加载中仍能看旧订单”“空态有创建入口”“权限错误禁用按钮”,注入假的仓储,不依赖真实服务器。集成测试只保留少数关键路径,如登录、创建订单、断网后恢复与再次同步。
| 层次 | 输入 | 最重要的断言 |
|---|---|---|
| 单元 | 延迟、冲突、网络错误 | 状态转换和数据不变量 |
| Widget | 快照与请求状态 | 文案、可访问性和操作入口 |
| 集成 | 真机/模拟器和后端测试环境 | 路由、平台权限与持久化 |
让失败可解释
测试数据固定 ID 与时间,避免用随机值掩盖顺序问题。对于异步页面,明确等待目标状态而不是固定 sleep。截图测试只用于布局稳定的关键状态,不能替代行为断言;字体、系统缩放和平台差异会影响像素结果。
围绕一次转账建立测试组合
转账功能同时包含金额校验、收款人查询、确认页、提交请求和结果页。先把金额范围、币种精度、余额与费用计算留在不依赖 Widget 的纯逻辑层,用单元测试覆盖边界值和舍入规则;这些测试快,适合每次提交执行。随后用 Widget 测试驱动输入错误、加载、确认和失败恢复,注入假的仓库与可控时钟。不要只断言某段文案存在,还应检查提交按钮在请求中禁用、失败后重新启用、旧请求不会污染新表单。
真正的集成测试只覆盖少数关键旅程:登录后进入转账、确认收款人、提交、返回记录。使用受控测试后端或明确标注的模拟环境,测试帐号与数据隔离;不要把真实资金网络当成 CI 依赖。系统键盘、权限弹窗、深链返回和应用进后台,需要在目标平台的真实运行环境再验一次,Widget 测试无法替代它们。
| 层级 | 关键问题 | 示例断言 |
|---|---|---|
| 单元 | 计算规则正确吗 | 货币精度、手续费与边界金额 |
| Widget | 交互状态可恢复吗 | 请求中防重复、错误后可重试 |
| 集成 | 组件协作真实吗 | 一次提交对应一条服务端记录 |
| 设备验收 | OS 行为符合预期吗 | 键盘、后台恢复、弱网 |
防止测试本身掩盖竞态
假仓库应允许手动决定响应顺序,不能总是立即返回成功。至少测试两次提交竞争、离开页面后回包、服务器超时但实际成功,以及重复进入结果页。一次请求是否“成功”应由服务端幂等结果决定,而不是由测试里预设的导航次数猜测。参考:Flutter 测试概览。
参考:Flutter 测试概览。
