1. 自动化测试概述与工具链介绍
自动化测试是HarmonyOS应用开发流程中保证质量的关键环节。随着HarmonyOS生态的快速发展,应用功能日益复杂,分布式特性、多设备适配需求以及快速迭代的开发模式,使得传统手动测试无法满足质量要求。通过自动化测试,可以大幅提高测试效率和准确性,确保代码质量,减少人为错误。
HarmonyOS提供了完整的自动化测试工具链,其中DevEco Testing是官方推荐的一站式自动化测试解决方案。该框架支持ArkTS/JS语言,提供单元测试、UI测试和白盒性能测试能力,能够满足不同层次的测试需求。
自动化测试的核心价值在于:
- 提高测试效率:自动化测试能够快速执行大量测试用例,节省手动测试时间
- 增强测试覆盖率:确保每次代码提交后都执行全量测试
- 减少人为错误:避免人工操作中的失误,确保测试一致性和可靠性
- 支持持续集成:为CI/CD流程提供自动化质量保障
2. 测试环境配置与框架搭建
2.1 环境准备与依赖配置
在开始自动化测试前,需要配置完整的测试环境。首先确保使用DevEco Studio 3.1及以上版本,并配置Node.js 14+运行环境。
在项目的build.gradle中添加测试依赖:
// entry/package.json
{
"devDependencies": {
"@ohos/hypium": "^1.0.0",
"@ohos/test-kit": "^1.0.0"
}
}
在module.json5中声明测试所需权限:
{
"module": {
"reqPermissions": [
{
"name": "ohos.permission.INTERNET",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.ACCESS_DEBUG",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
}
]
}
}
2.2 测试目录结构
HarmonyOS测试采用标准目录结构,API 10及以上版本支持创建Instrument Test和Local Test:
src/
├── main/
│ └── ets/
│ └── pages/
├── ohosTest/ # Instrument Test(需要运行在设备上)
│ └── ets/
│ └── test/
└── test/ # Local Test(不需要运行在设备上)
└── ets/
└── test/
Instrument Test需要运行在真实设备或模拟器上,支持单元测试和UI测试;Local Test不需要运行在设备上,仅支持单元测试。
3. 单元测试实战
3.1 基础单元测试编写
单元测试是测试金字塔的基础,主要验证核心业务逻辑的正确性。HarmonyOS使用基于JUnit的测试框架,支持ArkTS/JS语言编写测试用例。
被测类示例:
// main/ets/utils/Calculator.ts
export class Calculator {
add(a: number, b: number): number {
return a + b;
}
multiply(a: number, b: number): number {
return a * b;
}
async fetchData(): Promise<string> {
// 模拟异步操作
return new Promise(resolve => {
setTimeout(() => {
resolve('data loaded');
}, 100);
});
}
}
测试类示例:
// ohosTest/ets/test/CalculatorTest.ets
import { describe, it, expect, beforeAll, afterEach } from '@ohos/hypium';
import { Calculator } from '../../../main/ets/utils/Calculator';
export default function calculatorTest() {
describe('CalculatorTests', () => {
let calculator: Calculator;
beforeAll(() => {
calculator = new Calculator();
});
afterEach(() => {
// 清理操作
});
it('testAddition', 0, () => {
const result = calculator.add(2, 3);
expect(result).assertEqual(5);
});
it('testMultiplication', 0, () => {
const result = calculator.multiply(4, 5);
expect(result).assertEqual(20);
});
it('testAsyncOperation', 0, async () => {
const result = await calculator.fetchData();
expect(result).assertEqual('data loaded');
});
});
}
3.2 高级测试技巧
对于复杂场景,需要使用Mock和Stub技术模拟依赖项:
// 模拟网络请求
class MockHttpClient {
async get(url: string): Promise<string> {
return Promise.resolve('mocked data');
}
}
// 在测试中使用Mock
describe('ServiceWithDependency', () => {
it('should use mocked http client', 0, async () => {
const mockClient = new MockHttpClient();
const service = new DataService(mockClient);
const result = await service.loadData();
expect(result).assertEqual('mocked data');
});
});
4. UI自动化测试实战
4.1 UI测试框架基础
UI自动化测试基于UiTest框架,提供查找和操作界面控件的能力。框架主要包含Driver类、组件操作API和断言方法。
基础UI测试示例:
// ohosTest/ets/test/LoginUiTest.ets
import { describe, it, expect } from '@ohos/hypium';
import { Driver, ON, Component, MatchPattern } from '@ohos.UiTest';
import { abilityDelegatorRegistry } from '@kit.TestKit';
const delegator = abilityDelegatorRegistry.getAbilityDelegator();
export default function loginUiTest() {
describe('LoginUITests', () => {
let driver: Driver;
beforeAll(async () => {
driver = await Driver.create();
// 启动被测应用
const bundleName = abilityDelegatorRegistry.getArguments().bundleName;
const want = {
bundleName: bundleName,
abilityName: 'EntryAbility'
};
await delegator.startAbility(want);
await driver.delayMs(1000);
});
it('testLoginSuccess', 0, async () => {
// 输入用户名
const usernameInput = await driver.findComponent(ON.id('username_input'));
await usernameInput.inputText('testuser');
// 输入密码
const passwordInput = await driver.findComponent(ON.id('password_input'));
await passwordInput.inputText('password123');
// 点击登录按钮
const loginButton = await driver.findComponent(ON.id('login_button'));
await loginButton.click();
// 验证登录成功
await driver.assertComponentExist(ON.text('登录成功'));
});
it('testListScroll', 0, async () => {
const list = await driver.findComponent(ON.type('Scroll'));
await list.flingScroll(0, 500); // 向下滚动
// 验证特定项可见
await driver.assertComponentExist(ON.text('第20项'));
});
});
}
4.2 页面对象模式(Page Object Pattern)
为提高测试代码的可维护性,推荐使用页面对象模式:
// ohosTest/ets/pages/LoginPage.ets
export class LoginPage {
private driver: Driver;
constructor(driver: Driver) {
this.driver = driver;
}
async enterUsername(username: string): Promise<void> {
const input = await this.driver.findComponent(ON.id('username_input'));
await input.inputText(username);
}
async enterPassword(password: string): Promise<void> {
const input = await this.driver.findComponent(ON.id('password_input'));
await input.inputText(password);
}
async clickLogin(): Promise<void> {
const button = await this.driver.findComponent(ON.id('login_button'));
await button.click();
}
async isLoginSuccess(): Promise<boolean> {
return await this.driver.assertComponentExist(ON.text('欢迎页面'));
}
}
// 在测试中使用页面对象
describe('LoginFlowWithPageObject', () => {
it('should login successfully', 0, async () => {
const loginPage = new LoginPage(driver);
await loginPage.enterUsername('testuser');
await loginPage.enterPassword('password123');
await loginPage.clickLogin();
expect(await loginPage.isLoginSuccess()).assertTrue();
});
});
5. 性能测试与监控
5.1 白盒性能测试
HarmonyOS提供PerfTest框架进行白盒性能测试,支持采集指定代码段执行期间的性能数据。
性能测试示例:
// ohosTest/ets/test/PerformanceTest.ets
import { describe, it, expect } from '@ohos/hypium';
import { PerfMetric, PerfTest, PerfTestStrategy, PerfMeasureResult } from '@kit.TestKit';
export default function performanceTest() {
describe('PerformanceTests', () => {
it('testListScrollPerformance', 0, async (done) => {
const metrics: Array<PerfMetric> = [
PerfMetric.LIST_SWIPE_FPS,
PerfMetric.CPU_USAGE,
PerfMetric.MEMORY_USAGE
];
const actionCode = async (finish: Callback<boolean>) => {
// 执行性能测试操作
const list = await driver.findComponent(ON.type('Scroll'));
await list.flingScroll(0, 1000);
finish(true);
};
const perfTestStrategy: PerfTestStrategy = {
metrics: metrics,
actionCode: actionCode,
iterations: 10,
timeout: 30000
};
try {
const perfTest: PerfTest = PerfTest.create(perfTestStrategy);
await perfTest.run();
const fpsResult: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.LIST_SWIPE_FPS);
const cpuResult: PerfMeasureResult = perfTest.getMeasureResult(PerfMetric.CPU_USAGE);
// 断言性能指标
expect(fpsResult.average).assertLargerOrEqual(55); // FPS应≥55
expect(cpuResult.average).assertLessOrEqual(30); // CPU使用率应≤30%
perfTest.destroy();
} catch (error) {
console.error(`性能测试失败: ${error}`);
expect(false).assertTrue();
}
done();
});
});
}
5.2 启动性能测试
应用启动时间是关键性能指标,需要专门测试:
// 启动性能测试
it('testColdStartTime', 0, async () => {
const startTime = new Date().getTime();
// 启动应用
const want = {
bundleName: 'com.example.app',
abilityName: 'EntryAbility'
};
await delegator.startAbility(want);
// 等待首页加载完成
await driver.assertComponentExist(ON.id('home_page'), 5000);
const endTime = new Date().getTime();
const startupTime = endTime - startTime;
expect(startupTime).assertLessOrEqual(1000); // 冷启动时间应≤1秒
});
6. 持续集成流水线搭建
6.1 GitHub Actions配置
持续集成是自动化测试的重要环节,以下是基于GitHub Actions的CI配置示例:
# .github/workflows/harmonyos-ci.yml
name: HarmonyOS CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: |
npm install -g @ohos/hvigor
npm ci
- name: Run unit tests
run: |
hvigor test --mode unit
- name: Run UI tests
run: |
hvigor test --mode uitest
env:
TEST_DEVICE: ${{ secrets.TEST_DEVICE }}
- name: Generate test report
run: |
hvigor test --report html
- name: Upload test results
uses: actions/upload-artifact@v3
with:
name: test-results
path: |
build/reports/
coverage/
build:
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main'
steps:
- name: Build application
run: |
hvigor assembleRelease
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: harmonyos-app
path: build/outputs/
6.2 Jenkins流水线配置
对于企业级项目,Jenkins提供更灵活的CI/CD能力:
// Jenkinsfile
pipeline {
agent any
environment {
HARMONY_SDK = '/opt/harmony/sdk/5.0'
PATH = "$PATH:$HARMONY_SDK/toolchains/arkcompiler/bin"
}
stages {
stage('Checkout') {
steps {
git branch: 'main',
url: 'https://github.com/your-org/your-harmonyos-app.git'
}
}
stage('Build') {
parallel {
stage('Phone Build') {
steps {
sh 'hvigor assemblePhoneRelease'
}
}
stage('Tablet Build') {
steps {
sh 'hvigor assembleTabletRelease'
}
}
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'hvigor test --type unit'
}
}
stage('UI Tests') {
steps {
sh 'hvigor test --type uitest'
}
}
stage('Performance Tests') {
steps {
sh 'hvigor test --type performance'
}
}
}
post {
always {
publishHTML target: [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'build/reports/tests',
reportFiles: 'index.html',
reportName: 'HTML Test Report'
]
}
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh 'hvigor publishToAppGallery'
}
}
}
post {
always {
emailext body: '${DEFAULT_CONTENT}',
subject: '构建结果: ${JOB_NAME} - Build #${BUILD_NUMBER} - ${BUILD_STATUS}',
to: 'team@example.com'
}
}
}
7. 高级测试策略与最佳实践
7.1 测试分层策略
建立完整的测试金字塔,确保测试覆盖率和执行效率:
| 测试层级 | 覆盖范围 | 执行频率 | 工具支持 |
|---|---|---|---|
| 单元测试 | 核心业务逻辑 | 每次提交 | DevEco Testing |
| 集成测试 | 模块间调用 | 每日构建 | HiRunner |
| UI测试 | 关键用户流程 | 版本迭代 | DevEco Studio |
| E2E测试 | 完整业务流程 | 发布前 | 云测平台 |
7.2 质量门禁设置
建立严格的质量门禁,确保代码质量:
# 质量门禁配置示例
quality_gates:
unit_test_coverage: 80%
ui_test_pass_rate: 100%
performance_baseline:
cold_start: 1000ms
memory_usage: 200MB
security_scan: 0_critical
7.3 分布式测试策略
针对HarmonyOS的分布式特性,需要专门的测试策略:
// 分布式场景测试示例
describe('DistributedTests', () => {
it('testCrossDeviceDataSync', 0, async () => {
// 获取设备列表
const devices = await deviceManager.getDevices();
const phone = devices.find(d => d.deviceType === 'phone');
const tablet = devices.find(d => d.deviceType === 'tablet');
// 在手机端执行操作
await phone.driver.findComponent(ON.id('share_button')).click();
// 验证平板端数据同步
await driver.distributedAssert(
{device: 'PHONE', element: ON.id('data_value')},
{device: 'TABLET', element: ON.id('data_value')},
(phoneVal, tabletVal) => phoneVal === tabletVal
);
});
});
8. 常见问题与解决方案
8.1 测试执行问题处理
问题1:用例执行超时
// 解决方案:调整超时设置并优化测试逻辑
it('longRunningTest', 60000, async (done) => { // 设置60秒超时
// 优化测试逻辑,减少不必要的等待
await driver.delayMs(500); // 使用精确等待替代固定等待
done();
});
问题2:控件找不到
// 解决方案:增加重试机制和更好的定位策略
async function findElementWithRetry(locator, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await driver.findComponent(locator);
} catch (error) {
if (i === retries - 1) throw error;
await driver.delayMs(1000);
}
}
}
8.2 测试数据管理
实现测试数据与测试逻辑分离:
# test-data/login-cases.yaml
test_cases:
- name: "有效凭据登录"
username: "valid_user"
password: "correct_password"
expected: "登录成功"
- name: "无效用户名"
username: "invalid_user"
password: "any_password"
expected: "用户名错误"
9. 总结与最佳实践
通过本文的实战指南,可以建立完整的HarmonyOS自动化测试与持续集成体系。关键成功因素包括:
9.1 效能提升指标
通过实施完整的自动化测试与CI/CD流程,可以达成显著的效能提升:
| 指标 | 改进前 | 目标值 |
|---|---|---|
| 测试执行时间 | 8小时/轮 | 3小时/轮 |
| 缺陷发现阶段 | 50%在线上 | 80%在测试阶段 |
| 回归成本 | 3人日/版本 | 1人日/版本 |
9.2 持续改进机制
建立持续改进机制,包括:
- 每月用例有效性评审
- 自动化脚本重构机制
- 测试数据版本化管理
- 定期性能基准评估
自动化测试与持续集成是HarmonyOS应用高质量交付的基石。通过系统化的测试策略和DevEco Testing的深度应用,可以显著提升HarmonyOS应用的测试效率和质量保障能力,为用户提供稳定可靠的应用体验。
1100

被折叠的 条评论
为什么被折叠?



