# 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. 安装依赖 ```bash cd everything-is-suitable-test npm install ``` ### 2. 启动Uniapp应用 在另一个终端中启动Uniapp应用: ```bash cd ../everything-is-suitable-uniapp npm run dev:h5 ``` ### 3. 运行测试 ```bash # 运行所有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. 查看测试报告 ```bash # 查看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 所有页面对象的基类,提供通用的页面操作方法: ```typescript 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 万年历页面对象: ```typescript 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 黄历页面对象: ```typescript import { AlmanacPage } from './pages/almanac-page'; const almanacPage = new AlmanacPage(page); await almanacPage.navigate(); await almanacPage.clickNextDate(); const almanacInfo = await almanacPage.getAllAlmanacInfo(); ``` ### UserPage 用户中心页面对象: ```typescript import { UserPage } from './pages/user-page'; const userPage = new UserPage(page); await userPage.navigate(); const userName = await userPage.getUserName(); await userPage.clickMenuItem(0); ``` ### BottomNavigation 底部导航栏对象: ```typescript 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`生成自定义报告: ```typescript 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`: 应用基础URL - `projects`: 浏览器项目配置 - `webServer`: 开发服务器配置 ### 环境变量 - `BASE_URL`: 应用基础URL - `CI`: 是否在CI环境中运行 - `NODE_ENV`: Node环境 ## 最佳实践 ### 1. 测试用例编写 - 使用描述性的测试名称 - 遵循AAA模式(Arrange-Act-Assert) - 使用页面对象而不是直接操作元素 - 添加适当的等待和断言 ```typescript test('应该能够切换到黄历页面', async ({ page }) => { await calendarPage.navigate(); await bottomNavigation.clickTab('almanac'); const title = await page.title(); expect(title).toContain('黄历'); }); ``` ### 2. 页面对象使用 - 将选择器封装在页面对象中 - 实现业务逻辑方法 - 保持页面对象的独立性 ```typescript 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捕获错误 - 使用测试日志记录错误信息 - 在测试失败时截图 ```typescript 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的自动等待机制 ```typescript await page.waitForLoadState('networkidle'); await page.waitForSelector('.element', { state: 'visible' }); ``` ## 故障排查 ### 测试失败时的调试 1. 查看测试日志:控制台输出 2. 查看截图:`test-results/uniapp-artifacts/` 3. 查看测试报告:`npm run test:e2e:uniapp:report` 4. 使用调试模式运行:`npm run test:e2e:uniapp:debug` ### 常见问题 1. **元素未找到** - 检查选择器是否正确 - 确保元素已加载 - 使用适当的等待策略 2. **测试超时** - 增加超时配置 - 检查网络请求是否正常 - 优化测试等待策略 3. **应用未启动** - 确保Uniapp应用已启动 - 检查端口是否正确 - 查看应用日志 ## CI/CD集成 ### GitHub Actions示例 ```yaml 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/ ``` ## 扩展开发 ### 添加新的页面对象 1. 在`pages/`目录下创建新的页面类 2. 继承`BasePage`类 3. 实现页面特定的方法和选择器 ```typescript import { BasePage } from './base-page'; export class NewPage extends BasePage { private readonly selectors = { // 页面选择器 }; async navigate() { await this.navigate('/pages/new/index'); } async doSomething() { // 页面方法 } } ``` ### 添加新的测试用例 1. 在`e2e/uniapp/`目录下创建新的测试文件 2. 使用`test.describe`组织测试用例 3. 使用页面对象进行测试 ```typescript 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默认支持并行执行测试,可以通过配置文件调整: ```typescript export default defineConfig({ workers: 4, fullyParallel: true, }); ``` ### 测试隔离 确保每个测试用例都是独立的,避免测试之间的依赖: ```typescript test.beforeEach(async ({ page }) => { await page.goto('/'); }); test.afterEach(async ({ page }) => { await page.close(); }); ``` ### 重试机制 配置测试失败时的重试次数: ```typescript export default defineConfig({ retries: 2, }); ``` ## 总结 本E2E测试工具提供了完整的Uniapp应用端到端测试解决方案,包括: - ✅ 模块化的测试用例编写 - ✅ 统一的测试环境配置 - ✅ 常用测试操作的封装与复用 - ✅ 清晰的测试报告与日志输出 - ✅ 页面对象模型(POM) - ✅ 多浏览器支持 - ✅ 跨平台兼容性测试 - ✅ 自动化测试执行流程 - ✅ 详细的测试报告生成 通过使用本工具,可以高效地编写、执行和维护E2E测试,确保应用的质量和稳定性。