# 使用AI CLI 编写uni-app自动化测试用例并运行

随着uni-app (x)项目功能的日益复杂,如何保证跨端体验的一致性和高质量,成了一个巨大的挑战。自动化测试是解决这一问题的金钥匙,但编写和维护测试用例本身就是一项耗时耗力的工作。

现在,我们可以借助强大的 AI 编程助手(如 Google Gemini CLIGithub Copilot CLIclaude-codeqoder cli),将这一过程变得前所未有的简单和高效。本文将一步步教你如何利用 AI,为你的 uni-app 项目自动编写测试用例并运行测试。

# 测试环境准备

# 安装npm包

在AI CLI中,运行自动化测试,需要在项目目录下,安装 @dcloudio/hbuilderx-cli 依赖包,它让您可以通过 npm scripts 轻松使用 HBuilderX 的各种功能。

# 如果项目下不存在package.json文件,请先运行npm init -y命令,生成package.json文件。
npm init -y
# 安装
npm install @dcloudio/hbuilderx-cli --save-dev

# 安装HBuilderX自动化测试插件

浏览器访问DCloud插件市场,下载插件HBuilderX uni-app自动化测试

点击【导入插件】,会自动拉起本地安装的HBuilderX,完成插件安装。

uniapp自动化测试环境,需要安装jest、adbkit、puppeteer、playwright等库,安装相关依赖之后,才可以正常使用此插件。

受网络环境、电脑环境、安装包体积大小等,可能安装很慢。

# 测试支持的平台以及设备

平台 描述
Web Chrome、Safari、Firefox
微信小程序
Android 支持Android真机、模拟器
iOS 不支持windows;仅支持在Mac上测试,且仅支持iOS模拟器
Harmony 支持鸿蒙真机、模拟器

注意:

  1. iOS测试,需要Mac电脑安装 XCode
  2. Harmony测试,需要电脑 DevEco-Studio

# 关于npm包hbuilderx-cli

npm包 @dcloudio/hbuilderx-cli,是一个便捷的 HBuilderX 命令行工具包装器,让您可以通过 npm scripts 轻松使用 HBuilderX 的各种功能,也方便AI调取运行日志自动修复问题。

npm包,封装了HBuilderX cli uni-app (x)项目启动、日志查看、自动化测试相关功能。HBuilderX cli文档HBuilderX自动化测试插件cli文档

下面将介绍@dcloudio/hbuilderx-cli,使用npm命令运行自动化测试。

特别注意事项:运行测试前,请先确保HBuilderX uni-app自动化测试插件 可以在HBuilderX内正常使用。

# 运行测试到weixin

# 运行所有测试用例
npm run test:mp-weixin

# 指定测试用例
npm run test:mp-weixin -- --testcaseFile pages/index/index.test.js

# 运行测试到Web

# 运行测试到web(默认为 Chrome),运行所有测试用例
npm run test:web

# 运行测试到web特定浏览器、并指定测试用例
npm run test:web -- --browser Chrome --testcaseFile pages/index/index.test.js
npm run test:web -- --browser Safari --testcaseFile pages/index/index.test.js
npm run test:web -- --browser Firefox --testcaseFile pages/index/index.test.js

# 运行测试到iOS模拟器

# iOS模拟器 测试 (默认使用查找到的第一个iOS模拟器设备)
npm run test:app-ios

# iOS模拟器 测试 ,指定设备ID
npm run test:app-ios -- --device_id 3FFE4F41-997F-4ED3-AC3B-DF4ADB9A4262

# 运行测试到Harmony

# iOS模拟器 测试 (默认使用查找到的第一个iOS模拟器设备)
npm run test:app-harmony

# iOS模拟器 测试 ,指定设备ID
npm run test:app-harmony -- --device_id 23EGK24530000100

# 运行测试到Android

# Android 测试 (默认使用查找到的第一个android设备)
npm run test:app-android

# Android 测试,指定特定设备
npm run test:app-android -- --device_id emulator-5554

运行到Android,npm run test:app-android 输出结果示例:

> tmp@1.0.0 test:app-android
> uni-test app-android

