首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >自动打包、装机、生成用例、真机回归,AI 测试流水线终于跑通了

自动打包、装机、生成用例、真机回归,AI 测试流水线终于跑通了

作者头像
Bug挖掘机
发布2026-07-23 21:26:00
发布2026-07-23 21:26:00
210
举报
文章被收录于专栏:测试开发基础测试开发基础

大家好,我是洋子

自从去年底转AI测试工程师后,到现在我的工作模式已经有了非常大的转变

除了与RD、PM等协作角色沟通,E2E测试方面还有一部分在人工执行,其他的日常工作已全部交给AI去完成,包括生成功能/接口自动化/UI自动化测试用例,设计技术方案,开发测试工具,理解业务架构等等

这种工作模式已经持续了大半年了,可以说,再让我脱离AI,我都不会干活了

AI目前在团队内部已经完成了单点提效,比如开发用AI 写代码,测试用AI生成测试用例等,但这个过程还是需要人通过Prompt与AI对话来驱动

能不能改造成AI 自动完成上面的工作,人只来做决策,工作流全自动化流转起来

那么,要实现全自动化的前提,就是需要把CI/CD 基建改造成Agent 或者能让Agent 能更方便的调用流水线上的Job,另外就是尽量把工作SOP化成Skill

本文主要跟大家分享两方面

  • 在AI冲击下,目前项目交付模式的变化
  • 我基于Codex+Skill做的测试Agent,整体AI自动化测试工作流是如何进行搭建的

交付模式变化趋势

在开始正题之前,先来回顾一个项目需求交付模式,在2025年以前,每当来了一个新需求,基本上都是人在执行工作

产品经理先写PRD需求文档,UI设计画视觉稿,前后端开发设计技术方案+人工写代码,QA设计测试用例并执行,测试完成后上线

各角色的工作流程都是人来决策+执行

在这里插入图片描述
在这里插入图片描述

从2025年到现在,越来越多团队的工作模式变成了先由AI(如Claude Code、Codex等)来设计方案,人再通过对话的方式来调整方案,方案确定后再由AI来完成执行工作

AI负责决策+执行,部分互联网大厂已经自研出开发Agent,测试Agent等来代替人工执行开发和测试执行工作,但Agent执行过程中还是需要人与其对话进行驱动

在这里插入图片描述
在这里插入图片描述

而未来的工作模式,会以Agent为核心,自动去完成上述工作,彻底脱离人,人在整个过程的角色则变成了维护知识库供AI参考

在这里插入图片描述
在这里插入图片描述

有小伙伴会好奇,那Agent底层技术都是用的什么?基座大模型一般选择最新的模型,如GLM-5.2 ,DeepSeek-V4,Claude Opus 4.8,GPT-5.6等

上层的Agent根据业务场景来选择,如果是一些中小创业公司,AI赋能内部的工作流直接用Codex、Claude Code即可,也有选择OpenClaw来封装的

对于定制化的Agent,可以用LangGraph、LangChain、Dify等框架来实现

Claude Code与Codex,本质就是通用Agent,结合自己开发的各种Skill能快速搭建出适配团队内部的Agent

下面将重点介绍Codex+Skill做的测试Agent,用来全自动化执行APP 自动化测试

基于Skill的APP自动化测试工作流方案

对于执行APP 自动化测试,真正的难点往往不是写出第一条自动化测试用例,而是下面这些问题

  • 需求来了以后,谁来判断测试范围
  • 代码分支怎么拉
  • 是否需要重新打包
  • APK 怎么自动安装到真机
  • 旧用例是否还能覆盖此需求
  • 新用例怎么生成
  • 执行失败以后又该重试几次等

这些步骤只要还有一半依赖人工,APP自动化测试就很容易变成半自动化。

我现在做的这套方案,核心思路是把 GitLab CI、任务队列、真机节点和 Codex Skills 串成一个完整闭环

测试人员只需要先在 GitLab CI流水线场景测试任务,填写代码模块、代码分支、回归模式和 PRD文档路径等必要参数

Mac Mini本地自动监测到新的测试任务后,自动领取测试任务,开始生成Plan测试计划,后续进行代码分析、APK 构建安装、自动化用例生成、真机执行和结果通知

