SuperAPI AI 工具集

patrol-write-test

测试与质量

查看项目

更新于 10-15 14:31

技能介绍

用途

本技能用于指导为 Flutter 应用编写 Patrol 端到端(E2E)测试,覆盖测试编写流程、Patrol API 使用、断言规则、原生对话框处理以及测试键(test key)约定。

编写新测试的操作顺序

  1. 检查现有测试代码,找出可复用的函数。
  2. 思考现有函数是否可以在保持其既有用法的前提下调整,以同时满足新测试。
  3. 为所需元素分配测试键(若尚未分配)。
  4. 开始编写测试:复用现有函数,并将新测试步骤放入新的测试文件。
  5. 直接在测试文件中编写 Patrol 动作,不要创建新方法。
  6. 开发过程中频繁运行测试,不要等整个测试写完。每完成一组逻辑步骤就运行一次,以便尽早发现失败。
  7. 完整测试通过后,将新代码重组为可复用函数。
  8. 重组后重新运行测试,确认仍然通过。

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 使用模式;检查 $.platform API 中是否有对应动作;若代码库中找不到该方法,查阅 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 频繁运行和调试测试的开发流程。

限制

资料未提供关于收费、价格、平台支持范围、测试执行性能或效果保证等信息。