用途
本技能用于指导为 Flutter 应用编写 Patrol 端到端(E2E)测试,覆盖测试编写流程、Patrol API 使用、断言规则、原生对话框处理以及测试键(test key)约定。
编写新测试的操作顺序
- 检查现有测试代码,找出可复用的函数。
- 思考现有函数是否可以在保持其既有用法的前提下调整,以同时满足新测试。
- 为所需元素分配测试键(若尚未分配)。
- 开始编写测试:复用现有函数,并将新测试步骤放入新的测试文件。
- 直接在测试文件中编写 Patrol 动作,不要创建新方法。
- 开发过程中频繁运行测试,不要等整个测试写完。每完成一组逻辑步骤就运行一次,以便尽早发现失败。
- 完整测试通过后,将新代码重组为可复用函数。
- 重组后重新运行测试,确认仍然通过。
Patrol MCP 使用
- 使用
patrol-run({ "testFile": "patrol_test/your_test.dart" })运行测试并等待完成。若无会话运行,则用指定测试文件启动新会话;若已有会话运行,则自动重启当前测试。 - 使用
patrol-screenshot({ "platform": "android" })或patrol-screenshot({ "platform": "ios" })截取屏幕,用于调试测试失败。 - 使用
patrol-quit({})优雅退出会话。 - 使用
patrol-status({})查看当前状态和最近输出。 - 使用
patrol-native-tree({})获取当前原生 UI 树层级,用于编写原生交互以及与测试应用之外的其他应用交互。
Patrol 测试规则
Patrol API
- 任何直接使用 Patrol API(
$()、.scrollTo()、.tap()、.enterText()、.waitUntilVisible()等)的文件都应导入'package:patrol/patrol.dart'。 - 实现测试动作前务必先检查 Patrol API:在代码库中搜索现有 Patrol API 使用模式;检查
$.platformAPI 中是否有对应动作;若代码库中找不到该方法,查阅 https://patrol.leancode.co/ ;确认正确的 API 方法后再实现。 - 实现测试动作前务必先检查
$.platform方法。 - 不要使用 flutter_test 包,只使用 Patrol API。
- 单个测试只通过 Patrol MCP 服务器运行,全部测试使用 patrol test 运行。绝不使用 flutter test 命令。
- 不要自行编写
patrolSetUp和patrolTearDown方法。
动作规则
- 不要在 tap、scrollTo 和 enterText 前后使用
$.pump、waitUntilVisible、waitUntilExists等等待方法,Patrol 会自动处理。仅在测试末尾使用这些方法。 - 查找 widget 时只使用键(key)。
- 除非绝对必要,不要编写 try catch 块。
- 写完测试后通过 MCP 服务器运行验证,若失败则修复。
- 若测试因找不到元素而失败,检查应用代码中是否需要滚动到该元素,并相应调整测试。
断言规则
- 不要在动作之后写断言,而在测试末尾写断言。
- 优先在测试末尾使用
waitUntilVisible作为断言。 - 仅当
waitUntilVisible不够用时才使用expect()进行断言。
原生对话框处理
- 务必处理流程中出现的原生对话框:在触发对话框的动作之后立即处理。
- 对于原生权限,优先使用
$.platform.mobile.grantPermissionWhenInUse而非$.platform.mobile.tap。
测试键(Test Keys)
- 只为参与测试的 widget 分配键。
- 只向现有 widget 添加 key 参数。
- 绝不更改 widget 签名。
- 绝不重构现有代码结构。
- 绝不在应用中硬编码键,必须使用应用与测试共享的 keys 文件中的键。
- 绝不在应用中创建新 widget。
- 绝不创建未分配给 widget 的键。
- 始终确保每个键值唯一。
- 始终按键的字母顺序排序。
- 将 key 作为 widget 构造函数的第一个参数添加。
- 若 widget 不唯一(例如由列表生成),使用参数化键。
- 若已存在枚举或 DTO,始终优先将其作为参数使用。
- 使用现有 widget 属性作为参数化键的参数。
- 绝不在应用中使用参数化键却在 keys 文件中使用固定值(反之亦然)。
- 绝不创建辅助方法,改用参数化键。
- 当 widget 由现有枚举或 DTO 生成时,始终使用以这些枚举/DTO 值作为参数的参数化键。
使用独立键的场景:
- widget 是硬编码且在编译时已知。
- widget 具有独特且有意义的名称。
使用参数化键的场景:
- widget 由动态数据生成。
- widget 由 DTO 或枚举生成。
- widget 数量可变或很多。
- widget 在循环中或由列表生成。
适用场景
适用于为 Flutter 应用编写和维护 Patrol E2E 测试,尤其是需要复用现有测试函数、处理原生对话框与权限、以及通过 Patrol MCP 频繁运行和调试测试的开发流程。
限制
资料未提供关于收费、价格、平台支持范围、测试执行性能或效果保证等信息。