执行过程中不需要人工干预,任务执行失败/成功后,钉钉机器人会自动通知任务执行结果

架构介绍

要搭建起整套核心工作流,有两个核心服务

  • ui-test-task-server:管理(查询/新增/更新)测试任务,管理任务队列
  • ui-test-task-client:执行端,调用ui-test-task-server的接口,领取测试任务,之后调用Codex CLI和一系列Skill完成测试任务

部署环境注意事项:

ui-test-task-server部署在任意一台Linux服务器,ui-test-task-client运行在本地PC或Mac Mini(执行APP 自动化需要使用ADB命令操作真机,SDK依赖等限制)

涉及的Skill汇总如下:

在这里插入图片描述
在这里插入图片描述

这套方案解决的不是单纯的用例生成问题,而是把任务创建、代码分析、APK 构建安装、用例生成、真机执行和结果通知串成一条可持续运行的流水线。

测试人员只需要在 GitLab 创建任务。部署在 Mac Mini 上的 ui-test-task-client 会自动领取任务,并根据任务参数调用对应的 Skill 完成后续工作。

使用流程

一、运行前准备

Linux服务器上需要提前准备部署 ui-test-task-server 服务并能正常访问

在这里插入图片描述
在这里插入图片描述

Mac Mini 需要提前准备以下环境。

  • 已拉取 android-ui-tests 仓库(含APP自动化测试工程文件)
在这里插入图片描述
在这里插入图片描述
  • 已安装 Python 3、Codex CLI、Android SDK、ADB 和 Appium
  • Android 真机已开启 USB 调试
  • Codex API Key 已配置,Codex 加载完成必需的Skill文件,放置在Codex能自动发现Skill的目录 ~/.codex/skills
  • APK 构建需要的 GITLAB_TOKEN 已配置

先检查基础环境。

代码语言:javascript
复制
adb devices -l
codex --version
python3 --version

ADB 列表中的设备状态必须是 device。如果显示 unauthorizedoffline,Client 不会领取任务。

二、配置 ui-test-task-client

先将ui-test-task-client工程文件拉取在Mac Mini上

在这里插入图片描述
在这里插入图片描述

在仓库根目录创建本地环境文件。

代码语言:javascript
复制
cp ui-test-task-client/client.env.example \
   ui-test-task-client/client.env

chmod 600 ui-test-task-client/client.env

填写必要配置。

代码语言:javascript
复制
export OPENAI_API_KEY="your-openai-api-key"
export UI_TASK_SERVER_URL="http://your-ui-task-server:8091"
export ANDROID_HOME="$HOME/Library/Android/sdk"
export ANDROID_SDK_ROOT="$HOME/Library/Android/sdk"
export GITLAB_TOKEN="your-gitlab-token"

client.env 已被 Git 忽略,不要把 API Key、GitLab Token 或设备认证密码提交到代码仓库。

启动前可以打印一次配置。

代码语言:javascript
复制
python3 ui-test-task-client/ui_test_task_client.py --print-config

只消费一轮任务用于调试。

代码语言:javascript
复制
python3 ui-test-task-client/ui_test_task_client.py --once

正常启动常驻轮询。

代码语言:javascript
复制
python3 ui-test-task-client/ui_test_task_client.py

生产使用建议配置成 macOS LaunchAgent。进程退出后由 launchd 自动拉起,Mac Mini 重启后也能自动恢复。

三、在 GitLab 创建测试任务

进入 GitLab 项目的 Build → Pipelines → New pipeline,填写 UI 自动化任务参数,然后手动执行 create_ui_test_task Job。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常用参数如下。

参数

示例

用途

code_refs

{"uniclaw-server":"feature/a","uniclaw-android":"dev"}

指定代码模块与分支

module_kind

auto

自动识别 server、client 或 mixed

regression_strategy

changed

选择 auto、smoke、full 或 changed

prd_path

android-ui-tests/docs/pm/im.md

可选 PRD 文件

require_explicit_prd

false

是否禁止自动查找历史 PRD

auto_test_args

--skip-sync --skip-dump

控制 PRD 全流程中的跳过项

GitLab Job 会调用 create_ui_test_task.sh,把任务写入 ui-test-task-server。任务初始状态为 pending,数据保存在 MySQL 的 ui_test_tasks 表中。

