3 个命令上手 Maestro AI:发版前自动揪出 UI 缺陷,还能顺手提取屏幕文本
【免费下载链接】MaestroPainless E2E Automation for Mobile and Web项目地址: https://gitcode.com/GitHub_Trending/ma/Maestro
发版前最耗时的环节之一,是人工逐屏看截图:找文字溢出、找布局错位、找颜色反了的地方。Maestro 的 AI 能力可以把这一步半自动化——在测试脚本里加一条命令,截屏直接送去做 UI 缺陷检测,返回结构化的问题列表;同一套入口还支持把屏幕上的文本按自然语言查询提取出来存成变量。这篇文章带你走通 Maestro AI 这三件事:assertNoDefectsWithAI、assertWithAI、extractTextWithAI。
最小可跑示例:一条命令检测整屏 UI 缺陷
先给最短主流程。导出云端 key(占位符,换成你自己的):
export MAESTRO_CLOUD_API_KEY="your-cloud-api-key" export MAESTRO_CLI_AI_KEY="sk-your-llm-key"在 Maestro 测试脚本末尾加一条断言:
appId: com.example.app --- - launchApp - assertNoDefectsWithAI跑maestro test flow.yaml。assertNoDefectsWithAI会自动截取当前整屏(未压缩的原图字节),交给云端分析;没有缺陷就静默通过,有缺陷则这一步直接失败,报告里打印每条缺陷的reasoning。这就是它能解决的问题:截图进,缺陷列表出,不用人肉盯像素。
怎么调用 Maestro AI 的三个命令
assertNoDefectsWithAI:怎么调用、返回什么
解决"整屏有没有视觉问题"。脚本里不需要传任何路径,命令自己负责截图——你只需要保证此刻屏幕上是你想检查的页面。
- launchApp - tapOn: "首页" - assert: "余额显示区" - assertNoDefectsWithAI底层走 maestro-ai/ 里的AIPredictionEngine.findDefects(screen: ByteArray),输入是截图字节数组,输出是List<Defect>,每个Defect只有两个字段:category和reasoning。拿到非空列表后,Orchestra 会抛AssertionFailure,失败消息形如Found 2 possible defects: - ...,失败截图会被存进 debug 产物目录。
解读:它没有坐标、没有严重度分级,给的是分类加自然语言理由;定位靠你自己回看产物里的截图。
assertWithAI:怎么把一句自然语言断言跑起来
解决"某个该出现的内容出现了没有",比如验证码输入框、活动横幅这类精确文本匹配不好写的界面。命令接收一个assertion字符串,把截图和这句话一起送云端判断。
- launchApp - tapOn: "登录" - assertWithAI: "屏幕上显示了用于输入验证码的输入框"对应源码里performAssertion(screen, assertion)的返回是Defect?:null表示断言通过,非空时defect.reasoning就是失败原因,同样会抛出AssertionFailure。
解读:断言写得越具体越稳。"页面显示验证码输入框"比"页面正常"有用得多,后者会让模型给出含糊的判定。
extractTextWithAI:提取文本的查询参数怎么写
解决"屏幕上有文字,但我拿不到它的确切值"——WebView 里渲染的数字、Canvas 上的余额、动态生成订单号都属于这类。命令接收query(自然语言)和outputVariable(变量名)。
- extractTextWithAI: query: "页面上显示的订单总金额,只要数字" outputVariable: orderTotal - assert: text: "确认支付" visible: true - assertVariable: "orderTotal 不为空"返回是一个纯字符串,存进outputVariable后给后续步骤用,比如tapOn或再套一层正则断言。失败点很直接:key 没配会抛CloudApiKeyNotAvailable;查询太模糊,返回的字符串可能是整段无关文案。
把三个命令串进发版前的回归流程
三者有明确的先后依赖:先"找茬",再"确认",最后"取值"。
- launchApp - assert: "首页" - assertNoDefectsWithAI # 第一关:整屏无视觉缺陷 - assertWithAI: "顶部导航栏包含'我的订单'入口" # 第二关:关键入口存在 - extractTextWithAI: query: "当前账户余额,只要数字" outputVariable: balance - assertVariable: "balance 只包含数字和小数点" # 第三关:取到的值格式正确先跑assertNoDefectsWithAI是为了把纯视觉问题和内容缺失分开:第一关挂了,说明是渲染层面的回归;第一关过了、第二关挂了,说明内容本身没到位。最后一步只在前两步都过的前提下才有意义——从错屏里提取文本没有价值。把这条链放在登录页、首页、订单页等核心页面的用例末尾,就能在常规 E2E 之外多筛出一层视觉回归。
避坑与调优清单
- 两个环境变量一个都不能少:
MAESTRO_CLOUD_API_KEY驱动云端缺陷/文本接口,MAESTRO_CLI_AI_KEY(OpenAIsk-...或 Anthropicsk-ant-api-...)在 demo 应用里选择 LLM 模型。缺前者时执行到命令直接抛CloudApiKeyNotAvailable;缺后者 demo 会报OpenAI API key is not provided。 - 截图是全屏原图,不是压缩图:
takeScreenshot(compressed = false)的字节直接上传,分辨率越高传得越多。弱网环境先修网络再怀疑 AI;接口内部超时是连接 10 秒、请求 60 秒,60 秒后按失败处理。 - 断言查询写"可验证的描述":
assertWithAI和extractTextWithAI的 prompt 都写具体对象加判断条件("显示用于输入验证码的输入框"),模糊措辞会让reasoning变得不可解释。 - 提取结果是字符串,格式校验自己加:
extractTextWithAI不做类型判断,想确认余额是1234.56这种形态,用后续的assertVariable加正则,别指望查询语句保证格式。 - AI 判定允许出错,流程上留复核口:失败信息的 debug 提示会建议你核对 debug 产物里的截图。批量跑时把 AI 失败的用例单独拉出来人工过一遍,比整体重跑省事。
- 并行注意限流:官方 demo(maestro-ai/README.md)的
--parallel选项本身就标注了 "May get rate limited",核心页用例多时串行跑 AI 步骤更稳。
边界与下一步
说清前提:三个命令都依赖 Maestro 云端服务(默认https://api.copilot.mobile.dev,可用MAESTRO_CLOUD_API_URL覆盖),截图字节会上传,涉及敏感数据的界面慎用。它做不了整屏之外的细粒度分析——Defect没有坐标,提取文本也没有区域参数,想只检查局部只能先自己截局部。想继续往下走,两条路:一是读 maestro-ai/README.md 了解 demo 应用的截图命名规则(app_编号_good/bad.png)和模型切换;二是直接看源码入口 maestro-ai/src/main/java/maestro/ai/Prediction.kt 和同目录的ApiClient.kt,请求体FindDefectsRequest里assertion字段可空——传了就走断言模式,不传就是纯找缺陷,这就是assertWithAI和assertNoDefectsWithAI的差别来源。
【免费下载链接】MaestroPainless E2E Automation for Mobile and Web项目地址: https://gitcode.com/GitHub_Trending/ma/Maestro
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考