Files
novalon-website/docs/test-strategy-plan.md
T
zhangxiang 553d7c0afb docs: update test strategy plan and README with Phase 5 completion status
- Document complete test suite implementation (Phase 1-5)
- Update test counts (992 tests) and coverage metrics (Branches 75.61%)
- Add k6 stress test verification results (91285 iterations, 0 errors)
- Add mutation score improvements (use-focus-trap 49.18%, use-swipe-gesture 33.06%)
- Update npm scripts documentation
2026-07-31 20:25:51 +08:00

1275 lines
51 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Novalon Website 系统化测试套件实施计划
> 版本:1.3
> 日期:2026-07-31
> 状态:✅ 全部完成(Phase 1-5 全部验证通过)
> 负责人:张翔(测试架构师)
---
## 目录
1. [系统评估报告](#1-系统评估报告)
2. [测试策略总览](#2-测试策略总览)
3. [测试类型与实施细节](#3-测试类型与实施细节)
4. [测试用例模板与评审机制](#4-测试用例模板与评审机制)
5. [分阶段实施时间表](#5-分阶段实施时间表)
6. [CI/CD 集成方案](#6-cicd-集成方案)
7. [覆盖率目标与质量指标](#7-覆盖率目标与质量指标)
8. [持续改进机制](#8-持续改进机制)
9. [附录](#9-附录)
---
## 1. 系统评估报告
### 1.1 架构概览
| 维度 | 详细信息 |
|------|----------|
| **框架** | Next.js 16 (App Router) — 混合渲染(SSG + SSR/ISR + API Routes |
| **UI 层** | React 18 + TypeScript 5 (strict mode, `noUncheckedIndexedAccess`) |
| **样式系统** | Tailwind CSS 3 + CSS 自定义属性令牌系统 |
| **动画** | Framer Motion 12 |
| **组件库** | shadcn/ui (Radix UI + CVA + tailwind-merge) |
| **后端** | Prisma + SQLiteadmin/auth/CMS 数据层) |
| **监控** | Sentry + GA4 |
| **部署** | Nginx 反向代理 + CDN`dist/` 构建输出) |
### 1.2 目录结构
```
src/
├── app/ # Next.js App Router 页面 & API
│ ├── (marketing)/ # 营销页面(首页/关于/产品/方案/服务/案例/新闻/联系/团队)
│ ├── admin/ # 管理后台(登录/内容/媒体/角色/区域)
│ ├── api/ # API 路由(auth/admin/cms/contact
│ ├── privacy/ & terms/ # 法律页面
│ └── layout.tsx # 根布局
├── components/ # 组件层
│ ├── ui/ # 基础 UI 组件(button/card/input/dialog 等)
│ ├── layout/ # 布局组件(header/footer/mobile-menu/breadcrumb
│ ├── sections/ # 页面区块(hero/service-grid/stats-bar 等)
│ ├── detail/ # 四层叙事组件(hero/value/trust/CTA
│ ├── seo/ # SEO 结构化数据
│ ├── analytics/ # 分析/追踪组件
│ ├── effects/ # 视觉效果组件(技术债务,大部分未使用)
│ └── cms/ # CMS 富文本编辑器
├── hooks/ # 自定义 Hooks(共 5 个)
├── lib/ # 工具库
│ ├── constants/ # 数据常量(products/services/solutions/cases 等)
│ ├── cms/ # CMS 数据层(types/workflow/notifications/data-server
│ ├── media/ # 媒体处理(image-processor/storage/media-service
│ └── 其他工具 # auth/analytics/utils/colors/animations 等
├── generated/prisma/ # Prisma 生成客户端
└── middleware.ts # Next.js 中间件
```
### 1.3 当前测试覆盖现状
#### 1.3.1 单元测试(Jest
| 指标 | 当前值 | 全局阈值 | 差距分析 |
|------|--------|----------|----------|
| **Branches** | 41.76% | 30% | ✅ 已超阈值 |
| **Functions** | 40.50% | 25% | ✅ 已超阈值 |
| **Lines** | 34.22% | 32% | ✅ 已超阈值 |
| **Statements** | 44.96% | 30% | ✅ 已超阈值 |
**测试总量**72 suites / 954 tests ✅ 全部通过
**目录级覆盖率亮点**
| 目录 | Branches | Functions | 评估 |
|------|----------|-----------|------|
| `lib/cms/` | 80% | 75% | 🟢 优秀 |
| `lib/constants/` | 88% | 45% | 🟡 常量数据覆盖好,函数覆盖待提升 |
| `hooks/` | 38% | 60% | 🟢 良好 |
| `lib/` | 40% | 45% | 🟡 中等 |
| `components/layout/` | 45% | 35% | 🟡 中等 |
| `components/detail/` | 25% | 22% | 🔴 待提升 |
| `components/sections/` | 30% | 18% | 🔴 待提升 |
| `components/ui/` | 18% | 10% | 🔴 待大幅提升 |
| `components/seo/` | 0% | 18% | 🔴 待大幅提升 |
| `components/content/` | 4% | 4% | 🔴 待大幅提升 |
**已覆盖的单元测试文件**81 个 `.test.ts/tsx` 文件
**单元测试覆盖缺口**(关键模块):
- `src/lib/analytics.ts` — 分析追踪逻辑
- `src/lib/auth.ts` — 认证服务(已有部分测试)
- `src/lib/crypto.ts` — 加密工具
- `src/lib/media/` — 媒体处理(已有 storage/image-processor/media-service 测试,但覆盖率不足)
- `src/components/ui/` — 大量 UI 组件缺少测试(alert, checkbox, dialog, dropdown-menu, form, label, select, tabs 等)
- `src/components/analytics/` — 分析组件全部未覆盖
- `src/components/effects/` — 特效组件全部未覆盖
- `src/components/cms/` — CMS 编辑器组件未覆盖
#### 1.3.2 E2E 测试(Playwright
| 测试套件 | 文件 | 测试数 | 状态 |
|----------|------|--------|------|
| P1 品牌视觉审计 | `p1-brand-visual-audit.spec.ts` | ~15 | ✅ 通过 |
| P2 功能 E2E | `p2-functional-e2e.spec.ts` | ~80 | ✅ 通过 |
| P3 兼容性 | `p3-compatibility.spec.ts` | ~10 | ✅ 通过 |
| P4 性能与可访问性 | `p4-performance-a11y.spec.ts` | ~10 | ✅ 通过 |
| P5 边缘情况 | `p5-edge-cases.spec.ts` | ~15 | ✅ 通过 |
| P6 缺失路径 | `p6-missing-paths.spec.ts` | ~10 | ✅ 通过 |
| 案例筛选 | `cases-filter.spec.ts` | ~5 | ✅ 通过 |
| CMS 工作流 | `cms-workflow.spec.ts` | 3 | ✅ 通过 |
| 导航下拉菜单 | `nav-dropdown.spec.ts` | ~5 | ✅ 通过 |
| 备案号验证 | `footer-beian-verify.spec.ts` | ~2 | ✅ 通过 |
| 网站验收 | `website-acceptance.spec.ts` | ~10 | ✅ 通过 |
| 视觉回归 | `visual-regression.spec.ts` | ~105 (×5 项目) | ✅ 通过 |
**总 E2E**631 passed / 8 skipped / 0 failed
**E2E 测试覆盖缺口**
- 缺少用户旅程测试(跨页面、跨导航的完整业务场景)
- 缺少移动端独立的 E2E 测试(已有响应式断言,但无专项移动端流程)
- 缺少 API 层集成测试(已有 API route unit tests,但无端到端 API 测试)
- 缺少表单转换/GA4 事件验证的 E2E 测试
- 缺少 404/500 错误页面的用户反馈验证
#### 1.3.3 性能测试(k6
| 测试类型 | 结果 | 指标 |
|----------|------|------|
| 负载测试 | ✅ 通过 | p95=19.18ms < 500ms, 错误率 0% < 1% |
| 压力测试 | ⚠️ 脚本问题 | p95=123.48ms < 1000ms, 但错误率 66.7%(脚本缺陷) |
**性能测试缺口**
- 压力测试脚本需要修复适配
- 缺少 API 接口的专项性能测试
- 缺少数据库查询性能基线
- 缺少长时间稳定性测试(Soak Test)
#### 1.3.4 视觉回归测试
| 项目 | 快照数 | 状态 |
|------|--------|------|
| visual-chromium-desktop | 105 | ✅ |
| visual-chromium-tablet | 105 | ✅ |
| visual-chromium-mobile | 105 | ✅ |
| visual-firefox-desktop | 105 | ✅ |
| visual-webkit-desktop | 105 | ✅ |
#### 1.3.5 可访问性 & Lighthouse
| 检查项 | 结果 |
|--------|------|
| 颜色对比度 | ✅ 通过 |
| 标题层级 | ✅ 通过 |
| Lighthouse 性能 | ✅ ≥0.9 |
| Lighthouse 可访问性 | ✅ ≥0.9 |
| Lighthouse 最佳实践 | ✅ ≥0.9 |
| Lighthouse SEO | ✅ ≥0.9 |
### 1.4 现有 CI/CD 流水线
```
Jenkins Pipeline (Gitea Webhook 触发)
├── 🔧 环境检测与准备
├── 📥 安装依赖
├── 🔍 代码质量检查(并行:ESLint + TypeScript
├── 🧪 单元测试(coverage check + HTML report
├── 🏗️ 构建 dist
└── 🚀 部署到生产环境(main 分支 + 手动确认)
```
**CI/CD 缺口**
- ❌ Jenkins 流水线中**未包含 E2E 测试**阶段
- ❌ 无视觉回归测试自动化
- ❌ 无性能测试门禁
- ❌ 无可访问性检查自动执行
- ❌ 无安全扫描集成
- ❌ 测试报告未集成 Allure 等可视化框架
- ❌ 无变异测试集成
### 1.5 业务流程关键路径
```
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ 营销页面访问 │ ──▶ │ 导航与路由 │ ──▶ │ 内容浏览 │
│ (公开页面) │ │ (主导航/下拉) │ │ (产品/方案/ │
│ │ │ │ │ 服务/案例) │
└───────────────┘ └───────────────┘ └───────────────┘
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ CMS 内容管理 │ ◀── │ 管理员登录 │ ◀── │ 联系表单提交 │
│ (CRUD/工作流) │ │ (认证/权限) │ │ (验证/转换) │
└───────────────┘ └───────────────┘ └───────────────┘
┌───────────────┐ ┌───────────────┐
│ ISR 缓存刷新 │ ──▶ │ 前台内容可见 │
│ (CMS 发布后) │ │ (增量静态再生成)│
└───────────────┘ └───────────────┘
```
---
## 2. 测试策略总览
### 2.1 测试金字塔模型
```
╱╲
╱ ╲ 变异测试 (Mutation)
╱ ╲ ─────────────────
╱ E2E ╲ 用户旅程测试 (User Journey)
& ╲ ─────────────────
╱ 视觉回归 ╲ 端到端测试 (E2E)
╱────────────╲ ─────────────────
╱ ╲ 集成测试 (Integration)
╱────────────────╲ ─────────────────
╱ ╲ 单元测试 (Unit)
╱════════════════════╲─────────────────
```
### 2.2 测试层级定义
| 层级 | 测试类型 | 执行频率 | 执行时间目标 | 失败策略 |
|------|----------|----------|-------------|----------|
| **L0** | 静态分析(ESLint + TypeScript | 每次提交 | < 2min | 阻塞 |
| **L1** | 单元测试(Jest | 每次提交 | < 3min | 阻塞 |
| **L2** | 集成测试(API Routes + 组件集成) | 每次推送 | < 5min | 阻塞 |
| **L3** | E2E + 用户旅程测试 | PR 合并前 | < 15min | 阻塞 |
| **L4** | 视觉回归 + 跨浏览器兼容性 | PR 合并前 | < 10min | 非阻塞 |
| **L5** | 性能测试(k6 + Lighthouse | 每日/发布前 | < 20min | 非阻塞 |
| **L6** | 安全扫描 + 变异测试 | 每周/发布前 | < 30min | 非阻塞 |
### 2.3 测试类型选型矩阵
| 测试类型 | 工具 | 适用场景 | 当前状态 | 优先级 |
|----------|------|----------|----------|--------|
| **单元测试** | Jest + React Testing Library + ts-jest | 纯函数、Hooks、工具函数、UI 组件 | ✅ 已建立,954 tests | P0 |
| **组件集成测试** | React Testing Library + Jest | 组件组合交互、表单验证、状态流转 | 🔶 部分覆盖 | P0 |
| **API 集成测试** | Jest + Supertest 或 Playwright API | API Routes 业务逻辑、认证、鉴权 | 🔶 部分覆盖(API route unit tests | P0 |
| **E2E 测试** | Playwright | 关键用户路径、核心功能流程 | ✅ 已建立,631 tests | P0 |
| **用户旅程测试** | Playwright | 跨页面完整业务流程(如:浏览→联系→提交) | ❌ 缺失 | P1 |
| **视觉回归测试** | Playwright toHaveScreenshot | UI 一致性、品牌视觉合规 | ✅ 已建立,105 snapshots | P0 |
| **跨浏览器测试** | Playwright Chromium/Firefox/WebKit | 浏览器兼容性 | ✅ 已建立 | P0 |
| **响应式测试** | Playwright 多视口 | 设备适配 | ✅ 已建立 | P0 |
| **可访问性测试** | axe-core + Playwright | WCAG 2.1 AA 合规 | ✅ 已建立 | P0 |
| **性能测试** | k6 + Lighthouse | 负载/压力/性能基线 | 🔶 部分覆盖(load test 通过,stress test 脚本需修复) | P1 |
| **安全测试** | npm audit + OWASP ZAP 或自定义脚本 | 依赖漏洞、安全头、XSS/CSRF | 🔶 部分覆盖(npm audit + 安全头检查) | P1 |
| **变异测试** | Stryker Mutator | 测试质量验证(测试是否能捕获代码变异) | ❌ 缺失 | P2 |
| **CMS 工作流测试** | Playwright | 内容发布、审核、权限分离 | ✅ 已建立 | P0 |
| **GA4 事件追踪测试** | Playwright + 网络拦截 | 分析事件触发正确性 | ❌ 缺失 | P1 |
---
## 3. 测试类型与实施细节
### 3.1 单元测试(Unit Testing
#### 3.1.1 适用范围
| 模块 | 优先级 | 当前覆盖率 | 目标覆盖率 | 测试重点 |
|------|--------|-----------|-----------|----------|
| `src/lib/utils.ts` | P0 | 高 | 90% | 工具函数(cn, formatDate, truncate 等) |
| `src/lib/constants/*` | P0 | 85-94% | 90% | 数据完整性、结构正确性 |
| `src/lib/cms/*` | P0 | 60-80% | 85% | 工作流状态机、通知、数据查询 |
| `src/lib/auth.ts` | P0 | 中 | 80% | 认证逻辑、Token 管理 |
| `src/lib/analytics.ts` | P1 | 低 | 70% | 事件追踪、转换跟踪 |
| `src/lib/colors.ts` | P0 | 高 | 90% | 颜色工具函数 |
| `src/lib/animations.tsx` | P1 | 中 | 75% | 动画变体配置 |
| `src/hooks/*` | P0 | 38-60% | 80% | 5 个自定义 Hooks |
| `src/components/ui/*` | P0 | 10-18% | 60% | 基础 UI 组件行为 |
| `src/components/layout/*` | P0 | 35-59% | 70% | 布局组件交互 |
| `src/components/sections/*` | P1 | 18-30% | 50% | 业务区块渲染 |
| `src/components/detail/*` | P1 | 22-29% | 50% | 四层叙事组件 |
| `src/components/seo/*` | P1 | 0-18% | 50% | 结构化数据 |
| `src/components/content/*` | P2 | 4% | 40% | 内容渲染组件 |
| `src/components/analytics/*` | P2 | 0% | 40% | 分析组件 |
| `src/lib/media/*` | P1 | 中 | 70% | 媒体处理、存储、图片处理 |
| `src/lib/permissions.ts` | P0 | 中 | 80% | 权限检查逻辑 |
| `src/components/cms/*` | P2 | 0% | 40% | CMS 编辑器 |
#### 3.1.2 技术选型与工具配置
**当前工具链**
- 框架:Jest 30
- 渲染器:ts-jestjsx: 'react-jsx'
- 环境:jsdom
- 断言:@testing-library/jest-dom
- 路径别名:`@/``src/`
**增强配置建议**
```javascript
// config/test/jest.config.js(增强后)
module.exports = {
// ...现有配置保持不变
// 新增:集成测试配置
projects: [
{
displayName: 'unit',
testMatch: ['<rootDir>/src/**/*.test.{ts,tsx}'],
testPathIgnorePatterns: ['/api/.*route\\.test\\.ts'],
},
{
displayName: 'integration',
testMatch: ['<rootDir>/src/app/api/**/*.test.{ts,tsx}'],
testEnvironment: 'node',
},
],
};
```
#### 3.1.3 测试用例分类
| 类别 | 描述 | 示例 |
|------|------|------|
| **纯函数测试** | 输入→输出验证 | `utils.ts`, `colors.ts`, `constants.ts` |
| **Hooks 测试** | 状态管理、副作用 | `use-count-up`, `use-focus-trap`, `use-swipe-gesture` |
| **组件渲染测试** | 默认渲染、Props 变化 | Button, Card, Input, Badge |
| **组件交互测试** | 用户事件、状态变更 | 表单提交、点击、悬停 |
| **组件状态测试** | 加载/空/错误/边缘状态 | LoadingSkeleton, ErrorBoundary |
| **API Route 测试** | 请求处理、认证、鉴权 | admin/items, auth/login, cms/revalidate |
| **业务逻辑测试** | 工作流、状态机、权限 | CMS workflow, RBAC permissions |
### 3.2 集成测试(Integration Testing
#### 3.2.1 适用范围
| 集成点 | 测试范围 | 工具 | 优先级 |
|--------|----------|------|--------|
| **API Routes + Prisma** | CRUD 操作、认证鉴权、权限检查 | Jest + Prisma mock | P0 |
| **组件 + CMS 数据层** | 组件渲染 CMS 数据,Server Components 数据流 | Jest + data-server mock | P0 |
| **表单 + Server Actions** | 联系表单验证、提交、GA4 事件 | Jest + React Testing Library | P0 |
| **中间件 + API Routes** | 认证中间件、CORS、安全头 | Jest + NextRequest mock | P1 |
| **CMS 工作流 + 通知** | 状态流转、权限校验、通知生成 | Jest | P0 |
| **媒体上传 + 存储** | 文件上传、S3/本地双写、缩略图生成 | Jest + mocks | P1 |
#### 3.2.2 实施策略
```
API Route 集成测试架构:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Test Runner │ ──▶ │ API Route │ ──▶ │ Prisma Mock │
│ (Jest) │ ◀── │ (Next.js) │ ◀── │ (in-memory) │
└──────────────┘ └──────────────┘ └──────────────┘
┌──────────────┐
│ Auth Mock │
│ (JWT 验证) │
└──────────────┘
```
**关键改进点**
- 将 Prisma mock 从全局 `jest.setup.js` 迁移为每个测试文件可定制化的 mock
- 引入 `@prisma/inmemory` 或类似的轻量级内存数据库做真实查询测试
- 为 API Routes 增加请求/响应序列化测试
### 3.3 端到端测试(E2E Testing
#### 3.3.1 适用范围
| 测试模块 | 现有覆盖 | 需要补充 | 优先级 |
|----------|----------|----------|--------|
| **首页** | ✅ Hero/产品/解决方案/CTA/信任标识 | 深色主题切换 | P0 |
| **导航** | ✅ 下拉菜单/链接/响应式 | 键盘导航、搜索功能(如有) | P0 |
| **产品页面** | ✅ 列表/详情 | 筛选/排序、技术规格标签 | P0 |
| **解决方案** | ✅ 列表/详情 | 跨产品推荐链接 | P0 |
| **服务页面** | ✅ 列表/详情 | 服务流程交互 | P0 |
| **案例页面** | ✅ 筛选/详情 | 空筛选状态、分页 | P0 |
| **新闻页面** | ✅ 列表/详情 | 分类筛选、搜索 | P0 |
| **联系表单** | ✅ 提交/验证 | 蜜罐字段验证、数学验证码、转换事件 | P0 |
| **团队页面** | ✅ 渲染 | 团队成员详情弹窗 | P1 |
| **法律页面** | ✅ 隐私/条款 | 内容展开/折叠 | P1 |
| **CMS 管理后台** | ✅ 工作流/权限 | 媒体管理、角色管理、区域管理 | P0 |
| **错误页面** | 🔶 部分覆盖 | 404 导航、500 恢复 | P1 |
| **移动端 E2E** | ⚠️ 仅在响应式中覆盖 | 专门的移动端流程测试 | P1 |
#### 3.3.2 执行策略
```
E2E 测试分层执行:
Fast Tier (每次提交, <5min):
├── @smoke: 首页加载、导航、联系表单
├── @critical: 核心用户路径
└── @api: 关键 API 端点健康检查
Standard Tier (PR 合并前, <15min):
├── @regression: 全功能回归
├── @cms: CMS 工作流
└── @a11y: 可访问性检查
Deep Tier (每日/发布前, <30min):
├── @visual: 全量视觉回归
├── @cross-browser: 跨浏览器
├── @responsive: 响应式
└── @performance: 性能基线
```
### 3.4 用户旅程测试(User Journey Testing
#### 3.4.1 用户旅程场景定义
| 旅程 ID | 用户角色 | 场景路径 | 关键验证点 | 优先级 |
|---------|----------|----------|-----------|--------|
| **UJ-01** | 潜在客户 | 首页 → 产品 → 产品详情 → 联系表单 → 提交成功 | 导航连续性、产品信息展示、表单提交 | P0 |
| **UJ-02** | 行业客户 | 首页 → 解决方案 → 方案详情 → 推荐产品 → 产品详情 | HSI 架构导航、交叉推荐、产品组合 | P0 |
| **UJ-03** | 内容管理员 | 登录 → 后台 → 创建内容 → 提交审核 → 审核通过 → 前台可见 | 认证、CRUD、工作流、ISR 刷新 | P0 |
| **UJ-04** | 新闻读者 | 首页 → 新闻列表 → 新闻详情 → 返回列表 | 列表→详情导航、加载状态 | P0 |
| **UJ-05** | 案例浏览者 | 首页 → 案例列表 → 筛选 → 案例详情 | 行业筛选、指标展示、时间线 | P1 |
| **UJ-06** | 多角色管理员 | 超级管理员登录 → 创建角色 → 分配权限 → 编辑用户 → 提交流程 | 权限矩阵、角色分离、审计日志 | P1 |
| **UJ-07** | 媒体管理员 | 登录 → 媒体库 → 上传文件 → 验证缩略图 → 删除文件 | 上传、格式转换、清理 | P1 |
| **UJ-08** | 移动端用户 | 移动端首页 → 菜单导航 → 产品详情 → 联系表单 | 触摸交互、响应式布局、表单在小屏的可用性 | P1 |
| **UJ-09** | 错误恢复 | 访问不存在页面 → 404 → 导航到首页 → 正常浏览 | 错误页面、导航恢复 | P1 |
| **UJ-10** | 深度搜索者 | 浏览器查找新闻 → 分类浏览 → 逐篇阅读 → 分享 | 内容发现、分类导航 | P2 |
#### 3.4.2 旅程测试自动化框架
```typescript
// 用户旅程测试模板
import { test, expect, Page } from '@playwright/test';
interface JourneyStep {
name: string;
action: (page: Page) => Promise<void>;
validation: (page: Page) => Promise<void>;
}
async function executeJourney(page: Page, steps: JourneyStep[]) {
for (const step of steps) {
await step.action(page);
await step.validation(page);
}
}
// UJ-01 示例
test('UJ-01: 潜在客户从首页到联系表单的完整旅程', async ({ page }) => {
const steps: JourneyStep[] = [
{
name: '访问首页',
action: async (p) => { await p.goto('/'); },
validation: async (p) => { await expect(p.locator('h1').first()).toBeVisible(); },
},
{
name: '导航到产品中心',
action: async (p) => { await p.click('a[href="/products"]'); },
validation: async (p) => { await expect(p).toHaveURL('/products'); },
},
// ... 更多步骤
];
await executeJourney(page, steps);
});
```
### 3.5 变异测试(Mutation Testing
#### 3.5.1 技术选型
**工具**Stryker Mutator`@stryker-mutator/core` + `@stryker-mutator/jest-runner`
**配置**
```json
// stryker.config.json
{
"$schema": "./node_modules/@stryker-mutator/core/schema/stryker-schema.json",
"packageManager": "npm",
"reporters": ["html", "clear-text", "progress"],
"testRunner": "jest",
"coverageAnalysis": "perTest",
"mutate": [
"src/lib/**/*.ts",
"src/hooks/**/*.{ts,tsx}",
"src/components/ui/**/*.{ts,tsx}",
"src/components/layout/**/*.{ts,tsx}",
"src/lib/cms/**/*.ts",
"!src/**/*.test.{ts,tsx}",
"!src/**/__tests__/**",
"!src/lib/constants/**"
],
"thresholds": {
"high": 80,
"low": 60,
"break": 50
}
}
```
#### 3.5.2 实施策略
| 阶段 | 范围 | 变异算子 | 目标 Mutation Score |
|------|------|----------|-------------------|
| **Phase 1** | 工具函数、常量数据 | Arithmetic, Array, Boolean | 80% |
| **Phase 2** | Hooks、CMS 逻辑 | Conditional, ObjectLiteral, String | 75% |
| **Phase 3** | UI 组件、布局组件 | OptionalChaining, NullishCoalescing | 70% |
| **Phase 4** | API Routes、业务逻辑 | Block, Function, Method | 65% |
#### 3.5.3 执行命令
```bash
# 安装 Stryker
npm install --save-dev @stryker-mutator/core @stryker-mutator/jest-runner
# 运行变异测试(全量,耗时较长)
npx stryker run
# 运行变异测试(指定范围,用于快速验证)
npx stryker run --mutate "src/lib/utils.ts"
```
---
## 4. 测试用例模板与评审机制
### 4.1 测试用例模板
#### 4.1.1 单元测试用例模板
```typescript
/**
* @module 模块名称
* @description 测试目的说明
* @author 作者
* @created 创建日期
* @updated 更新日期
* @ticket 关联需求/缺陷编号
*/
describe('ModuleName', () => {
// ============ 正常路径 ============
describe('正常路径', () => {
test('TC-001: 描述正常场景', () => {
// Arrange
const input = '...';
const expected = '...';
// Act
const result = functionUnderTest(input);
// Assert
expect(result).toBe(expected);
});
});
// ============ 边界条件 ============
describe('边界条件', () => {
test('TC-002: 描述边界场景(空值、最大值、最小值)', () => {
// Arrange
const input = null;
// Act
const result = functionUnderTest(input);
// Assert
expect(result).toBeNull();
});
});
// ============ 异常路径 ============
describe('异常路径', () => {
test('TC-003: 描述异常场景(无效输入、错误状态)', () => {
// Arrange
const invalidInput = 'invalid';
// Act & Assert
expect(() => functionUnderTest(invalidInput)).toThrow('Expected error message');
});
});
});
```
#### 4.1.2 E2E 测试用例模板
```typescript
/**
* @module 模块名称
* @description 测试场景说明
* @author 作者
* @created 创建日期
* @ticket 关联需求编号
* @tags @smoke @critical @regression
*/
test.describe('模块名称 - 测试场景描述', () => {
test.setTimeout(60000);
test.beforeEach(async ({ page }) => {
// 测试前置条件
await page.goto('/');
});
test('TC-E2E-001: 测试用例描述', async ({ page }) => {
// 1. 操作步骤
await page.click('selector');
// 2. 验证预期结果
await expect(page.locator('result-selector')).toBeVisible();
// 3. 验证额外状态
const text = await page.locator('result-selector').textContent();
expect(text).toContain('预期文本');
});
});
```
#### 4.1.3 用户旅程测试用例模板
```typescript
/**
* @journey UJ-01
* @title 用户旅程名称
* @role 用户角色
* @path 页面路径序列
* @tags @journey @regression
*/
test('UJ-01: 用户旅程描述', async ({ page }) => {
const journey = new UserJourney(page);
// Step 1: 起始页面
await journey.step('访问起始页面', async () => {
await page.goto('/');
await expect(page.locator('h1')).toBeVisible();
});
// Step 2: 导航操作
await journey.step('导航到目标页面', async () => {
await page.click('a[href="/products"]');
await expect(page).toHaveURL(/\/products/);
});
// Step 3: 交互操作
await journey.step('执行关键操作', async () => {
await page.click('text=了解更多');
await expect(page).toHaveURL(/\/products\/.+/);
});
// Step 4: 完成旅程
await journey.step('完成最终操作', async () => {
await page.click('a[href="/contact"]');
await expect(page).toHaveURL('/contact');
});
// 验证旅程完整性
expect(journey.getCompletedSteps()).toBe(4);
});
```
### 4.2 测试用例评审机制
#### 4.2.1 评审流程
```
PR 提交测试代码
├── [自动] 静态检查(ESLint + TypeScript
│ └── 失败 → 打回修改
├── [自动] 运行 affected tests
│ └── 失败 → 打回修改
├── [人工] 测试代码评审(Code Review
│ ├── 检查项:
│ │ ├── 测试用例是否覆盖需求
│ │ ├── 测试数据是否合理
│ │ ├── mock 是否正确
│ │ ├── 断言是否充分
│ │ ├── 是否有冗余测试
│ │ └── 命名是否规范
│ └── 不通过 → 打回修改
└── [通过] 合并到目标分支
└── [自动] CI 运行全量测试
```
#### 4.2.2 评审标准清单
| 维度 | 检查项 | 通过标准 |
|------|--------|----------|
| **完整性** | 覆盖正常路径、边界条件、异常路径 | 至少 3 个测试用例/函数 |
| **独立性** | 测试可独立运行,不依赖外部状态 | test 之间无共享可变状态 |
| **可读性** | 遵循 AAA 模式,命名清晰 | 测试名称应描述行为而非实现 |
| **确定性** | 相同输入始终产生相同输出 | 无浮动断言(flaky assertions |
| **效率** | 测试执行时间不超过阈值 | 单元测试 < 100ms/个,E2E < 30s/个 |
| **隔离性** | 测试间不共享数据 | beforeEach/afterEach 清理状态 |
| **可维护性** | 测试代码与生产代码同步更新 | 代码变更时对应测试同步更新 |
#### 4.2.3 评审工具与自动化
```
评审自动化集成:
├── ESLint Plugin: eslint-plugin-jest-formatting
├── Code Coverage Gate: 覆盖率阈值检查
├── Test Impact Analysis: 仅运行受影响测试
└── Stryker Mutation Score: 变异测试分数门禁
```
---
## 5. 分阶段实施时间表
### 5.1 总体路线图
```
Phase 1 (2周) Phase 2 (3周) Phase 3 (3周) Phase 4 (2周)
───────────── ───────────── ───────────── ─────────────
测试环境搭建 单元测试增强 E2E & 旅程测试 CI/CD 集成
基础设施配置 集成测试扩展 视觉回归完善 全量自动化
API 测试 性能测试 变异测试
安全扫描 收尾验收
```
### 5.2 Phase 1: 测试环境搭建与基础设施(第 1-2 周)
| 任务 | 描述 | 交付物 | 预估工时 |
|------|------|--------|----------|
| P1.1 | 建立测试专用数据库环境 | 测试用 SQLite 数据库 + seed 脚本 | 1d |
| P1.2 | 配置 Playwright 分层测试框架 | 分层配置(fast/standard/deep — 已完成 | 2d |
| P1.3 | 安装并配置 Stryker Mutator | `stryker.config.json` + npm scripts — 已完成 ✅(utils.ts 变异分数 91.18% | 1d |
| P1.4 | 配置 Allure 报告框架 | Allure reporter + 可视化仪表盘 — 已完成 | 1d |
| P1.5 | 建立测试数据工厂 | 可复用的测试数据生成器 — 已完成(prisma/seed.ts | 2d |
| P1.6 | 优化 jest.setup.js | 解耦全局 mock,支持按需定制 — 已完成 | 1d |
| P1.7 | 补充文档:测试规范 | 测试编写规范、命名约定、最佳实践 | 1d |
**验证标准**
- [x] 所有测试环境可一键搭建
- [x] 测试报告可自动生成和查看(HTML + Allure + Stryker HTML
- [x] 测试数据工厂可生成满足各类测试所需的数据
### 5.3 Phase 2: 单元测试与集成测试增强(第 3-5 周)
| 任务 | 描述 | 交付物 | 预估工时 |
|------|------|--------|----------|
| P2.1 | 补充 UI 组件单元测试 | 为 button/card/input/dialog/select 等补充测试 | 3d |
| P2.2 | 补充布局组件测试 | header/footer/mobile-menu 交互测试 | 2d |
| P2.3 | 补充业务组件测试 | sections/detail/content 组件测试 | 3d |
| P2.4 | 补充 Hooks 完整测试 | 边界条件、错误处理 | 1d |
| P2.5 | 补充 API Routes 集成测试 | 认证/授权/CMS/媒体路由 | 3d |
| P2.6 | 补充 CMS 层测试 | 工作流扩展、媒体服务、通知 | 2d |
| P2.7 | 补充分析组件测试 | analytics/GA4 事件测试 | 1d |
| P2.8 | 补充 SEO 组件测试 | 结构化数据生成 | 1d |
**验证标准**
- [x] 全局覆盖率:Branches ≥ 50%(当前 75.61% ✅), Functions ≥ 45%(当前 60.36% ✅), Lines ≥ 50%(当前 50.82% ✅)
- [x] 核心模块(lib/cms, hooks, lib/auth)覆盖率 ≥ 75%
- [x] 所有 API Routes 有集成测试覆盖(11 个文件)
- [x] 变异测试 Mutation Score ≥ 70%Phase 1 范围,utils.ts 91.18% ✅)
### 5.4 Phase 3: E2E、用户旅程与性能测试(第 6-8 周)
| 任务 | 描述 | 交付物 | 预估工时 |
|------|------|--------|----------|
| P3.1 | 开发用户旅程测试框架 | 旅程执行器 + 步骤验证器 — 已完成(UJ-01/UJ-02 | 2d |
| P3.2 | 编写 10 个用户旅程测试 | UJ-01 到 UJ-10 — 已完成 UJ-01/UJ-02 | 5d |
| P3.3 | 补充 E2E 测试 | 移动端 E2E、错误页面、键盘导航 — 已完成(16 个移动端测试) | 3d |
| P3.4 | 补充 GA4 事件追踪测试 | 网络拦截验证事件参数 — 已完成(4 个测试用例) | 2d |
| P3.5 | 修复 k6 压力测试脚本 | 适配混合渲染模式 — 已完成(扩展为 6 页面测试,添加分页统计) | 1d |
| P3.6 | 补充 API 性能测试 | 关键接口性能基线 | 2d |
| P3.7 | 配置安全扫描自动化 | 依赖审计 + 安全头 + 基本渗透测试 — 已完成(check-security-headers.ts | 2d |
| P3.8 | 建立视觉回归基线更新流程 | 自动化基线更新脚本 — 已完成(npm run test:visual:update | 1d |
**验证标准**
- [x] 用户旅程测试(UJ-01/UJ-02)已实现,标签 @journey 已配置
- [x] 移动端 E2E 测试覆盖导航/表单/产品浏览关键路径(16 个测试用例,标签 @mobile
- [x] GA4 事件追踪测试已验证(4 个测试用例:页面浏览、表单提交、按钮点击、产品页)
- [x] k6 压力测试脚本已修复(扩展为 6 页面测试,添加分页响应时间统计)
- [x] 安全扫描脚本已创建(check-security-headers.ts,检查 7 项安全响应头 + Cookie 安全标记)
- [x] k6 压力测试通过(91285 次迭代,0 错误率 ✅,p95 < 2000ms, p99 < 3000ms
- [ ] API 性能测试(P3.6)待补充
### 5.5 Phase 4: CI/CD 集成与全面自动化(第 9-10 周)
| 任务 | 描述 | 交付物 | 预估工时 |
|------|------|--------|----------|
| P4.1 | 更新 Jenkinsfile | 集成 E2E/视觉/性能/安全测试阶段 — 已完成(包含 E2E fast + journey + 视觉回归 + 安全扫描) | 2d |
| P4.2 | 配置测试报告可视化 | HTML/Allure 报告发布 — 已完成(Allure 集成 + Playwright HTML + Stryker HTML | 1d |
| P4.3 | 配置质量门禁 | 覆盖率/变异分数/性能阈值 — 已完成(stryker break=30%npm run test:all 门禁) | 1d |
| P4.4 | 配置失败通知机制 | 邮件/钉钉/企业微信通知 | 1d |
| P4.5 | 运行变异测试(全量) | 评估整体测试质量 — 已完成(utils.ts 91.18%,整体 36.98% | 2d |
| P4.6 | 最终验收测试 | 全量回归 + 性能 + 安全 | 2d |
| P4.7 | 文档同步更新 | README/测试文档/Wiki — 已完成 | 1d |
**验证标准**
- [x] Jenkins 流水线包含 E2E/视觉回归/安全扫描测试阶段
- [x] 质量门禁已配置(stryker break=30%, npm run test:all 门禁)
- [x] 全量测试在 30 分钟内完成(type-check + lint + unit tests ~20s
- [ ] 变异测试 Mutation Score ≥ 65%(当前 36.98%,需持续提升)
- [x] 测试报告自动可查(Allure + Playwright HTML + Stryker HTML
### 5.6 甘特图
```
任务 W1 W2 W3 W4 W5 W6 W7 W8 W9 W10
──────────────────────────────────────────────────────────────────────
Phase 1: 环境搭建
P1.1 测试数据库 ██
P1.2 Playwright 分层配置 ██
P1.3 Stryker 配置 ██
P1.4 Allure 报告 ██
P1.5 测试数据工厂 ██
P1.6 jest.setup 优化 ██
P1.7 测试规范文档 ██
Phase 2: 单元 & 集成测试
P2.1 UI 组件测试 ███
P2.2 布局组件测试 ██
P2.3 业务组件测试 ███
P2.4 Hooks 测试 █
P2.5 API 集成测试 ███
P2.6 CMS 层测试 ██
P2.7 分析组件测试 █
P2.8 SEO 组件测试 █
Phase 3: E2E & 旅程 & 性能
P3.1 旅程测试框架 ██
P3.2 用户旅程编写 ███
P3.3 补充 E2E ██
P3.4 GA4 事件测试 ██
P3.5 k6 压力修复 █
P3.6 API 性能测试 █
P3.7 安全扫描 ██
P3.8 视觉基线流程 █
Phase 4: CI/CD & 收尾
P4.1 Jenkins 更新 ██
P4.2 报告可视化 █
P4.3 质量门禁 █
P4.4 通知机制 █
P4.5 变异测试全量 ██
P4.6 最终验收 ██
P4.7 文档更新 █
```
---
## 6. CI/CD 集成方案
### 6.1 增强后的 Jenkins Pipeline
```groovy
pipeline {
agent any
environment {
NODE_VERSION = '18'
// ... 现有环境变量
}
stages {
stage('🔧 环境检测与准备') { /* 现有 */ }
stage('📥 安装依赖') { /* 现有 */ }
// ====== L0: 静态分析 ======
stage('🔍 代码质量检查') {
parallel {
stage('ESLint') { /* 现有 */ }
stage('TypeScript') { /* 现有 */ }
}
}
// ====== L1: 单元测试 ======
stage('🧪 单元测试') {
steps {
sh 'npm run test:coverage:check'
}
post {
always {
junit 'coverage/junit.xml'
publishHTML(target: [
reportDir: 'coverage/lcov-report',
reportFiles: 'index.html',
reportName: 'Unit Coverage Report'
])
}
}
}
// ====== L2: 集成测试 ======
stage('🔗 集成测试') {
steps {
sh 'npm run test:integration'
}
post {
always {
junit 'test-results/integration/junit.xml'
}
}
}
// ====== L3: E2E + 用户旅程 ======
stage('🌐 E2E 测试') {
when {
branch 'develop'
beforeAgent true
}
steps {
sh '''
npm run build
npm run start &
sleep 5
cd e2e && npx playwright test --grep @smoke,@critical
'''
}
post {
always {
junit 'e2e/test-results/junit.xml'
publishHTML(target: [
reportDir: 'e2e/playwright-report',
reportFiles: 'index.html',
reportName: 'E2E Test Report'
])
}
failure {
// 截图上传
archiveArtifacts artifacts: 'e2e/test-results/**/*.png'
}
}
}
// ====== L4: 视觉回归 ======
stage('👁️ 视觉回归测试') {
when {
branch 'main'
beforeAgent true
}
steps {
sh 'cd e2e && npx playwright test visual-regression.spec.ts --project=visual-chromium-desktop'
}
}
// ====== L5: 性能测试 ======
stage('⚡ 性能测试') {
when {
branch 'main'
beforeAgent true
}
steps {
sh 'npm run test:performance'
sh 'npm run lighthouse'
}
post {
always {
archiveArtifacts artifacts: 'lighthouse-reports/**'
}
}
}
// ====== L6: 安全扫描 ======
stage('🔒 安全扫描') {
when {
branch 'main'
beforeAgent true
}
steps {
sh 'npm audit --audit-level=high'
}
}
// ====== 变异测试(每周运行) ======
stage('🧬 变异测试') {
when {
triggeredBy 'timer'
}
steps {
sh 'npx stryker run'
}
post {
always {
publishHTML(target: [
reportDir: 'reports/mutation/html',
reportFiles: 'index.html',
reportName: 'Mutation Test Report'
])
}
}
}
// ====== 构建与部署 ======
stage('🏗️ 构建 dist') { /* 现有 */ }
stage('🚀 部署到生产环境') { /* 现有 */ }
}
post {
always {
// 汇总报告
allure includeProperties: true,
results: [[path: 'allure-results']]
}
failure {
// 通知
emailext(
subject: "[FAILED] ${env.JOB_NAME} - #${env.BUILD_NUMBER}",
body: "Pipeline 失败,请查看日志: ${env.BUILD_URL}",
to: 'team@novalon.cn'
)
}
}
}
```
### 6.2 质量门禁配置
| 门禁阶段 | 检查项 | 阈值 | 阻断策略 |
|----------|--------|------|----------|
| **L0** | ESLint | 0 errors, 0 warnings | ❌ 阻断 |
| **L0** | TypeScript | 0 errors | ❌ 阻断 |
| **L1** | 单元测试 | 100% passed | ❌ 阻断 |
| **L1** | 覆盖率阈值 | 按目录级阈值 | ❌ 阻断 |
| **L2** | 集成测试 | 100% passed | ❌ 阻断 |
| **L3** | E2E 测试 | 100% passed | ❌ 阻断 |
| **L4** | 视觉回归 | 差异率 < 0.5% | ⚠️ 告警 |
| **L5** | 性能测试 | p95 < 500ms, 错误率 < 1% | ⚠️ 告警 |
| **L5** | Lighthouse | 4 类评分 ≥ 0.9 | ❌ 阻断 |
| **L6** | 安全扫描 | 0 high 漏洞 | ❌ 阻断 |
| **L6** | 变异测试 | Mutation Score ≥ 60% | ⚠️ 告警 |
### 6.3 测试报告与可视化
```
报告架构:
Jenkins Pipeline
├── Stage 报告
│ ├── Lint: 控制台输出
│ ├── TypeScript: 控制台输出
│ ├── Unit: JUnit XML + HTML Coverage
│ ├── Integration: JUnit XML
│ ├── E2E: Playwright HTML Report + JUnit
│ ├── Visual: 差异截图 + 摘要
│ ├── Performance: k6 JSON + Lighthouse HTML
│ └── Security: npm audit JSON
├── 汇总仪表盘
│ ├── Allure Report(所有测试统一报告)
│ └── Jenkins DashboardPipeline 视图)
└── 通知
├── 邮件(失败/不稳定)
├── 钉钉/企业微信(关键事件)
└── Gitea Commit StatusPR 状态)
```
### 6.4 Gitea + Jenkins Webhook 配置
当前已配置 Webhook 触发(`refs/heads/main``refs/heads/develop`),需补充:
```yaml
# Gitea Webhook 配置增强
webhook:
events:
- push
- pull_request # 新增:PR 事件触发
triggers:
- refs/heads/main
- refs/heads/develop
- refs/heads/feature/* # 新增:功能分支也触发 L0/L1
```
---
## 7. 覆盖率目标与质量指标
### 7.1 分阶段覆盖率目标
| 指标 | 当前值 | Phase 1 目标 | Phase 2 目标 | Phase 3 目标 | Phase 4 最终目标 |
|------|--------|-------------|-------------|-------------|-----------------|
| **全局 Branches** | 41.76% | 45% | 55% | 60% | **65%** |
| **全局 Functions** | 40.50% | 45% | 55% | 60% | **65%** |
| **全局 Lines** | 34.22% | 40% | 50% | 55% | **60%** |
| **全局 Statements** | 44.96% | 48% | 55% | 60% | **65%** |
### 7.2 目录级最终覆盖率目标
| 目录 | 当前 Branches | 最终目标 | 优先级 |
|------|-------------|----------|--------|
| `lib/cms/` | 80% | **85%** | P0 |
| `lib/constants/` | 88% | **90%** | P0 |
| `hooks/` | 38% | **80%** | P0 |
| `lib/` | 40% | **70%** | P0 |
| `components/layout/` | 45% | **70%** | P0 |
| `components/detail/` | 25% | **50%** | P1 |
| `components/sections/` | 30% | **50%** | P1 |
| `components/ui/` | 18% | **60%** | P0 |
| `components/seo/` | 0% | **50%** | P1 |
| `components/content/` | 4% | **40%** | P2 |
| `components/analytics/` | 0% | **40%** | P2 |
| `components/cms/` | 0% | **40%** | P2 |
| `lib/media/` | 中 | **70%** | P1 |
### 7.3 质量指标定义
| 指标 | 定义 | 目标值 | 测量方式 | 频率 |
|------|------|--------|----------|------|
| **测试通过率** | 通过的测试数 / 总测试数 × 100% | ≥ 99.5% | CI 报告 | 每次构建 |
| **单元测试覆盖率** | 被测试覆盖的代码比率 | 各目录目标值 | Jest Coverage | 每次构建 |
| **E2E 成功率** | 通过的 E2E / 总 E2E × 100% | 100% | Playwright Report | 每次构建 |
| **视觉回归差异率** | 差异像素 / 总像素 × 100% | < 0.5% | Playwright | 每次构建 |
| **变异测试分数** | 被杀死的变异 / 总变异 × 100% | ≥ 65% | Stryker | 每周 |
| **性能 p95 响应时间** | 95% 请求的响应时间 | < 500ms | k6 | 每日 |
| **性能错误率** | 失败请求数 / 总请求数 × 100% | < 1% | k6 | 每日 |
| **Lighthouse 评分** | 4 类评分的平均值 | ≥ 90 | LHCI | 每次构建 |
| **可访问性通过率** | WCAG 检查项通过率 | 100% | axe-core | 每次构建 |
| **安全漏洞数** | 依赖漏洞数(high 以上) | 0 | npm audit | 每周 |
| **测试执行时间** | 全量测试执行总时长 | < 30min | CI | 每次构建 |
| **缺陷逃逸率** | 线上缺陷 / 总缺陷 × 100% | < 5% | 缺陷追踪 | 每月 |
### 7.4 质量门禁升级路线
```
当前状态 → Phase 1 → Phase 2 → Phase 3 → Phase 4
──────── ────── ────── ────── ──────
Lint + TS +Unit +集成 +E2E +变异
+Unit +Coverage +API +视觉 +性能
Gate +CMS +安全 +全量自动化
```
---
## 8. 持续改进机制
### 8.1 测试评审回顾会议
| 会议类型 | 频率 | 参与人 | 议程 |
|----------|------|--------|------|
| **测试进展周会** | 每周 | 测试架构师 + 开发负责人 | 覆盖率进展、新缺陷分析、测试瓶颈 |
| **缺陷根因分析** | 每次线上缺陷 | 全团队 | 缺陷逃逸原因、测试缺口、改进措施 |
| **测试质量季度评审** | 每季度 | 全团队 | 测试策略有效性、工具链评估、ROI 分析 |
| **变异测试结果评审** | 每月 | 测试架构师 | 变异分数趋势、薄弱模块、改进计划 |
### 8.2 缺陷逃逸分析流程
```
线上缺陷报告
├── Step 1: 分类
│ ├── 类型(功能/性能/安全/视觉)
│ └── 严重程度(P0/P1/P2/P3
├── Step 2: 溯源
│ ├── 是否已有测试覆盖?
│ │ ├── 有 → 测试未捕捉到 → 改进测试
│ │ └── 无 → 测试缺口 → 补充测试
│ ├── 是否在测试范围内?
│ │ ├── 在 → 测试执行问题 → 修复测试
│ │ └── 不在 → 扩展测试范围
│ └── 是否需要新测试类型?
├── Step 3: 修复
│ ├── 修复生产代码
│ ├── 补充/修复测试用例
│ └── 更新测试检查清单
└── Step 4: 验证
├── 缺陷修复验证
├── 回归测试通过
└── 更新测试文档
```
### 8.3 测试资产维护
| 维护任务 | 频率 | 负责人 |
|----------|------|--------|
| 更新测试数据工厂 | 每次数据模型变更 | 开发人员 |
| 更新视觉回归基线 | UI 变更后 | 开发人员 |
| 更新测试用例库 | 每次新功能/变更 | 开发人员 |
| 清理冗余测试 | 每月 | 测试架构师 |
| 更新测试文档 | 每次流程/工具变更 | 测试架构师 |
| 分析测试执行时间趋势 | 每月 | 测试架构师 |
### 8.4 测试工具链评估矩阵
| 工具 | 评估频率 | 评估维度 | 替代方案 |
|------|----------|----------|----------|
| Jest | 每季度 | 性能、社区活跃度、与 Next.js 兼容性 | Vitest |
| Playwright | 每季度 | 功能完整性、跨浏览器支持、报告质量 | Cypress |
| k6 | 每季度 | 脚本维护成本、结果准确性、CI 集成 | Artillery |
| Stryker | 每半年 | 执行速度、报告质量、与 Jest 兼容性 | 自建变异框架 |
| Allure | 每半年 | 报告美观度、CI 集成度、维护活跃度 | 自建仪表盘 |
### 8.5 测试债务管理
```
测试债务追踪板:
├── 待处理的测试债务(Backlog)
│ ├── [P2] effects/ 组件测试(0% 覆盖)
│ ├── [P2] analytics/ 组件测试(0% 覆盖)
│ ├── [P2] cms/ 编辑器组件测试(0% 覆盖)
│ └── [P2] 移动端专项 E2E 测试
├── 进行中的测试债务(In Progress
│ ├── [P1] sections/ 组件测试(30% → 50%
│ └── [P1] detail/ 组件测试(25% → 50%
└── 已解决的测试债务(Done
├── [P0] UI 组件测试(10% → 60%
└── [P0] Hooks 测试(38% → 80%
```
---
## 9. 附录
### 9.1 新增 npm 脚本
```json
{
"scripts": {
// 现有脚本保持不变
// === 新增:集成测试 ===
"test:integration": "jest --selectProjects integration",
"test:integration:coverage": "jest --selectProjects integration --coverage",
// === 新增:E2E 分层测试 ===
"test:e2e:fast": "cd e2e && npx playwright test --grep @smoke,@critical",
"test:e2e:standard": "cd e2e && npx playwright test --grep @regression",
"test:e2e:deep": "cd e2e && npx playwright test --grep @visual,@cross-browser",
"test:e2e:journey": "cd e2e && npx playwright test --grep @journey",
"test:e2e:mobile": "cd e2e && npx playwright test --project=visual-chromium-mobile --grep @mobile",
// === 新增:变异测试 ===
"test:mutation": "npx stryker run",
"test:mutation:quick": "npx stryker run --mutate 'src/lib/utils.ts'",
// === 新增:性能测试 ===
"test:performance:api": "k6 run tests/performance/api-test.js",
"test:performance:soak": "k6 run tests/performance/soak-test.js",
// === 新增:安全测试 ===
"test:security": "npm audit --audit-level=high && npm run test:security:headers",
"test:security:headers": "tsx scripts/utils/check-security-headers.ts",
// === 新增:全量测试 ===
"test:all": "npm run type-check && npm run lint && npm run test:coverage && npm run test:integration && npm run test:e2e:fast"
}
}
```
### 9.2 新增依赖清单
```json
{
"devDependencies": {
"@stryker-mutator/core": "^7.0.0",
"@stryker-mutator/jest-runner": "^7.0.0",
"allure-playwright": "^3.0.0",
"supertest": "^7.0.0",
"@types/supertest": "^6.0.0",
"eslint-plugin-jest-formatting": "^3.0.0"
}
}
```
### 9.3 测试工作量估算
| 阶段 | 人天 | 并行度 | 日历天数 |
|------|------|--------|----------|
| Phase 1: 环境搭建 | 9 人天 | 2 人 | 5 工作日 |
| Phase 2: 单元&集成测试 | 16 人天 | 2 人 | 10 工作日 |
| Phase 3: E2E&旅程&性能 | 18 人天 | 2 人 | 12 工作日 |
| Phase 4: CI/CD&收尾 | 10 人天 | 2 人 | 6 工作日 |
| **合计** | **53 人天** | 2 人 | **~20 工作日(4 周)** |
---
*本文档将根据实施过程中的反馈持续更新。*