四、Mac Mini 轮询并领取任务

ui-test-task-client 默认每 10 秒轮询一次。

每轮处理顺序如下。

  1. 使用 adb devices 检查真机状态
  2. 查询是否存在最近 48 小时内的 pending 任务
  3. 调用 /v1/ui-test-tasks/claim 原子领取最早任务
  4. 将任务状态更新为 running
  5. 记录 claimed_byclaimed_at
  6. 发送任务开始钉钉通知,钉钉通知内容如下:
代码语言:javascript
复制
UI 自动化任务开始执行
• client: lucasdeMacBook-Air.local
• host: lucasdeMacBook-Air.local
• workspace: /Users/lucas/xxx-test
任务信息
• id=19
• project=xxx-test
• branch=ui_test
• commit=af17f7
• created_at=2026-07-14T15:45:09.233
• module_kind=auto
代码模块/分支
• xxx-server: release-20260701
• xxx-android: dev

原子领取可以防止多台 Mac Mini 同时执行同一个任务。

如果存在待执行任务但没有可用真机,Client 不会领取任务,而是发送钉钉报警。超过 24 小时仍未执行的积压任务,每天还会额外提醒一次。

五、生成结构化测试计划

领取任务后,Client 会先调用 android-ui-task-orchestrator 中的确定性规划脚本。

代码语言:javascript
复制
python3 skills/android-ui-task-orchestrator/scripts/plan_task.py \
  android-ui-tests/data/task-inputs/task-{task_id}.json

规划器会完成以下工作。

  • 解析 code_refs
  • 识别客户端和服务端模块
  • 选择 fullsmokechanged
  • 分析是否需要构建 APK
  • 确定 Android 构建分支和环境
  • 计算 Changed 模式的 Git Diff
  • 映射受影响的 Pytest Marker
  • 判断是否需要生成新用例
  • 查找显式 PRD或历史 PRD

完整计划写入以下目录。

代码语言:javascript
复制
android-ui-tests/data/task-plans/task-{task_id}-plan.json

六、构建并安装最新 APK

如果计划要求使用新包,Client 会在启动 Codex 前执行 APK 前置流程。

先调用 android-apk-build

代码语言:javascript
复制
android-apk-build
→ 触发  Android GitLab Pipeline (根据自身业务流程调整Android端打包)
→ 触发钉钉通知 
→ 等待 APK 构建 Job
→ 获取 APK 下载地址和版本信息

构建开始的钉钉通知内容

代码语言:javascript
复制
UI 自动化前置 APK 构建开始
• id=19
• project=xxx-test
• branch=ui_test
• commit=af17f722
• created_at=2026-07-14T15:45:09.233
• module_kind=auto
• branch: dev
• environment: prod

构建成功的钉钉通知内容

代码语言:javascript
复制
UI 自动化前置 APK 构建完成,开始安装
• task: 19
• branch: dev
• version: 1.0.5 (105)
• download_url: https://xxxx/app/download/fe128b2a
• job_url: http://xxx/chagent/xxx-android/-/jobs/1840732

安装APK完成的钉钉通知内容

代码语言:javascript
复制
UI 自动化前置 APK 安装完成
• task: 19
• device: LKN5T18A28017235
• package: com.xxx.xxx
• installed_version: 1.0.5 (105)
• next: start Android UI automation

构建环境根据模块组合决定。

代码模块

APK 策略

包含 server 或 gateway

构建 test 预发包

只有 uniclaw-android

构建 prod 正式包

server + Android

使用传入 Android 分支构建 test 包

server-only

默认使用 Android dev 分支构建 test 包

构建完成后调用 android-ui-install-apk

代码语言:javascript
复制
android-ui-install-apk
→ 解析真实下载地址
→ 下载并校验 APK
→ adb install
→ 处理 Android 或华为安装提示
→ 校验 versionName 和 versionCode
→ 启动 App

只有真机版本与本次构建结果一致,任务才会继续。同一 Task 重试时,如果分支、环境和 Pipeline SHA 都没有变化,可以复用已有构建结果。

七、启动 Codex 和任务编排 Skill

APK 准备完成后,Client 启动 Codex CLI。