16:28:04.769 欢迎使用 HBuilderX CLI uni-app (x) 自动化测试命令行工具 (4.3.1)16:28:06.479 [uniapp.test] ....... 开始运行测试 ......
16:28:06.479 [uniapp.test] 测试项目:/Users/hx/Documents/__tmp/tmp
16:28:06.480 [uniapp.test] 测试平台:android
16:28:06.484 [uniapp.test] 开始获取可用的测试设备列表 ..... 
16:28:06.486 [uniapp.test] 可用的测试设备列表: android:feyhuos8ai89jr4p
16:28:06.495 [uniapp.test] 项目 tmp,开始运行测试 ......
16:28:06.496 [uniapp.test] 测试命令为:/Users/hx/DCloud/dcloud_test/env_run_lib/0.0.4/node_modules/jest/bin/jest.js -i --forceExit --json --outputFile="/Users/hx/Library/Application Support/HBuilder X/hbuilderx-for-uniapp-test/tmp/android/feyhuos8ai89jr4p-2092.json" --env="/Applications/HBuilderX-Dev.app/Contents/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/uni-automator/dist/environment.js" --globalTeardown="/Applications/HBuilderX-Dev.app/Contents/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/uni-automator/dist/teardown.js"
16:28:08.672 [uniapp.test]  Compiling...
16:28:12.117 [uniapp.test]  DONE  Build complete. Watching for changes...
16:28:12.334 [uniapp.test]  <Buffer >
16:28:12.334 [uniapp.test]  准备压缩数据
16:28:12.427 [uniapp.test]  压缩数据完成
16:28:12.471 [uniapp.test]  wifi server listening 8000
16:28:12.559 [uniapp.test]  http server listening 8001
16:28:12.560 [uniapp.test]  准备启动基座
16:28:12.561 [uniapp.test]  启动基座完成
16:28:12.630 [uniapp.test]  null Starting: Intent { cmp=io.dcloud.HBuilder/io.dcloud.debug.PullDebugActivity (has extras) }
16:28:13.672 [uniapp.test]  发送同步资源数据 {"mobile":{},"contents":{"project":{"type":"UniApp","appID":"HBuilder"},"fileInfo":[{"action":"writeFile","sourcePath":"http://127.0.0.1:8001/static/?path=/tmp/1765441692185.zip","name":"1765441692185.zip","fullPackage":true,"firstInstall":true}],"app":{"appID":"HBuilder","customBase":false},"refreashType":"reload"}}
16:28:20.896 [uniapp.test]  PASS pages/index/index.test.js (13.561 s)
16:28:20.896 [uniapp.test]  test title
16:28:20.896 [uniapp.test]  ✓ check page title (102 ms)
16:28:20.899 [uniapp.test]  Test Suites: 1 passed, 1 total
16:28:20.899 [uniapp.test]  Tests:       1 passed, 1 total
16:28:20.899 [uniapp.test]  Time:        13.765 s, estimated 14 s
16:28:20.899 [uniapp.test]  Snapshots:   0 total
16:28:20.899 [uniapp.test]  Ran all test suites.
16:28:23.903 [uniapp.test]  Test results written to: ../../../Library/Application Support/HBuilder X/hbuilderx-for-uniapp-test/tmp/android/feyhuos8ai89jr4p-2092.json
16:28:23.913 [uniapp.test]  测试运行结束。

16:28:23.913 [uniapp.test] 测试报告:/Users/hx/Library/Application Support/HBuilder X/hbuilderx-for-uniapp-test/tmp/android/feyhuos8ai89jr4p-2092.json
16:28:23.919 [uniapp.test] [uniapp.test] 测试用例总计:1,运行通过 1,运行失败 0,运行异常 0
16:28:23.920 [uniapp.test] 测试运行结束。

# 如何让AI编写并运行测试?

uni-app 提供了一批API,这些API可以操控uni-app应用,包括运行、跳转页面、触发点击等,并可以获取页面元素状态、进行截图。 uni-app 自动化测试API详情

所以我们要做的,就是让AI分析项目分析页面、根据页面编写测试用例、运行测试用例、执行测试、输出测试报告。

因此我们需要将相关规则(页面分析规则、测试用例编写规范、运行命令等等)整理成一份md文件,然后将md文件放置在项目根目录,以便AI读取。

md 文件编写要注意一些事项

规则要具体、明确、可执行,不要写模糊话术

  • 明确:页面分析规则、测试范围
  • 明确:测试用例编写生成规范
  • 明确:测试执行命令

# AI使用实例

# Copilot CLI

Copilot cli 安装:Github Copilot CLI

打开终端,进入项目目录,运行命令:

copilot -p "读取文件AGENT-Test-Prompt.md,按照要求生成测试用例并运行测试到android" --allow-all-tools

效果如下:

# Gemini CLI

Copilot cli 安装:Google Gemini CLI

打开终端,进入项目目录,输入命令 gemini

在gemini中提问,比如按照@AGENT-Test-Prompt.md 生成测试用例并运行测试到android

# 规范

# 测试用例编写规范

