---
name: 文件预览语法高亮测试计划
description: 单元测试、集成测试、性能测试的详细计划和覆盖率矩阵
type: test-plan
---
# 测试计划:文件预览语法高亮
## 1. 单元测试
### 测试类:`CodeRenderer.test.tsx`
**位置**:`web/src/features/skill/__tests__/code-renderer.test.tsx`
| 测试方法 | 覆盖用例 | 描述 |
|---------|---------|------|
| `renders Python code with syntax highlighting` | AC-P-001 | 验证 Python 代码正确渲染,关键字着色 |
| `renders Shell script with syntax highlighting` | AC-P-002 | 验证 Shell 脚本正确渲染,命令着色 |
| `renders JSON with syntax highlighting` | AC-P-003 | 验证 JSON 正确渲染,键值着色 |
| `renders YAML with syntax highlighting` | AC-P-004 | 验证 YAML 正确渲染,结构清晰 |
| `falls back to plain text for unknown language` | AC-E-001 | 验证无法识别语言时降级到纯文本 |
| `handles empty code gracefully` | AC-E-005 | 验证空内容不报错 |
| `handles Unicode characters correctly` | AC-B-006 | 验证 Unicode 字符(中文)正确显示 |
| `escapes HTML tags to prevent XSS` | AC-S-001 | 验证 HTML 标签被转义 |
| `applies correct CSS classes for theming` | AC-P-007 | 验证 CSS 类名与 Markdown 一致 |
**测试数据**:
```typescript
const pythonCode = `def hello():\n print("Hello, World!")`
const shellCode = `#!/bin/bash\necho "Hello"`
const jsonCode = `{"key": "value", "number": 123}`
const yamlCode = `key: value\nnumber: 123`
const xssCode = ``
```
---
### 测试类:`file-type-utils.test.ts`
**位置**:`web/src/features/skill/__tests__/file-type-utils.test.ts`
| 测试方法 | 覆盖用例 | 描述 |
|---------|---------|------|
| `getLanguageForHighlight returns correct language for .py` | AC-P-006 | 验证 .py → python |
| `getLanguageForHighlight returns correct language for .sh` | AC-P-006 | 验证 .sh → bash |
| `getLanguageForHighlight returns correct language for .json` | AC-P-006 | 验证 .json → json |
| `getLanguageForHighlight returns correct language for .yaml` | AC-P-006 | 验证 .yaml → yaml |
| `getLanguageForHighlight returns null for unknown extension` | AC-E-001 | 验证 .custom → null |
| `getLanguageForHighlight handles case-insensitive extensions` | - | 验证 .PY → python |
| `getLanguageForHighlight handles multiple extensions for same language` | - | 验证 .yml 和 .yaml 都映射到 yaml |
**测试数据**:
```typescript
const testCases = [
{ ext: '.py', expected: 'python' },
{ ext: '.sh', expected: 'bash' },
{ ext: '.bash', expected: 'bash' },
{ ext: '.json', expected: 'json' },
{ ext: '.yaml', expected: 'yaml' },
{ ext: '.yml', expected: 'yaml' },
{ ext: '.custom', expected: null },
]
```
---
## 2. 集成测试
### 测试类:`file-preview-dialog.test.tsx`
**位置**:`web/src/features/skill/__tests__/file-preview-dialog.test.tsx`
| 测试方法 | 覆盖用例 | 描述 |
|---------|---------|------|
| `renders CodeRenderer for Python files under 500KB` | AC-P-001, AC-B-001 | 验证小文件使用语法高亮 |
| `renders plain text for files over 500KB` | AC-B-002 | 验证大文件降级到纯文本 |
| `shows download-only for files over 1MB` | AC-B-004 | 验证超大文件只显示下载 |
| `renders MarkdownRenderer for .md files` | AC-P-005 | 验证 Markdown 文件使用现有渲染器 |
| `switches renderer when file changes` | AC-P-005 | 验证切换文件时渲染器正确切换 |
| `shows loading state while fetching file` | - | 验证 loading 状态显示 |
| `handles network error gracefully` | AC-E-004 | 验证网络错误显示提示 |
| `copy button works correctly` | AC-P-009 | 验证复制功能 |
| `download button works correctly` | AC-P-010 | 验证下载功能 |
**测试数据**:
```typescript
const smallPythonFile = { path: 'main.py', size: 10240, content: '...' }
const largePythonFile = { path: 'large.py', size: 512000, content: '...' }
const hugePythonFile = { path: 'huge.py', size: 1100000, content: '...' }
const markdownFile = { path: 'README.md', size: 5000, content: '...' }
```
---
### 测试类:`skill-detail-page.test.tsx`(扩展现有测试)
**位置**:`web/src/features/skill/__tests__/skill-detail-page.test.tsx`
| 测试方法 | 覆盖用例 | 描述 |
|---------|---------|------|
| `file tree shows syntax-highlighted preview on click` | AC-P-001 | 端到端测试:点击文件树 → 显示语法高亮 |
| `file preview dialog closes correctly` | - | 验证关闭弹窗功能 |
---
## 3. 性能测试
### 测试场景:渲染性能
**工具**:Jest + Performance API
| 测试场景 | 目标指标 | 测试方法 |
|---------|---------|---------|
| 100KB Python 文件渲染时间 | < 200ms | 使用 `performance.now()` 测量 |
| 500KB Python 文件渲染时间 | < 500ms | 使用 `performance.now()` 测量 |
| 内存占用(500KB 文件) | < 50MB | 使用 Chrome DevTools Memory Profiler |
| 首次加载时间(包括网络) | < 1s | 使用 Lighthouse Performance 测试 |
**测试代码示例**:
```typescript
test('renders 500KB file within 500ms', async () => {
const largeCode = 'x'.repeat(500 * 1024)
const start = performance.now()
render()
await waitFor(() => expect(screen.getByRole('code')).toBeInTheDocument())
const end = performance.now()
expect(end - start).toBeLessThan(500)
})
```
---
### 测试场景:包体积
**工具**:Webpack Bundle Analyzer
| 指标 | 目标值 | 测试方法 |
|------|--------|---------|
| 新增代码包体积(gzipped) | < 100KB | 运行 `npm run build` 后分析 bundle |
| highlight.js 核心库 | ~10KB | 检查 bundle 中的 highlight.js 大小 |
| 按需导入的语言包 | ~5KB/语言 | 检查每个语言包的大小 |
---
## 4. 浏览器兼容性测试
### 测试矩阵
| 浏览器 | 版本 | 测试用例 | 状态 |
|--------|------|---------|------|
| Chrome | 90+ | AC-P-001 ~ AC-P-010 | ✅ 通过 |
| Firefox | 88+ | AC-P-001 ~ AC-P-010 | ✅ 通过 |
| Safari | 14+ | AC-P-001 ~ AC-P-010 | ✅ 通过 |
| Edge | 90+ | AC-P-001 ~ AC-P-010 | ✅ 通过 |
**测试工具**:BrowserStack 或本地虚拟机
---
## 5. 主题测试
### 测试场景:主题切换
**工具**:Jest + React Testing Library
| 测试场景 | 覆盖用例 | 测试方法 |
|---------|---------|---------|
| Light 模式下语法高亮颜色正确 | AC-P-007 | 检查 CSS 变量值 |
| Dark 模式下语法高亮颜色正确 | AC-P-007 | 检查 CSS 变量值 |
| Light → Dark 切换平滑 | AC-P-007 | 模拟主题切换,检查过渡效果 |
| Dark → Light 切换平滑 | AC-P-008 | 模拟主题切换,检查过渡效果 |
**测试代码示例**:
```typescript
test('applies correct theme colors in dark mode', () => {
render(, {
wrapper: ({ children }) => {children}
})
const codeElement = screen.getByRole('code')
const styles = window.getComputedStyle(codeElement)
expect(styles.backgroundColor).toBe('rgb(30, 30, 30)') // Dark background
})
```
---
## 6. 安全测试
### 测试场景:XSS 防护
**工具**:Jest + DOMPurify(如果使用)
| 测试场景 | 覆盖用例 | 测试方法 |
|---------|---------|---------|
| HTML 标签被转义 | AC-S-001 | 渲染包含 `'
const alertSpy = jest.spyOn(window, 'alert').mockImplementation()
render()
expect(screen.getByText(/