代码语言:javascript
复制
codex exec \
  -C "$UI_TASK_WORKSPACE" \
  --dangerously-bypass-approvals-and-sandbox \
  --json \
"<task prompt>"

Codex 首先调用 android-ui-task-orchestrator。它根据测试计划选择后续 Skill,不会无条件读取所有生成规范。

Smoke 模式

Smoke 只执行带有 P0 和 smoke 标记的存量用例。

代码语言:javascript
复制
android-ui-task-orchestrator
→ android-ui-run-and-fix
→ Android 真机

这条路径不会调用 PRD 解析和用例生成。

Full 模式

Full 无 PRD 时,直接执行全部存量测试。

Full 带 PRD 时,调用 android-ui-auto-test,执行完整 PRD 流程。

代码语言:javascript
复制
android-ui-sync-bug-history
→ android-ui-dump-ui
→ android-ui-prd-parse
→ android-ui-gen-tests
→ android-ui-run-and-fix
→ android-ui-analyze-results

可以通过 --skip-sync--skip-dump 复用已有数据,减少执行时间。

Changed 模式

Changed 模式先调用 android-ui-changed-regression

它会拉取指定代码仓库,对比基准分支和任务分支,并把变化文件映射到消息、群聊、联系人、个人资料等测试模块。

代码语言:javascript
复制
android-ui-task-orchestrator
→ android-ui-changed-regression
→ git clone / fetch / diff
→ 计算影响范围

如果存量用例已经覆盖变化范围,直接执行对应 Marker。

如果需要生成新用例并且找到了可用 PRD,则进入生成链路。

代码语言:javascript
复制
android-ui-dump-ui
→ android-ui-prd-parse
→ android-ui-gen-tests
→ android-ui-run-and-fix

如果没有上传新 PRD,系统可以从 android-ui-tests/docs/pm 自动匹配历史 PRD。找不到可信 PRD时,不会生成占位用例,而是执行已有的受影响用例,并记录未生成原因。

八、生成并验证 Appium 用例

android-ui-gen-tests 会综合以下信息生成测试代码。

  • PRD 结构化需求
  • 最新 UI Dump
  • Changed 代码差异
  • 页面导航图
  • Locator 规范
  • 历史 Bug
  • 已有测试代码

生成目录如下。

代码语言:javascript
复制
android-ui-tests/tests/generated/task_{task_id}/

生成后会先执行静态验证。

代码语言:javascript
复制
python py_compile
pytest --collect-only

只有能够正常编译和收集的测试,才允许进入真机执行阶段。

九、真机执行和自动修复

android-ui-run-and-fix 使用 Pytest、Appium 和 UiAutomator2 驱动真机。

它会收集日志、截图和 Allure Results,并区分以下问题。

  • 产品功能缺陷
  • Locator 失效
  • 等待时间不合理
  • App 未处于前台
  • 设备或系统安装问题
  • 测试环境异常

Changed 和 Smoke 默认只进行一轮聚类修复,并精确复测当前失败 Node ID,不会反复执行整套 Case。

十、结果分析和任务收尾

执行结束后,android-ui-analyze-results 解析 Allure 数据,生成失败分类和 Bug 信息。确认属于产品缺陷时,可以继续调用 yunxiao-bug 提交云效工作项。

无论 Codex 是否正常退出,Client 最后都会调用 finalize_task.py

它会生成两份固定产物。

代码语言:javascript
复制
android-ui-tests/docs/manual-cases/task-{id}-manual.md
android-ui-tests/docs/task-reports/task-{id}-report.md

人工回归清单记录自动化未覆盖、跨设备、环境受限或缺少可靠 Dump 的场景。

任务报告记录输入参数、代码影响范围、执行结果、失败原因、踩坑经验、产物位置和后续优化建议。

最后,Client 根据 Codex 退出码、测试汇总和计划错误综合判断任务状态,将结果更新为 successfailed,并发送钉钉通知。失败通知会附带最多三条失败 Case 的前置条件、执行步骤、预期结果和失败原因。

任务完成后的钉钉通知内容

代码语言:javascript
复制
### UI 自动化任务执行失败

**执行节点**

- client: lucasdeMac.local
- host: lucasdeMac.local
- status: failed
- message: Codex CLI 以 exit code 1 异常退出,Pytest 在约 35% 时中断,未完成全部测试和最终结果汇总