测试用例需要遵循以下规范:

  • 测试用例文件名通常为 *.test.js,便于 Jest 自动识别。
  • *.test.js 测试文件一般放在被测试文件同级,强烈建议放置到跟页面同一级目录。比如页面pages/login/login.uvue, 则测试用例文件名login.test.js
  • 每个测试用例应相互独立,避免依赖其他测试的执行结果
  • 遵守 Jest 语法规范,用法如:test('描述', () => { ... }) 或 it('描述', () => { ... })
  • uni测试框架API文档

# AI 自动化测试 Prompt 模板

将以下内容保存为 AGENT-Test-Prompt.md,放置在项目根目录。在使用 AI CLI 时,让 AI 读取此文件作为指令。

您可以根据需要,进行修改和扩展。

你是一个专业的 uni-app (x) 自动化测试工程师。你的任务是分析项目页面、编写高质量的自动化测试用例、运行测试并修复失败的用例。

1. 分析指定页面的结构和逻辑。
2. 生成或完善对应的测试用例文件 (*.test.js)。
3. 运行测试并输出结果。
4. 如果测试失败,分析原因并修复代码,直到测试通过。

## Workflow

### 1. 分析页面

uni-app (x)项目页面,在pages目录下,一般以 `.uvue``.vue` 结尾

分析内容包括:

* 页面结构: 识别关键组件 (button, input, list 等) 及其 class/id。
* 交互逻辑: 识别点击事件 (@click)、输入事件等。
* 数据状态: 识别页面绑定的数据变量。
* 预期行为: 这里的业务逻辑是什么?用户操作后应该发生什么?

###  2. 测试框架API

uni-app测试框架,提供的API可以操控uni-app应用,包括`控制跳转到指定页面``获取页面数据``获取页面元素状态``触发元素绑定事件``调用 uni 对象上任意接口``截图`等;本功能使用到了业内常见的测试库如jest。

你可以从 [测试API文档](https://uniapp.dcloud.net.cn/worktile/auto/api.html)获取相关用法。

###  3. 编写/更新测试用例

* 文件路径: 测试文件应与页面文件同级,命名为 `[page-name].test.js`* 检查存在性: 如果文件已存在,请读取内容并在其基础上完善;如果不存在,则创建。
* 编写规范:
  - 每个测试用例应相互独立,避免依赖其他测试的执行结果
  - 遵守 Jest 语法规范,用法如:`test('描述', () => { ... }) 或 it('描述', () => { ... })`

    **代码示例**:
    ```javascript
    describe('pages/login/login', () => {
        let page;
        beforeAll(async () => {
            page = await program.reLaunch('/pages/login/login');
            await page.waitFor(1000);
        });

        it('should display correct title', async () => {
            const titleEl = await page.$('.title');
            expect(await titleEl.text()).toBe('登录');
        });

        it('should validate phone number length', async () => {
            const input = await page.$('.phone-input');
            await input.input('123'); // 模拟输入
            const value = await input.value();
            expect(value.length).toBe(3);
        });
    });
    ```

###  4. 运行测试

* Web Chrome: `npm run test:web`
* Web Safari: `npm run test:web -- --browser Safari`
* Web Firefox: `npm run test:web -- --browser Firefox`
* Android: `npm run test:app-android`
* iOS: `npm run test:app-ios`
* harmony: `npm run test:app-harmony`
* 微信小程序: `npm run test:mp-weixin`

注意:
1. 默认运行所有测试文件。
2. 运行指定测试文件,增加参数 `--testcaseFile <test-file-path>`。示例 `npm run test:app-android -- --testcaseFile pages/index/index.test.js` 
3. Android、iOS、harmony测试,默认使用查找到的第一个设备进行测试。指定设备,可使用参数 `--deviceId <device-id>`。示例 `npm run test:app-android -- --deviceId emulator-5554`
4. iOS测试需要在Mac环境下运行,不支持windows,且仅支持iOS模拟器运行。

### 5. 结果分析与修复

*  检查终端输出的测试结果。
*  如果通过: 任务完成。
*  如果失败:
   *  读取报错信息。
   *  分析是测试代码问题还是业务代码问题。
   *  修改 `*.test.js` 或业务代码。
   *  重新运行测试,直到通过。

## Constraints

* 不要修改非目标页面的代码。
* 保持测试代码简洁、可读。
* 优先使用 `data-testid` 或具体的 class 选择器。

# AI运行测试中可能遇到的问题

# Q1:端口被占用

现象: 报错 Port 9520 is in use 或类似端口占用提示。

解决方案:

  1. 手动解决: 查找占用端口的进程并关闭。
    • Mac/Linux: lsof -i :9520 然后 kill -9 <PID>
    • Windows: netstat -ano | findstr 9520 然后 taskkill /PID <PID> /F
  2. AI 自动解决: 在 Prompt 中增加指令:“如果遇到端口占用错误,请自动查找并终止占用该端口的进程,然后重试。”