08ea5fbe98
添加用户管理视图、API和状态管理文件
Uniapp E2E测试使用指南
概述
本E2E测试工具为everything-is-suitable-uniapp小程序提供全面的端到端测试解决方案,基于Playwright构建,支持多浏览器、多平台测试,并提供详细的测试报告。
目录结构
e2e/uniapp/
├── pages/ # 页面对象模型
│ ├── base-page.ts # 基础页面类
│ ├── calendar-page.ts # 万年历页面
│ ├── almanac-page.ts # 黄历页面
│ ├── user-page.ts # 用户中心页面
│ └── bottom-navigation.ts # 底部导航栏
├── navigation.spec.ts # 页面导航测试
├── calendar.spec.ts # 万年历页面测试
├── almanac.spec.ts # 黄历页面测试
├── user.spec.ts # 用户中心页面测试
├── data-loading.spec.ts # 数据加载测试
├── state-update.spec.ts # 状态更新测试
├── boundary.spec.ts # 边界条件测试
├── test-reporter.ts # 测试报告生成器
├── global-setup.ts # 全局测试设置
└── global-teardown.ts # 全局测试清理
快速开始
1. 安装依赖
cd everything-is-suitable-test
npm install
2. 启动Uniapp应用
在另一个终端中启动Uniapp应用:
cd ../everything-is-suitable-uniapp
npm run dev:h5
3. 运行测试
# 运行所有Uniapp E2E测试
npm run test:e2e:uniapp
# 运行特定测试文件
npx playwright test --config=playwright.uniapp.config.ts e2e/uniapp/navigation.spec.ts
# 运行特定测试用例
npx playwright test --config=playwright.uniapp.config.ts -g "底部导航栏切换测试"
# 调试模式运行
npm run test:e2e:uniapp:debug
# UI模式运行
npm run test:e2e:uniapp:ui
# 有头模式运行(显示浏览器)
npm run test:e2e:uniapp:headed
4. 查看测试报告
# 查看Playwright HTML报告
npm run test:e2e:uniapp:report
测试用例
页面导航测试 (navigation.spec.ts)
- TC-001: 底部导航栏切换测试
- TC-002: 页面标题显示测试
万年历页面测试 (calendar.spec.ts)
- TC-003: 日历月份切换测试
- TC-004: 日期选择测试
- TC-005: 农历信息显示测试
黄历页面测试 (almanac.spec.ts)
- TC-006: 黄历日期切换测试
- TC-007: 黄历信息显示测试
用户中心页面测试 (user.spec.ts)
- TC-008: 用户信息显示测试
- TC-009: 菜单导航测试
数据加载测试 (data-loading.spec.ts)
- TC-012: 黄历数据加载测试
- TC-013: 日历数据加载测试
状态更新测试 (state-update.spec.ts)
- TC-014: 选中日期状态更新测试
- TC-015: 导航栏状态更新测试
边界条件测试 (boundary.spec.ts)
- TC-016: 月份边界测试
- TC-017: 日期边界测试
- TC-018: 表单验证测试
页面对象模型
BasePage
所有页面对象的基类,提供通用的页面操作方法:
import { BasePage } from './pages/base-page';
const page = new BasePage(page);
await page.navigate('/pages/calendar/index');
await page.waitForLoad();
await page.clickElement('.button');
await page.fillInput('.input', 'value');
CalendarPage
万年历页面对象:
import { CalendarPage } from './pages/calendar-page';
const calendarPage = new CalendarPage(page);
await calendarPage.navigate();
await calendarPage.clickNextMonth();
await calendarPage.clickDay(15);
const lunarDate = await calendarPage.getLunarDate();
AlmanacPage
黄历页面对象:
import { AlmanacPage } from './pages/almanac-page';
const almanacPage = new AlmanacPage(page);
await almanacPage.navigate();
await almanacPage.clickNextDate();
const almanacInfo = await almanacPage.getAllAlmanacInfo();
UserPage
用户中心页面对象:
import { UserPage } from './pages/user-page';
const userPage = new UserPage(page);
await userPage.navigate();
const userName = await userPage.getUserName();
await userPage.clickMenuItem(0);
BottomNavigation
底部导航栏对象:
import { BottomNavigation } from './pages/bottom-navigation';
const bottomNavigation = new BottomNavigation(page);
await bottomNavigation.clickTab('almanac');
const isActive = await bottomNavigation.isTabActive('almanac');
测试报告
Playwright报告
Playwright自动生成HTML报告,包含:
- 测试执行摘要
- 每个测试的详细信息
- 失败测试的截图和视频
- 性能指标
自定义报告
使用test-reporter.ts生成自定义报告:
import { UniappTestReporter } from './test-reporter';
const reporter = new UniappTestReporter();
reporter.addTestSuite('测试套件名称', [
{
testName: '测试用例名称',
status: 'passed',
duration: 1000,
}
]);
await reporter.generateJSONReport('test-results/uniapp-report.json');
await reporter.generateHTMLReport('test-results/uniapp-report.html');
await reporter.generateMarkdownReport('test-results/uniapp-report.md');
配置
Playwright配置
配置文件:playwright.uniapp.config.ts
主要配置项:
testDir: 测试文件目录baseURL: 应用基础URLprojects: 浏览器项目配置webServer: 开发服务器配置
环境变量
BASE_URL: 应用基础URLCI: 是否在CI环境中运行NODE_ENV: Node环境
最佳实践
1. 测试用例编写
- 使用描述性的测试名称
- 遵循AAA模式(Arrange-Act-Assert)
- 使用页面对象而不是直接操作元素
- 添加适当的等待和断言
test('应该能够切换到黄历页面', async ({ page }) => {
await calendarPage.navigate();
await bottomNavigation.clickTab('almanac');
const title = await page.title();
expect(title).toContain('黄历');
});
2. 页面对象使用
- 将选择器封装在页面对象中
- 实现业务逻辑方法
- 保持页面对象的独立性
export class CalendarPage extends BasePage {
private readonly selectors = {
prevMonthButton: '[data-testid="prev-month"]',
nextMonthButton: '[data-testid="next-month"]',
};
async clickNextMonth() {
await this.clickElement(this.selectors.nextMonthButton);
await this.waitForLoad();
}
}
3. 测试数据管理
- 使用测试数据生成器
- 避免硬编码测试数据
- 使用测试夹具提供的预定义数据
4. 错误处理
- 在测试用例中使用try-catch捕获错误
- 使用测试日志记录错误信息
- 在测试失败时截图
test('测试用例', async ({ page }) => {
try {
await page.goto('/pages/calendar/index');
expect(await page.title()).toContain('万年历');
} catch (error) {
await page.screenshot({ path: 'test-failure.png' });
throw error;
}
});
5. 等待策略
- 使用页面对象提供的等待方法
- 避免使用固定的等待时间
- 使用Playwright的自动等待机制
await page.waitForLoadState('networkidle');
await page.waitForSelector('.element', { state: 'visible' });
故障排查
测试失败时的调试
- 查看测试日志:控制台输出
- 查看截图:
test-results/uniapp-artifacts/ - 查看测试报告:
npm run test:e2e:uniapp:report - 使用调试模式运行:
npm run test:e2e:uniapp:debug
常见问题
-
元素未找到
- 检查选择器是否正确
- 确保元素已加载
- 使用适当的等待策略
-
测试超时
- 增加超时配置
- 检查网络请求是否正常
- 优化测试等待策略
-
应用未启动
- 确保Uniapp应用已启动
- 检查端口是否正确
- 查看应用日志
CI/CD集成
GitHub Actions示例
name: Uniapp E2E Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm run test:e2e:uniapp
- uses: actions/upload-artifact@v3
if: failure()
with:
name: test-results
path: test-results/
扩展开发
添加新的页面对象
- 在
pages/目录下创建新的页面类 - 继承
BasePage类 - 实现页面特定的方法和选择器
import { BasePage } from './base-page';
export class NewPage extends BasePage {
private readonly selectors = {
// 页面选择器
};
async navigate() {
await this.navigate('/pages/new/index');
}
async doSomething() {
// 页面方法
}
}
添加新的测试用例
- 在
e2e/uniapp/目录下创建新的测试文件 - 使用
test.describe组织测试用例 - 使用页面对象进行测试
import { test, expect } from '@playwright/test';
import { NewPage } from './pages/new-page';
test.describe('新功能测试', () => {
test('应该能够执行新功能', async ({ page }) => {
const newPage = new NewPage(page);
await newPage.navigate();
await newPage.doSomething();
expect(await page.title()).toContain('新页面');
});
});
性能优化
并行执行
Playwright默认支持并行执行测试,可以通过配置文件调整:
export default defineConfig({
workers: 4,
fullyParallel: true,
});
测试隔离
确保每个测试用例都是独立的,避免测试之间的依赖:
test.beforeEach(async ({ page }) => {
await page.goto('/');
});
test.afterEach(async ({ page }) => {
await page.close();
});
重试机制
配置测试失败时的重试次数:
export default defineConfig({
retries: 2,
});
总结
本E2E测试工具提供了完整的Uniapp应用端到端测试解决方案,包括:
- ✅ 模块化的测试用例编写
- ✅ 统一的测试环境配置
- ✅ 常用测试操作的封装与复用
- ✅ 清晰的测试报告与日志输出
- ✅ 页面对象模型(POM)
- ✅ 多浏览器支持
- ✅ 跨平台兼容性测试
- ✅ 自动化测试执行流程
- ✅ 详细的测试报告生成
通过使用本工具,可以高效地编写、执行和维护E2E测试,确保应用的质量和稳定性。