**任务信息**

- id: 19
- project: xxx/xxx/xxx-test
- branch: ui_test
- commit: af17f722
- created_at: 2026-07-14T15:45:09.233
- module_kind: auto
- regression_strategy: changed
- Android 设备: EVR_AL00
- APK 版本: 1.0.5(105)

**测试汇总**

- 收集用例: 515
- 执行进度: 约 35%
- 已记录失败: 3
- 最终汇总: 未生成
- 中断原因: Codex CLI 在 Pytest 完成前异常退出
- Allure Results: `data/allure-results-task19_changed-20260714_163439`
- 运行日志: `data/test_results/run_20260714_163439.log`

**失败 Case**

1. `L1-001 添加好友页元素组存在`
   - 失败原因: 添加好友页标题不存在
   - 失败断言: `AddFriendPage.TITLE` 定位结果为空

2. `L1-002 通讯录页面元素组存在`
   - 失败原因: 通讯录标题不存在
   - 失败断言: `ContactsPage.TITLE` 定位结果为空

3. `L1-003 扫一扫页面元素组存在`
   - 失败原因: 扫一扫页面标题不存在
   - 失败断言: `ScanQRPage.TITLE` 定位结果为空

**失败分析**

- 3 条失败集中在添加好友模块的页面标题和前置导航
- 同模块后续搜索、扫一扫入口、好友详情等多数用例执行成功
- ADB、Appium 和 UiAutomator2 运行正常
- 初步归类为页面导航或 Locator 契约失效
- 暂未确认属于产品功能缺陷
- 需要刷新通讯录、添加好友和扫一扫页面的 UI Dump 后重新核对 Locator

**人工复现步骤**

前置条件:

- 使用已登录测试账号
- 安装 APK 1.0.5(105)
- App 位于主界面

操作步骤:

1. 启动 xxx App
2. 点击底部「通讯录」Tab
3. 检查页面顶部是否展示「通讯录」标题
4. 点击通讯录页面右上角添加好友按钮
5. 检查页面是否进入「添加好友」页面
6. 检查标题、搜索框和「扫一扫」入口是否展示
7. 点击「扫一扫」
8. 如出现相机权限弹窗,允许权限或关闭弹窗
9. 检查扫一扫页面标题和扫描提示是否展示

预期结果:

- 通讯录、添加好友和扫一扫页面均能正常进入
- 页面标题和关键操作入口正确展示

实际结果:

- 自动化未找到「通讯录」「添加好友」「扫一扫」页面标题
- 需要结合失败截图和最新 UI XML 判断是页面未跳转,还是 Locator 已失效

**建议处理**

1. 执行 `android-ui-dump-ui` 更新三个页面的 UI XML
2. 检查 `ContactsPage.TITLE`、`AddFriendPage.TITLE` 和 `ScanQRPage.TITLE`
3. 修复前置导航或 Locator
4. 仅复测以上 3 条失败 Node ID
5. 排查 Codex CLI 提前退出原因,避免测试未完成却缺少最终 summary

到这里,一次完整的 UI 自动化任务才算真正结束。

整条主流程可以概括为。

代码语言:javascript
复制
GitLab 创建任务
→ ui-test-task-server 写入 pending 任务
→ Mac Mini Client 领取任务
→ 生成测试计划
→ 构建并安装 APK
→ Codex 调用 Orchestrator
→ 选择 full / smoke / changed
→ 必要时生成新用例
→ Appium 真机执行
→ Allure 结果分析
→ 生成任务报告
→ 更新任务状态
→ 钉钉通知
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试开发Guide 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 交付模式变化趋势
  • 基于Skill的APP自动化测试工作流方案
    • 架构介绍
  • 使用流程
    • 一、运行前准备
    • 二、配置 ui-test-task-client
    • 三、在 GitLab 创建测试任务
    • 四、Mac Mini 轮询并领取任务
    • 五、生成结构化测试计划
    • 六、构建并安装最新 APK
    • 七、启动 Codex 和任务编排 Skill
      • Smoke 模式
      • Full 模式
      • Changed 模式
    • 八、生成并验证 Appium 用例
    • 九、真机执行和自动修复
    • 十、结果分析和任务收尾
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档