14 KiB
14 KiB
测试框架重构设计文档
概述
本文档描述了将现有的E2E测试框架和开发环境测试脚本整合为一个统一、可复用的测试框架的设计方案。
目标
- 统一技术栈 - 所有测试使用Playwright + TypeScript
- 代码复用 - 创建共享的页面对象、配置和工具类
- 类型安全 - 利用TypeScript提供完整的类型检查
- 渐进式迁移 - 保持现有测试稳定的同时逐步整合
- 可维护性 - 提高测试代码的可维护性和可扩展性
当前状态分析
现有测试系统
1. E2E测试框架 (e2e/)
- 技术栈: Playwright + TypeScript
- 结构:
- 页面对象模式 (BasePage, HomePage等)
- 测试分类 (smoke, regression, performance等)
- Fixtures和配置管理
- 完整的测试报告系统
- 优势:
- 成熟的页面对象模式
- 丰富的测试覆盖
- 良好的类型安全
- 劣势:
- 部分工具类功能重复
- 配置分散
2. 开发环境测试脚本 (scripts/)
- 技术栈: Node.js + JavaScript
- 结构:
- 独立的脚本文件
- 工具类 (lighthouse-runner, axe-runner等)
- Shell脚本执行器
- 优势:
- 快速执行
- 专注于性能、SEO、可访问性
- 劣势:
- 缺乏类型安全
- 代码复用性低
- 与E2E测试隔离
重构架构设计
整体架构
test-framework/
├── shared/ # 共享层
│ ├── config/ # 配置管理
│ │ ├── base.config.ts # 基础配置
│ │ ├── environments.ts # 环境配置
│ │ ├── test-pages.ts # 测试页面配置
│ │ └── test-data.ts # 测试数据配置
│ ├── pages/ # 页面对象(统一)
│ │ ├── BasePage.ts # 基础页面对象
│ │ ├── HomePage.ts # 首页
│ │ ├── AboutPage.ts # 关于页面
│ │ ├── ContactPage.ts # 联系页面
│ │ ├── ProductsPage.ts # 产品页面
│ │ ├── ServicesPage.ts # 服务页面
│ │ ├── CasesPage.ts # 案例页面
│ │ └── NewsPage.ts # 新闻页面
│ ├── utils/ # 工具类
│ │ ├── performance/ # 性能测试工具
│ │ │ ├── PerformanceMonitor.ts
│ │ │ ├── LighthouseRunner.ts
│ │ │ └── CoreWebVitals.ts
│ │ ├── seo/ # SEO测试工具
│ │ │ ├── SEOValidator.ts
│ │ │ ├── MetaTagChecker.ts
│ │ │ └── LinkValidator.ts
│ │ ├── accessibility/ # 可访问性测试工具
│ │ │ ├── AccessibilityTester.ts
│ │ │ ├── AxeRunner.ts
│ │ │ └── WCAGCompliance.ts
│ │ ├── forms/ # 表单测试工具
│ │ │ ├── FormTester.ts
│ │ │ ├── FieldValidator.ts
│ │ │ └── FormSubmitter.ts
│ │ ├── mobile/ # 移动端测试工具
│ │ │ ├── GestureSimulator.ts
│ │ │ ├── MobilePerformanceMonitor.ts
│ │ │ └── NetworkSimulator.ts
│ │ ├── reporting/ # 报告生成工具
│ │ │ ├── TestReporter.ts
│ │ │ ├── HTMLReportGenerator.ts
│ │ │ └── JSONReportGenerator.ts
│ │ └── common/ # 通用工具
│ │ ├── TestDataGenerator.ts
│ │ ├── WaitHelper.ts
│ │ └── ScreenshotHelper.ts
│ ├── fixtures/ # 共享Fixtures
│ │ ├── base.fixture.ts # 基础fixture
│ │ ├── performance.fixture.ts # 性能测试fixture
│ │ ├── accessibility.fixture.ts # 可访问性测试fixture
│ │ └── mobile.fixture.ts # 移动端测试fixture
│ └── types/ # 类型定义
│ ├── page.types.ts # 页面对象类型
│ ├── test.types.ts # 测试类型
│ ├── performance.types.ts # 性能测试类型
│ └── accessibility.types.ts # 可访问性测试类型
│
├── e2e/ # E2E测试(保持不变)
│ ├── tests/
│ │ ├── smoke/ # 冒烟测试
│ │ ├── regression/ # 回归测试
│ │ ├── performance/ # 性能测试
│ │ ├── accessibility/ # 可访问性测试
│ │ ├── mobile/ # 移动端测试
│ │ ├── security/ # 安全测试
│ │ ├── visual/ # 视觉回归测试
│ │ └── responsive/ # 响应式测试
│ ├── fixtures/
│ └── playwright.config.ts
│
├── dev-audit/ # 开发环境测试(重构)
│ ├── performance/
│ │ ├── performance.spec.ts # 性能审计测试
│ │ ├── lighthouse.spec.ts # Lighthouse测试
│ │ └── core-web-vitals.spec.ts # Core Web Vitals测试
│ ├── seo/
│ │ ├── seo.spec.ts # SEO检查测试
│ │ ├── meta-tags.spec.ts # Meta标签测试
│ │ └── links.spec.ts # 链接检查测试
│ ├── accessibility/
│ │ ├── accessibility.spec.ts # 可访问性测试
│ │ └── wcag-compliance.spec.ts # WCAG合规测试
│ └── forms/
│ ├── forms.spec.ts # 表单验证测试
│ └── validation.spec.ts # 字段验证测试
│
└── reports/ # 测试报告
├── html/ # HTML报告
├── json/ # JSON报告
└── screenshots/ # 截图
核心设计原则
1. 页面对象统一
所有测试使用相同的页面对象,确保测试的一致性和可维护性。
// shared/pages/BasePage.ts
export class BasePage {
readonly page: Page;
readonly config: TestConfig;
constructor(page: Page, config?: TestConfig) {
this.page = page;
this.config = config || defaultConfig;
}
// 通用方法
async navigate(url: string): Promise<void> { }
async click(locator: Locator | string): Promise<void> { }
async fill(locator: Locator | string, value: string): Promise<void> { }
// 性能监控方法
async measurePerformance(): Promise<PerformanceMetrics> { }
async getCoreWebVitals(): Promise<CoreWebVitals> { }
// 可访问性方法
async runAccessibilityCheck(): Promise<AccessibilityResult> { }
// SEO方法
async validateSEO(): Promise<SEOResult> { }
}
2. 配置集中管理
所有配置集中管理,便于维护和切换环境。
// shared/config/environments.ts
export const environments = {
development: {
baseURL: 'http://localhost:3000',
timeout: 5000,
retries: 3
},
staging: {
baseURL: 'https://staging.example.com',
timeout: 10000,
retries: 2
},
production: {
baseURL: 'https://www.example.com',
timeout: 10000,
retries: 1
}
};
// shared/config/test-pages.ts
export const testPages = {
home: { name: '首页', url: '/', selectors: { title: 'h1' } },
about: { name: '关于我们', url: '/about', selectors: { title: 'h1' } },
contact: { name: '联系我们', url: '/contact', selectors: { title: 'h1' } },
products: { name: '产品', url: '/products', selectors: { title: 'h1' } },
services: { name: '服务', url: '/services', selectors: { title: 'h1' } },
cases: { name: '案例', url: '/cases', selectors: { title: 'h1' } },
news: { name: '新闻', url: '/news', selectors: { title: 'h1' } }
};
3. 工具类复用
创建可复用的工具类,避免代码重复。
// shared/utils/performance/PerformanceMonitor.ts
export class PerformanceMonitor {
async measurePageLoad(page: Page): Promise<PageLoadMetrics> { }
async measureCoreWebVitals(page: Page): Promise<CoreWebVitals> { }
async measureResourceTiming(page: Page): Promise<ResourceTiming[]> { }
}
// shared/utils/accessibility/AccessibilityTester.ts
export class AccessibilityTester {
async runAxeScan(page: Page): Promise<AxeResults> { }
async checkWCAGCompliance(page: Page): Promise<WCAGResult> { }
async generateAccessibilityReport(results: AxeResults): Promise<string> { }
}
// shared/utils/seo/SEOValidator.ts
export class SEOValidator {
async validateMetaTags(page: Page): Promise<MetaTagResult> { }
async validateLinks(page: Page): Promise<LinkResult> { }
async validateHeadings(page: Page): Promise<HeadingResult> { }
}
4. 类型安全
使用TypeScript提供完整的类型定义。
// shared/types/performance.types.ts
export interface PerformanceMetrics {
loadTime: number;
domContentLoaded: number;
firstPaint: number;
firstContentfulPaint: number;
}
export interface CoreWebVitals {
largestContentfulPaint: number;
firstInputDelay: number;
cumulativeLayoutShift: number;
}
// shared/types/accessibility.types.ts
export interface AccessibilityResult {
score: number;
violations: Violation[];
passes: number;
incomplete: number;
}
export interface Violation {
id: string;
impact: string;
description: string;
help: string;
helpUrl: string;
nodes: number;
}
// shared/types/test.types.ts
export interface TestConfig {
baseURL: string;
timeout: number;
retries: number;
environment: string;
}
export interface TestResult {
name: string;
status: 'passed' | 'failed' | 'skipped';
duration: number;
errors?: Error[];
}
实施计划
阶段1:创建共享层(不破坏现有测试)
目标: 创建共享的基础层,为后续迁移做准备
任务:
- 创建
test-framework/shared/目录结构 - 提取E2E测试中的页面对象到shared层
- 创建统一的配置管理系统
- 创建工具类框架
- 创建类型定义
时间估计: 2-3天
验收标准:
- 共享层目录结构创建完成
- 页面对象迁移完成
- 配置管理系统创建完成
- 工具类框架创建完成
- 类型定义创建完成
- 现有E2E测试仍然正常运行
阶段2:迁移开发环境测试
目标: 将开发环境测试迁移到TypeScript和Playwright
任务:
- 创建
test-framework/dev-audit/目录结构 - 将性能审计脚本迁移到TypeScript
- 将SEO检查脚本迁移到TypeScript
- 将可访问性测试迁移到TypeScript
- 将表单验证迁移到TypeScript
- 使用共享的页面对象和工具类
- 保留scripts/作为向后兼容
时间估计: 3-4天
验收标准:
- 所有开发环境测试迁移完成
- 使用TypeScript重写
- 使用Playwright API
- 使用共享的页面对象
- 使用共享的工具类
- 测试结果与原有脚本一致
- 旧scripts/仍然可用
阶段3:优化和清理
目标: 优化测试框架,移除冗余代码
任务:
- 移除旧的scripts/目录
- 统一测试报告格式
- 添加共享的测试数据生成器
- 优化测试执行性能
- 添加测试覆盖率统计
- 更新文档
时间估计: 2-3天
验收标准:
- 旧scripts/目录移除
- 测试报告格式统一
- 测试数据生成器创建完成
- 测试执行性能优化
- 测试覆盖率统计添加
- 文档更新完成
阶段4:集成和验证
目标: 验证整个测试框架的集成和功能
任务:
- 运行完整的测试套件
- 验证所有测试结果
- 性能基准测试
- 创建CI/CD集成
- 编写使用文档
时间估计: 2-3天
验收标准:
- 完整测试套件运行成功
- 所有测试结果验证通过
- 性能基准测试完成
- CI/CD集成完成
- 使用文档编写完成
测试执行流程
E2E测试执行
# 运行所有E2E测试
npm run test:e2e
# 运行特定类型的E2E测试
npm run test:e2e:smoke
npm run test:e2e:regression
npm run test:e2e:performance
开发环境测试执行
# 运行所有开发环境测试
npm run test:dev-audit
# 运行特定类型的开发环境测试
npm run test:dev-audit:performance
npm run test:dev-audit:seo
npm run test:dev-audit:accessibility
npm run test:dev-audit:forms
综合测试执行
# 运行所有测试
npm run test:all
# 生成综合报告
npm run test:report
测试报告
报告格式
- HTML报告 - 可视化的测试报告,包含图表和详细信息
- JSON报告 - 机器可读的测试结果,便于CI/CD集成
- 截图 - 测试失败时的截图,便于调试
报告内容
- 测试摘要(总数、通过数、失败数、跳过数)
- 测试详情(每个测试的执行时间、状态、错误信息)
- 性能指标(页面加载时间、Core Web Vitals等)
- 可访问性评分(WCAG合规性、违规项等)
- SEO评分(Meta标签、链接、标题等)
- 表单验证结果(必填字段、格式验证等)
风险和缓解措施
风险1:迁移过程中破坏现有测试
缓解措施:
- 采用渐进式迁移策略
- 每个阶段都进行完整的测试验证
- 保留原有测试作为备份
风险2:性能测试结果不一致
缓解措施:
- 建立性能基准
- 使用相同的测试环境
- 多次运行取平均值
风险3:学习曲线
缓解措施:
- 提供详细的文档
- 提供示例代码
- 进行团队培训
成功标准
- 功能完整性 - 所有现有测试功能在新框架中都能正常工作
- 性能提升 - 测试执行时间不超过原有框架的120%
- 代码质量 - TypeScript编译无错误,测试覆盖率不低于80%
- 可维护性 - 代码结构清晰,易于理解和维护
- 文档完整性 - 提供完整的文档和示例
总结
本设计文档提供了一个渐进式的测试框架重构方案,通过创建共享层、统一技术栈、提高代码复用性,最终实现一个统一、可维护、可扩展的测试框架。该方案采用渐进式迁移策略,确保在重构过程中不破坏现有测试,同时为未来的测试开发提供良好的基础。