本文将深入探讨HarmonyOS中的单元测试与自动化测试实践,重点介绍Hypium测试框架的核心功能和使用方法,帮助您构建完善的测试体系。
1. Hypium测试框架概述
Hypium是HarmonyOS官方提供的一体化测试框架,集成了单元测试、UI测试和性能测试能力,为开发者提供完整的测试解决方案。
1.1 框架核心特性
- 多测试类型支持:单元测试、UI自动化测试、性能测试、分布式测试
- 丰富的断言库:提供多种断言方法验证测试结果
- Mock能力:支持函数和对象的模拟,隔离测试环境
- 数据驱动测试:通过外部数据文件驱动测试用例执行
- 分布式测试支持:专为HarmonyOS多设备协同场景设计
1.2 环境配置与依赖
在项目的package.json
中添加Hypium依赖:
{
"dependencies": {
"@ohos/hypium": "1.0.6"
}
}
在需要运行的测试模块下的ohosTest
目录中配置测试依赖:
// ohosTest模块下的package.json
{
"dependencies": {
"decc.test": "^1.0.0",
"hypium": "^1.0.0"
}
}
2. 单元测试实践
单元测试是测试金字塔的基础,专注于验证单个函数、方法或组件的正确性。
2.1 基础单元测试编写
// 计算器类 - 被测试代码
export class Calculator {
// 加法运算
add(a: number, b: number): number {
return a + b;
}
// 减法运算
subtract(a: number, b: number): number {
return a - b;
}
// 乘法运算
multiply(a: number, b: number): number {
return a * b;
}
// 除法运算
divide(a: number, b: number): number {
if (b === 0) {
throw new Error('Division by zero is not allowed');
}
return a / b;
}
// 复杂计算:百分比
calculatePercentage(value: number, total: number): number {
if (total === 0) {
throw new Error('Total cannot be zero for percentage calculation');
}
return (value / total) * 100;
}
}
// Calculator.test.ts - 单元测试
import { describe, it, expect, beforeAll, afterAll } from '@ohos/hypium';
import { Calculator } from '../src/main/ets/utils/Calculator';
describe('Calculator Tests', () => {
let calculator: Calculator;
// 测试前置操作
beforeAll(() => {
calculator = new Calculator();
console.info('Calculator instance created');
});
// 测试后置清理
afterAll(() => {
console.info('Calculator tests completed');
});
// 加法测试
it('should_add_two_numbers_correctly', 0, () => {
const result = calculator.add(2, 3);
expect(result).assertEqual(5);
});
// 减法测试
it('should_subtract_two_numbers_correctly', 0, () => {
const result = calculator.subtract(5, 3);
expect(result).assertEqual(2);
});
// 乘法测试
it('should_multiply_two_numbers_correctly', 0, () => {
const result = calculator.multiply(4, 3);
expect(result).assertEqual(12);
});
// 除法测试
it('should_divide_two_numbers_correctly', 0, () => {
const result = calculator.divide(10, 2);
expect(result).assertEqual(5);
});
// 除零异常测试
it('should_throw_error_when_dividing_by_zero', 0, () => {
try {
calculator.divide(10, 0);
// 如果执行到这里说明测试失败
expect(true).assertFalse(); // 强制测试失败
} catch (error) {
expect(error.message).assertEqual('Division by zero is not allowed');
}
});
// 百分比计算测试
it('should_calculate_percentage_correctly', 0, () => {
const result = calculator.calculatePercentage(25, 100);
expect(result).assertEqual(25);
});
// 边界值测试
it('should_handle_zero_value_in_percentage_calculation', 0, () => {
const result = calculator.calculatePercentage(0, 100);
expect(result).assertEqual(0);
});
// 异常情况测试
it('should_throw_error_for_zero_total_in_percentage', 0, () => {
try {
calculator.calculatePercentage(50, 0);
expect(true).assertFalse();
} catch (error) {
expect(error.message).assertEqual('Total cannot be zero for percentage calculation');
}
});
});
2.2 异步操作测试
// 数据服务类 - 包含异步操作
export class DataService {
// 模拟异步数据获取
async fetchData(url: string): Promise<any> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url.includes('error')) {
reject(new Error('Network error'));
} else {
resolve({ data: 'mock data', status: 200 });
}
}, 100);
});
}
// 处理多个异步操作
async processMultipleRequests(urls: string[]): Promise<any[]> {
const results: any[] = [];
for (const url of urls) {
try {
const result = await this.fetchData(url);
results.push(result);
} catch (error) {
results.push({ error: error.message });
}
}
return results;
}
}
// DataService.test.ts - 异步测试
import { describe, it, expect, beforeEach } from '@ohos/hypium';
import { DataService } from '../src/main/ets/services/DataService';
describe('DataService Tests', () => {
let dataService: DataService;
beforeEach(() => {
dataService = new DataService();
});
// 成功异步操作测试
it('should_fetch_data_successfully', 0, async () => {
const result = await dataService.fetchData('https://api.example.com/data');
expect(result.status).assertEqual(200);
expect(result.data).assertEqual('mock data');
});
// 异步操作失败测试
it('should_handle_network_error', 0, async () => {
try {
await dataService.fetchData('https://api.example.com/error');
expect(true).assertFalse(); // 不应该执行到这里
} catch (error) {
expect(error.message).assertEqual('Network error');
}
});
// 多个异步操作测试
it('should_process_multiple_requests_correctly', 0, async () => {
const urls = [
'https://api.example.com/data1',
'https://api.example.com/data2',
'https://api.example.com/error' // 其中一个会失败
];
const results = await dataService.processMultipleRequests(urls);
expect(results.length).assertEqual(3);
expect(results[0].status).assertEqual(200);
expect(results[2].error).assertEqual('Network error');
});
// 超时测试
it('should_complete_within_time_limit', 0, async () => {
const startTime = Date.now();
await dataService.fetchData('https://api.example.com/data');
const duration = Date.now() - startTime;
expect(duration).assertLess(200); // 应该在200ms内完成
});
});
3. Mock与测试隔离
使用Mock技术隔离外部依赖,确保测试的纯粹性和可重复性。
3.1 函数Mock示例
// 用户服务类
export class UserService {
private apiUrl: string = 'https://api.example.com/users';
// 获取用户信息
async getUserInfo(userId: string): Promise<any> {
const response = await fetch(`${this.apiUrl}/${userId}`);
return response.json();
}
// 验证用户权限
hasPermission(user: any, permission: string): boolean {
return user.permissions.includes(permission);
}
}
// UserService.test.ts - Mock测试
import { describe, it, expect, beforeEach, mock } from '@ohos/hypium';
import { UserService } from '../src/main/ets/services/UserService';
describe('UserService Tests', () => {
let userService: UserService;
beforeEach(() => {
userService = new UserService();
});
// Mock fetch函数
it('should_get_user_info_using_mock_fetch', 0, async () => {
// 模拟fetch函数
const mockFetch = mock(global, 'fetch');
const mockUser = { id: '1', name: 'John Doe', permissions: ['read', 'write'] };
// 设置mock返回值
mockFetch.mockImplementation(() =>
Promise.resolve({
json: () => Promise.resolve(mockUser)
})
);
const userInfo = await userService.getUserInfo('1');
expect(userInfo.id).assertEqual('1');
expect(userInfo.name).assertEqual('John Doe');
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/users/1');
// 恢复原始实现
mockFetch.restore();
});
// 权限验证测试
it('should_check_user_permissions_correctly', 0, () => {
const user = {
id: '1',
name: 'Test User',
permissions: ['read', 'write', 'delete']
};
expect(userService.hasPermission(user, 'read')).assertTrue();
expect(userService.hasPermission(user, 'write')).assertTrue();
expect(userService.hasPermission(user, 'admin')).assertFalse();
});
// 错误处理测试
it('should_handle_api_errors', 0, async () => {
const mockFetch = mock(global, 'fetch');
mockFetch.mockImplementation(() =>
Promise.reject(new Error('API unavailable'))
);
try {
await userService.getUserInfo('1');
expect(true).assertFalse();
} catch (error) {
expect(error.message).assertEqual('API unavailable');
}
mockFetch.restore();
});
});
3.2 复杂对象Mock
// 数据库服务类
export class DatabaseService {
private connection: any;
constructor(connection: any) {
this.connection = connection;
}
async query(sql: string, params: any[] = []): Promise<any[]> {
return this.connection.execute(sql, params);
}
async getUserById(id: string): Promise<any> {
const result = await this.query('SELECT * FROM users WHERE id = ?', [id]);
return result[0];
}
}
// DatabaseService.test.ts - 复杂Mock
import { describe, it, expect, beforeEach, mock } from '@ohos/hypium';
import { DatabaseService } from '../src/main/ets/services/DatabaseService';
describe('DatabaseService Tests', () => {
let mockConnection: any;
let dbService: DatabaseService;
beforeEach(() => {
// 创建模拟数据库连接
mockConnection = {
execute: mock().mockImplementation((sql, params) => {
if (sql.includes('SELECT')) {
return Promise.resolve([{ id: params[0], name: 'Mock User' }]);
}
return Promise.resolve([]);
})
};
dbService = new DatabaseService(mockConnection);
});
it('should_execute_query_with_mock_connection', 0, async () => {
const result = await dbService.query('SELECT * FROM users WHERE id = ?', ['1']);
expect(result.length).assertEqual(1);
expect(result[0].id).assertEqual('1');
expect(result[0].name).assertEqual('Mock User');
expect(mockConnection.execute).toHaveBeenCalledWith(
'SELECT * FROM users WHERE id = ?',
['1']
);
});
it('should_get_user_by_id', 0, async () => {
const user = await dbService.getUserById('123');
expect(user.id).assertEqual('123');
expect(user.name).assertEqual('Mock User');
});
it('should_handle_empty_results', 0, async () => {
// 重写mock实现返回空数组
mockConnection.execute.mockImplementation(() => Promise.resolve([]));
const user = await dbService.getUserById('999');
expect(user).assertUndefined();
});
});
4. UI自动化测试
UI测试验证用户界面的交互和显示是否正确。
4.1 基础UI组件测试
// 登录组件
@Component
export struct LoginComponent {
@State username: string = '';
@State password: string = '';
@State errorMessage: string = '';
@State isLoading: boolean = false;
// 登录处理
async handleLogin() {
if (!this.username || !this.password) {
this.errorMessage = '用户名和密码不能为空';
return;
}
this.isLoading = true;
this.errorMessage = '';
try {
// 模拟登录API调用
await this.loginAPI(this.username, this.password);
// 登录成功处理...
} catch (error) {
this.errorMessage = '登录失败,请检查凭证';
} finally {
this.isLoading = false;
}
}
private async loginAPI(username: string, password: string): Promise<void> {
// 模拟API调用
return new Promise((resolve, reject) => {
setTimeout(() => {
if (username === 'admin' && password === 'password') {
resolve();
} else {
reject(new Error('Invalid credentials'));
}
}, 1000);
});
}
build() {
Column() {
TextInput({ placeholder: '用户名' })
.onChange((value: string) => {
this.username = value;
})
.width('80%')
.margin(10)
TextInput({ placeholder: '密码', type: InputType.Password })
.onChange((value: string) => {
this.password = value;
})
.width('80%')
.margin(10)
if (this.errorMessage) {
Text(this.errorMessage)
.fontColor(Color.Red)
.margin(10)
}
if (this.isLoading) {
LoadingIndicator()
.margin(10)
} else {
Button('登录', () => {
this.handleLogin();
})
.width('80%')
.margin(10)
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
// LoginComponent.test.ts - UI测试
import { describe, it, expect, beforeEach } from '@ohos/hypium';
import { LoginComponent } from '../src/main/ets/components/LoginComponent';
import { Driver, ON } from '@kit.TestKit';
describe('LoginComponent UI Tests', () => {
let driver: Driver;
let loginComponent: LoginComponent;
beforeEach(() => {
driver = Driver.create();
loginComponent = new LoginComponent();
});
it('should_display_error_when_fields_empty', 0, async () => {
// 直接测试组件方法
await loginComponent.handleLogin();
expect(loginComponent.errorMessage).assertEqual('用户名和密码不能为空');
});
it('should_show_loading_indicator_during_login', 0, async () => {
loginComponent.username = 'admin';
loginComponent.password = 'password';
// 启动登录过程
const loginPromise = loginComponent.handleLogin();
// 检查加载状态
expect(loginComponent.isLoading).assertTrue();
// 等待登录完成
await loginPromise;
expect(loginComponent.isLoading).assertFalse();
});
it('should_handle_successful_login', 0, async () => {
loginComponent.username = 'admin';
loginComponent.password = 'password';
await loginComponent.handleLogin();
expect(loginComponent.errorMessage).assertEqual('');
});
it('should_handle_failed_login', 0, async () => {
loginComponent.username = 'wrong';
loginComponent.password = 'wrong';
await loginComponent.handleLogin();
expect(loginComponent.errorMessage).assertEqual('登录失败,请检查凭证');
});
});
4.2 完整页面UI测试
// 主页测试示例
import { describe, it, expect, beforeAll } from '@ohos/hypium';
import { Driver, ON, device } from '@kit.TestKit';
describe('HomePage UI Tests', () => {
let driver: Driver;
beforeAll(async () => {
driver = Driver.create();
// 启动应用
await device.launchApp({ bundleName: 'com.example.app' });
await driver.delayMs(1000); // 等待应用加载
});
it('should_display_welcome_message', 0, async () => {
const welcomeText = await driver.findComponent(ON.text('欢迎使用'));
expect(await welcomeText.isDisplayed()).assertTrue();
});
it('should_navigate_to_settings', 0, async () => {
// 查找设置按钮并点击
const settingsButton = await driver.findComponent(ON.id('settings_button'));
await settingsButton.click();
await driver.delayMs(500);
// 验证是否跳转到设置页面
const settingsTitle = await driver.findComponent(ON.text('设置'));
expect(await settingsTitle.isDisplayed()).assertTrue();
});
it('should_handle_form_submission', 0, async () => {
// 在表单中输入文本
const nameInput = await driver.findComponent(ON.id('name_input'));
await nameInput.typeText('Test User');
const emailInput = await driver.findComponent(ON.id('email_input'));
await emailInput.typeText('test@example.com');
// 提交表单
const submitButton = await driver.findComponent(ON.id('submit_button'));
await submitButton.click();
await driver.delayMs(1000);
// 验证提交结果
const successMessage = await driver.findComponent(ON.text('提交成功'));
expect(await successMessage.isDisplayed()).assertTrue();
});
it('should_display_list_items_correctly', 0, async () => {
// 滚动查找列表项
const listItems = await driver.findComponents(ON.className('list_item'));
expect(listItems.length).assertLarger(0);
// 验证第一个列表项的内容
const firstItem = listItems[0];
const itemText = await firstItem.getText();
expect(itemText).assertContain('Item');
});
});
5. 数据驱动测试
数据驱动测试允许使用外部数据文件来参数化测试用例。
5.1 数据文件配置
创建test/data.json
数据文件:
{
"suites": [
{
"describe": "LoginTestSuite",
"params": {
"testEnvironment": "staging"
},
"items": [
{
"it": "test_login_scenarios",
"stress": 3,
"params": [
{
"username": "admin",
"password": "password",
"expectedSuccess": true,
"description": "Valid credentials"
},
{
"username": "user",
"password": "wrong",
"expectedSuccess": false,
"description": "Invalid password"
},
{
"username": "",
"password": "password",
"expectedSuccess": false,
"description": "Empty username"
},
{
"username": "admin",
"password": "",
"expectedSuccess": false,
"description": "Empty password"
}
]
}
]
}
]
}
5.2 数据驱动测试用例
// LoginDataDriven.test.ts
import { describe, it, expect } from '@ohos/hypium';
import { LoginComponent } from '../src/main/ets/components/LoginComponent';
// 从数据文件导入测试数据
const testData = require('../test/data.json');
describe('LoginDataDrivenTests', () => {
const loginScenarios = testData.suites[0].items[0].params;
loginScenarios.forEach((scenario: any, index: number) => {
it(`login_scenario_${index + 1}: ${scenario.description}`, 0, async () => {
const loginComponent = new LoginComponent();
// 设置测试数据
loginComponent.username = scenario.username;
loginComponent.password = scenario.password;
try {
await loginComponent.handleLogin();
if (scenario.expectedSuccess) {
expect(loginComponent.errorMessage).assertEqual('');
} else {
expect(loginComponent.errorMessage).assertNotEqual('');
}
} catch (error) {
// 处理意外错误
expect(error.message).assertEqual('Unexpected test error');
}
});
});
// 压力测试:多次执行同一测试用例
it('login_stress_test', 0, async () => {
const loginComponent = new LoginComponent();
const validScenario = loginScenarios[0];
for (let i = 0; i < 10; i++) {
loginComponent.username = validScenario.username;
loginComponent.password = validScenario.password;
await loginComponent.handleLogin();
expect(loginComponent.errorMessage).assertEqual('');
}
});
});
6. 性能测试
性能测试确保应用在各种条件下都能保持良好的性能表现。
6.1 基础性能测试
// PerformanceTests.test.ts
import { describe, it, expect, perf } from '@ohos/hypium';
import { Calculator } from '../src/main/ets/utils/Calculator';
import { HeavyOperationService } from '../src/main/ets/services/HeavyOperationService';
describe('Performance Tests', () => {
let calculator: Calculator;
let heavyService: HeavyOperationService;
beforeAll(() => {
calculator = new Calculator();
heavyService = new HeavyOperationService();
});
it('should_calculate_quickly', 0, async () => {
const result = await perf.measureTime(() => {
// 执行1000次计算操作
for (let i = 0; i < 1000; i++) {
calculator.add(i, i * 2);
calculator.multiply(i, 3);
}
});
expect(result.totalTime).assertLess(50); // 应在50ms内完成
});
it('should_maintain_low_memory_usage', 0, async () => {
const memoryUsage = await perf.measureMemory(() => {
// 创建大量临时对象
const tempArray = [];
for (let i = 0; i < 10000; i++) {
tempArray.push({ index: i, data: 'test'.repeat(10) });
}
return tempArray.length;
});
expect(memoryUsage.peakBytes).assertLess(10 * 1024 * 1024); // 峰值内存应小于10MB
});
it('should_handle_heavy_operations_efficiently', 0, async () => {
const performanceResult = await perf.measure(() => {
return heavyService.processLargeData(10000);
});
expect(performanceResult.time).assertLess(1000); // 操作时间应小于1秒
expect(performanceResult.memory).assertLess(5 * 1024 * 1024); // 内存使用应小于5MB
});
it('should_maintain_high_fps_during_ui_operations', 0, async () => {
const fpsResult = await perf.measureFPS(async () => {
// 模拟UI渲染操作
for (let i = 0; i < 60; i++) {
await heavyService.simulateUIRender();
await perf.delayMs(16); // 模拟60FPS的帧间隔
}
});
expect(fpsResult.avgFPS).assertLarger(55); // 平均FPS应高于55
expect(fpsResult.minFPS).assertLarger(45); // 最低FPS应高于45
});
});
6.2 高级性能监控
// AdvancedPerformanceMonitor.test.ts
import { describe, it, expect, perf, mock } from '@ohos/hypium';
import { PerformanceMonitor } from '../src/main/ets/utils/PerformanceMonitor';
describe('Advanced Performance Monitoring', () => {
it('should_monitor_cpu_usage', 0, async () => {
const cpuUsage = await perf.measureCPU(() => {
// CPU密集型操作
let result = 0;
for (let i = 0; i < 1000000; i++) {
result += Math.sqrt(i) * Math.cos(i);
}
return result;
});
expect(cpuUsage.percentage).assertLess(80); // CPU使用率应低于80%
});
it('should_detect_memory_leaks', 0, async () => {
const memoryResults = [];
// 多次执行相同操作,检查内存增长
for (let i = 0; i < 10; i++) {
const result = await perf.measureMemory(() => {
// 模拟可能的内存泄漏操作
const data = new Array(1000).fill('test data');
return data.length;
});
memoryResults.push(result.peakBytes);
await perf.delayMs(100);
}
// 检查内存是否稳定增长(可能的内存泄漏)
const memoryGrowth = memoryResults[memoryResults.length - 1] - memoryResults[0];
expect(memoryGrowth).assertLess(1024 * 1024); // 内存增长应小于1MB
});
it('should_measure_network_performance', 0, async () => {
const networkMetrics = await perf.measureNetwork(async () => {
// 模拟网络请求
await perf.delayMs(100); // 模拟网络延迟
return { status: 200, data: 'response' };
});
expect(networkMetrics.latency).assertLess(200); // 延迟应小于200ms
expect(networkMetrics.success).assertTrue(); // 请求应成功
});
});
7. 持续集成与自动化执行
将测试集成到CI/CD流水线中,实现自动化测试执行。
7.1 CI/CD配置示例
// Jenkinsfile 或 GitHub Actions 配置示例
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: 'main',
url: 'https://github.com/your-repo/your-harmonyos-app.git'
}
}
stage('Build') {
steps {
script {
sh 'npm install'
sh 'npm run build'
}
}
}
stage('Test') {
steps {
script {
// 运行单元测试
sh 'npm run test:unit -- --coverage'
// 运行UI测试
sh 'npm run test:ui -- --device=emulator-5554'
// 运行性能测试
sh 'npm run test:perf'
}
}
}
stage('Report') {
steps {
script {
// 生成测试报告
sh 'npm run test:report'
// 发布测试结果
publishHTML target: [
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'test-reports',
reportFiles: 'index.html',
reportName: 'Test Results'
]
}
}
}
}
post {
always {
// 清理操作
cleanWs()
}
}
}
7.2 测试脚本配置
在package.json
中配置测试脚本:
{
"scripts": {
"test:unit": "hypium test --type unit --coverage",
"test:ui": "hypium test --type ui --device emulator-5554",
"test:perf": "hypium test --type performance",
"test:all": "npm run test:unit && npm run test:ui && npm run test:perf",
"test:report": "hypium report --format html --output test-reports/",
"test:ci": "npm run test:all -- --ci --headless"
}
}
8. 测试报告与结果分析
生成详细的测试报告,帮助分析测试结果和改进代码质量。
8.1 测试报告生成
// ReportGenerator.ts
import { writeFile, mkdir } from '@ohos.fileio';
import { TestResults, TestSuiteResult, TestCaseResult } from '@ohos/hypium/reporter';
export class TestReportGenerator {
async generateHTMLReport(results: TestResults, outputPath: string): Promise<void> {
const reportContent = this.buildHTMLContent(results);
await this.ensureDirectoryExists(outputPath);
await writeFile(`${outputPath}/index.html`, reportContent);
}
private buildHTMLContent(results: TestResults): string {
return `
<!DOCTYPE html>
<html>
<head>
<title>Test Execution Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.summary { background: #f5f5f5; padding: 15px; border-radius: 5px; }
.test-suite { margin: 10px 0; }
.test-case { padding: 5px; margin: 2px; }
.passed { background: #d4edda; }
.failed { background: #f8d7da; }
.skipped { background: #fff3cd; }
</style>
</head>
<body>
<h1>Test Execution Report</h1>
<div class="summary">
<h2>Summary</h2>
<p>Total Tests: ${results.totalTests}</p>
<p>Passed: ${results.passed}</p>
<p>Failed: ${results.failed}</p>
<p>Skipped: ${results.skipped}</p>
<p>Success Rate: ${((results.passed / results.totalTests) * 100).toFixed(2)}%</p>
</div>
${this.buildTestSuitesContent(results.suites)}
</body>
</html>`;
}
private buildTestSuitesContent(suites: TestSuiteResult[]): string {
return suites.map(suite => `
<div class="test-suite">
<h3>${suite.name}</h3>
${suite.testCases.map(testCase => `
<div class="test-case ${testCase.status}">
<strong>${testCase.name}</strong>: ${testCase.status}
${testCase.error ? `<br><em>Error: ${testCase.error}</em>` : ''}
${testCase.duration ? `<br>Duration: ${testCase.duration}ms` : ''}
</div>
`).join('')}
</div>
`).join('');
}
private async ensureDirectoryExists(path: string): Promise<void> {
try {
await mkdir(path, { recursive: true });
} catch (error) {
console.warn(`Directory creation failed: ${error.message}`);
}
}
}
9. 最佳实践与建议
9.1 测试策略建议
- 测试金字塔遵循:70%单元测试,20%集成测试,10%UI测试
- 及时测试:编写代码的同时编写测试用例
- 覆盖率目标:关键业务代码达到80%以上覆盖率
- Mock适度使用:只Mock外部依赖,避免过度Mock
- 定期重构测试:保持测试代码的整洁和可维护性
9.2 常见问题解决
// 常见测试问题解决方案
import { describe, it, expect } from '@ohos/hypium';
describe('Troubleshooting Guide', () => {
// 1. 异步测试超时问题
it('should_handle_async_timeouts', 0, async () => {
// 增加超时时间
this.timeout(5000); // 5秒超时
await someAsyncOperation();
expect(true).assertTrue();
});
// 2. 测试依赖顺序问题
it('should_run_independently', 0, () => {
// 确保每个测试都是独立的
// 使用beforeEach/afterEach重置状态
});
// 3. 浮动点数比较
it('should_compare_floating_point_numbers', 0, () => {
const result = 0.1 + 0.2;
// 使用近似比较而不是精确相等
expect(result).assertCloseTo(0.3, 0.0001);
});
// 4. 测试随机性
it('should_handle_randomness', 0, () => {
// 设置随机种子或Mock随机数生成器
mock(Math, 'random').mockReturnValue(0.5);
const randomValue = Math.random();
expect(randomValue).assertEqual(0.5);
});
});
通过本指南,您应该能够建立完整的HarmonyOS应用测试体系,从单元测试到UI自动化测试,从性能测试到持续集成。记住良好的测试实践是高质量软件开发的基石。
需要参加鸿蒙认证的请点击 鸿蒙认证链接