Files
it/frontend/docs/TESTING.md

354 lines
7.2 KiB
Markdown
Raw Permalink Normal View History

2025-11-03 19:47:36 +08:00
# 前端自动化测试和代码质量检查
本文档介绍了前端项目的自动化测试和代码质量检查流程、工具和最佳实践。
## 目录
- [测试策略](#测试策略)
- [测试工具](#测试工具)
- [测试环境设置](#测试环境设置)
- [运行测试](#运行测试)
- [代码质量检查](#代码质量检查)
- [持续集成](#持续集成)
- [测试覆盖率](#测试覆盖率)
- [常见问题](#常见问题)
## 测试策略
我们采用多层次测试策略,确保代码质量和应用稳定性:
1. **单元测试**:测试单个函数、组件或模块
2. **集成测试**:测试多个组件或模块之间的交互
3. **端到端测试**:模拟用户操作,测试完整用户流程
### 测试金字塔
```
/\
/ \
/ E2E \ 少量端到端测试
/______\
/ \
/Integration\ 适量集成测试
/__________\
/ \
/ Unit Tests \ 大量单元测试
/______________\
```
## 测试工具
### 单元测试和集成测试
- **Vitest**:基于 Vite 的快速单元测试框架
- **Vue Test Utils**Vue.js 官方测试工具库
- **jsdom**:轻量级 DOM 实现,用于在 Node.js 中模拟浏览器环境
### 端到端测试
- **Playwright**:现代端到端测试框架,支持多浏览器
- **Playwright Test**Playwright 的测试运行器
### 代码质量检查
- **ESLint**JavaScript 代码风格和错误检查工具
- **Prettier**:代码格式化工具
- **TypeScript**:静态类型检查
- **Husky**Git hooks 管理
- **lint-staged**:对暂存文件运行检查
## 测试环境设置
### 安装依赖
```bash
npm install
```
### 环境变量
创建 `.env.test` 文件用于测试环境配置:
```env
VITE_API_BASE_URL=http://localhost:7001/api
VITE_APP_TITLE=硬件性能对比平台 - 测试环境
```
## 运行测试
### 单元测试
运行所有单元测试:
```bash
npm run test:unit
```
监听模式运行单元测试(文件变化时自动重新运行):
```bash
npm run test:unit:watch
```
运行单元测试并生成覆盖率报告:
```bash
npm run test:unit:coverage
```
仅运行组件测试:
```bash
npm run test:component
```
仅运行 API 服务测试:
```bash
npm run test:api
```
仅运行状态管理测试:
```bash
npm run test:store
```
### 端到端测试
运行所有 E2E 测试:
```bash
npm run test:e2e
```
以 UI 模式运行 E2E 测试:
```bash
npm run test:e2e:ui
```
以调试模式运行 E2E 测试:
```bash
npm run test:e2e:debug
```
### 所有测试
运行所有测试(单元测试 + E2E 测试):
```bash
npm test
```
以 CI 模式运行所有测试:
```bash
npm run test:ci
```
## 代码质量检查
### ESLint
运行 ESLint 检查并自动修复问题:
```bash
npm run lint
```
### Prettier
格式化代码:
```bash
npm run format
```
检查代码格式(不修改文件):
```bash
npm run format:check
```
### TypeScript 类型检查
运行 TypeScript 类型检查:
```bash
npm run type-check
```
### 综合质量检查
运行 ESLint 和 Prettier
```bash
npm run quality
```
生成代码质量报告:
```bash
npm run quality-report
```
## 持续集成
项目使用 GitHub Actions 进行持续集成,配置文件位于 `.github/workflows/ci.yml`
CI 流程包括:
1. 代码检出
2. 依赖安装
3. 类型检查
4. 代码风格检查
5. 单元测试和覆盖率报告
6. 应用构建
7. E2E 测试
8. 安全审计
9. 部署(仅 main 分支)
### Git Hooks
项目配置了以下 Git Hooks
- **pre-commit**:对暂存文件运行 ESLint 和 Prettier
- **pre-push**:运行单元测试
这些 hooks 通过 Husky 和 lint-staged 管理。
## 测试覆盖率
### 覆盖率目标
- **行覆盖率**:≥ 80%
- **函数覆盖率**:≥ 80%
- **分支覆盖率**:≥ 75%
- **语句覆盖率**:≥ 80%
### 覆盖率报告
运行 `npm run test:unit:coverage` 后,覆盖率报告将生成在 `coverage/` 目录下。
- `coverage/lcov-report/index.html`HTML 格式的详细报告
- `coverage/coverage-summary.json`JSON 格式的摘要数据
### 覆盖率徽章
可以在 README.md 中添加覆盖率徽章:
```markdown
![Coverage](https://img.shields.io/badge/coverage-80%25-brightgreen)
```
## 测试编写指南
### 单元测试示例
```javascript
// tests/unit/components/MyComponent.spec.js
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
describe('MyComponent', () => {
it('renders correctly', () => {
const wrapper = mount(MyComponent, {
props: {
title: 'Test Title'
}
})
expect(wrapper.find('h1').text()).toBe('Test Title')
})
it('emits event when button is clicked', async () => {
const wrapper = mount(MyComponent)
await wrapper.find('button').trigger('click')
expect(wrapper.emitted()).toHaveProperty('button-clicked')
})
})
```
### E2E 测试示例
```javascript
// tests/e2e/user-journey.spec.js
import { test, expect } from '@playwright/test'
test('user can view product details', async ({ page }) => {
// 导航到首页
await page.goto('/')
// 点击产品类别
await page.click('[data-testid="category-cpu"]')
// 点击第一个产品
await page.click('[data-testid="product-card"]:first-child')
// 验证产品详情页面
await expect(page.locator('h1')).toContainText('产品详情')
await expect(page.locator('[data-testid="product-specs"]')).toBeVisible()
})
```
### 测试最佳实践
1. **保持测试简单**:每个测试只验证一个功能点
2. **使用描述性测试名称**:清楚说明测试的目的
3. **使用数据-testid**:避免依赖 CSS 类名或元素结构
4. **模拟外部依赖**:使用 mock 隔离测试
5. **保持测试独立性**:测试之间不应相互依赖
6. **使用页面对象模式**:对于 E2E 测试,使用页面对象封装页面操作
## 常见问题
### 问题:测试运行缓慢
**解决方案**
1. 使用 `vitest` 的并行测试功能
2. 使用 `vitest --mode=development` 进行开发时测试
3. 使用 `vitest --reporter=verbose` 查看详细输出
4. 考虑使用 `vitest --no-coverage` 跳过覆盖率收集
### 问题E2E 测试不稳定
**解决方案**
1. 使用 `page.waitForSelector()` 等待元素出现
2. 使用 `page.waitForLoadState()` 等待页面加载完成
3. 增加测试超时时间
4. 使用 `test.beforeEach()``test.afterEach()` 进行测试隔离
### 问题:覆盖率报告不准确
**解决方案**
1. 检查 `vitest.config.js` 中的覆盖率配置
2. 确保所有源文件都被包含在覆盖率统计中
3. 使用 `coverage.exclude` 排除不需要测试的文件
### 问题ESLint 与 Prettier 冲突
**解决方案**
1. 使用 `eslint-config-prettier` 禁用与 Prettier 冲突的 ESLint 规则
2.`.eslintrc.js` 中添加 `"extends": ["prettier"]`
3. 确保 `package.json` 中的脚本顺序正确
## 参考资源
- [Vitest 官方文档](https://vitest.dev/)
- [Vue Test Utils 官方文档](https://test-utils.vuejs.org/)
- [Playwright 官方文档](https://playwright.dev/)
- [ESLint 官方文档](https://eslint.org/)
- [Prettier 官方文档](https://prettier.io/)
---
如有其他问题,请查看项目 Wiki 或联系开发团队。