# 角色测试框架迁移设计文档

**日期**: 2026-04-05
**作者**: 张翔
**状态**: 已批准

## 1. 背景

### 问题描述
运行完整E2E测试套件时遇到错误：
```
TypeError: Cannot redefine property: Symbol($$jest-matchers-object)
```

### 根本原因
- `e2e/role-based-tests/`目录下存在vitest单元测试文件（`.test.ts`）
- Playwright运行时会加载这些文件，导致与Playwright的expect冲突
- 单元测试文件位置不当，不符合项目结构最佳实践

### 受影响的文件
**单元测试文件**（6个）：
- `e2e/role-based-tests/shared/__tests__/permission-helper.test.ts`
- `e2e/role-based-tests/shared/__tests__/role-auth-manager.test.ts`
- `e2e/role-based-tests/shared/__tests__/test-data-manager.test.ts`
- `e2e/role-based-tests/roles/__tests__/admin.role.test.ts`
- `e2e/role-based-tests/roles/__tests__/base.role.test.ts`
- `e2e/role-based-tests/roles/__tests__/role-factory.test.ts`

**工具类文件**（8个）：
- `e2e/role-based-tests/shared/auth-helper.ts`
- `e2e/role-based-tests/shared/permission-helper.ts`
- `e2e/role-based-tests/shared/role-auth-manager.ts`
- `e2e/role-based-tests/shared/test-data-manager.ts`
- `e2e/role-based-tests/roles/admin.role.ts`
- `e2e/role-based-tests/roles/base.role.ts`
- `e2e/role-based-tests/roles/role-factory.ts`
- `e2e/role-based-tests/roles/user.role.ts`

**E2E测试文件**（4个，需要更新导入路径）：
- `e2e/role-based-tests/scenarios/authentication/login-flow.spec.ts`
- `e2e/role-based-tests/scenarios/authentication/logout-flow.spec.ts`
- `e2e/role-based-tests/scenarios/user-management/admin-creates-user.spec.ts`
- `e2e/role-based-tests/scenarios/user-management/permission-boundary.spec.ts`

## 2. 解决方案

### 设计原则
1. **职责分离**：单元测试和E2E测试应该分开存放
2. **符合最佳实践**：单元测试放在`src/`目录，E2E测试放在`e2e/`目录
3. **便于维护**：工具类和单元测试在同一目录，便于查找和修改
4. **避免冲突**：彻底解决Playwright与Vitest的冲突问题

### 文件结构变更

**迁移前**：
```
e2e/role-based-tests/
├── shared/
│   ├── __tests__/
│   │   ├── permission-helper.test.ts
│   │   ├── role-auth-manager.test.ts
│   │   └── test-data-manager.test.ts
│   ├── auth-helper.ts
│   ├── permission-helper.ts
│   ├── role-auth-manager.ts
│   └── test-data-manager.ts
├── roles/
│   ├── __tests__/
│   │   ├── admin.role.test.ts
│   │   ├── base.role.test.ts
│   │   └── role-factory.test.ts
│   ├── admin.role.ts
│   ├── base.role.ts
│   ├── role-factory.ts
│   └── user.role.ts
└── scenarios/
    ├── authentication/
    │   ├── login-flow.spec.ts
    │   └── logout-flow.spec.ts
    └── user-management/
        ├── admin-creates-user.spec.ts
        └── permission-boundary.spec.ts
```

**迁移后**：
```
src/role-based-tests/
├── shared/
│   ├── __tests__/
│   │   ├── permission-helper.test.ts
│   │   ├── role-auth-manager.test.ts
│   │   └── test-data-manager.test.ts
│   ├── auth-helper.ts
│   ├── permission-helper.ts
│   ├── role-auth-manager.ts
│   └── test-data-manager.ts
└── roles/
    ├── __tests__/
    │   ├── admin.role.test.ts
    │   ├── base.role.test.ts
    │   └── role-factory.test.ts
    ├── admin.role.ts
    ├── base.role.ts
    ├── role-factory.ts
    └── user.role.ts

e2e/role-based-tests/
└── scenarios/
    ├── authentication/
    │   ├── login-flow.spec.ts
    │   └── logout-flow.spec.ts
    └── user-management/
        ├── admin-creates-user.spec.ts
        └── permission-boundary.spec.ts
```

## 3. 实施步骤

### 步骤1：创建目标目录结构
```bash
mkdir -p src/role-based-tests/shared/__tests__
mkdir -p src/role-based-tests/roles/__tests__
```

### 步骤2：迁移shared目录
```bash
# 迁移工具类
mv e2e/role-based-tests/shared/*.ts src/role-based-tests/shared/
# 迁移单元测试
mv e2e/role-based-tests/shared/__tests__/*.test.ts src/role-based-tests/shared/__tests__/
```

### 步骤3：迁移roles目录
```bash
# 迁移角色定义
mv e2e/role-based-tests/roles/*.ts src/role-based-tests/roles/
# 迁移单元测试
mv e2e/role-based-tests/roles/__tests__/*.test.ts src/role-based-tests/roles/__tests__/
```

### 步骤4：删除空目录
```bash
rm -rf e2e/role-based-tests/shared
rm -rf e2e/role-based-tests/roles
```

### 步骤5：更新vitest配置

**文件**: `vitest.config.ts`

**变更前**：
```typescript
include: [
  'src/test/**/*.{test,spec}.{js,ts,jsx,tsx}',
  'e2e/role-based-tests/**/__tests__/*.{test,spec}.{js,ts,jsx,tsx}'
]
```

**变更后**：
```typescript
include: [
  'src/test/**/*.{test,spec}.{js,ts,jsx,tsx}',
  'src/__tests__/**/*.{test,spec}.{js,ts,jsx,tsx}'
]
```

**完整配置更新**：
```typescript
export default defineConfig({
  plugins: [vue()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./src/test/setup.ts'],
    include: [
      'src/test/**/*.{test,spec}.{js,ts,jsx,tsx}',
      'src/__tests__/**/*.{test,spec}.{js,ts,jsx,tsx}'
    ],
    exclude: [
      'node_modules/',
      'dist/',
      'e2e/**/*.spec.ts',
      '**/*.d.ts',
      '**/*.config.*',
      '**/mockData',
    ],
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html', 'lcov'],
      exclude: [
        'node_modules/',
        'src/test/',
        'src/__tests__/',
        '**/*.d.ts',
        '**/*.config.*',
        '**/mockData',
        'e2e/',
      ],
      lines: 80,
      functions: 80,
      branches: 80,
      statements: 80,
    },
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
})
```

### 步骤6：更新E2E测试导入路径

**文件**: `e2e/role-based-tests/scenarios/authentication/login-flow.spec.ts`

**变更前**：
```typescript
import { RoleFactory } from '../../roles/role-factory';
import { createAuthenticatedPage } from '../../shared/auth-helper';
```

**变更后**：
```typescript
import { RoleFactory } from '@/role-based-tests/roles/role-factory';
import { createAuthenticatedPage } from '@/role-based-tests/shared/auth-helper';
```

**需要更新的文件**：
1. `e2e/role-based-tests/scenarios/authentication/login-flow.spec.ts`
2. `e2e/role-based-tests/scenarios/authentication/logout-flow.spec.ts`
3. `e2e/role-based-tests/scenarios/user-management/admin-creates-user.spec.ts`
4. `e2e/role-based-tests/scenarios/user-management/permission-boundary.spec.ts`

## 4. 验证步骤

### 4.1 验证单元测试
```bash
npm run test:unit
```

**预期结果**：
- 所有单元测试通过
- vitest能够正确找到`src/role-based-tests/`下的测试文件

### 4.2 验证E2E测试
```bash
npx playwright test e2e/role-based-tests --project=chromium
```

**预期结果**：
- 无TypeError错误
- 所有E2E测试正常运行

### 4.3 验证导入路径
```bash
npm run type-check
```

**预期结果**：
- 无类型错误
- TypeScript能够正确解析`@/`别名

## 5. 风险与缓解措施

### 风险1：导入路径遗漏
**描述**：可能有其他文件引用了迁移的文件
**缓解措施**：
- 使用grep搜索所有引用
- 运行类型检查确保无遗漏

### 风险2：Playwright配置冲突
**描述**：Playwright可能无法正确解析`@/`别名
**缓解措施**：
- Playwright使用自己的配置，不依赖tsconfig.json
- 如果出现问题，可以使用相对路径作为备选方案

### 风险3：单元测试依赖问题
**描述**：单元测试可能依赖E2E测试的某些资源
**缓解措施**：
- 单元测试使用相对路径导入，不依赖别名
- 迁移后立即运行测试验证

## 6. 后续优化建议

1. **清理诊断代码**：移除`PasswordDiagnosticHandler.java`（生产环境不需要）
2. **完善测试文档**：更新README，说明单元测试和E2E测试的运行方式
3. **CI/CD集成**：确保CI流水线正确运行单元测试和E2E测试

## 7. 参考资料

- [Vitest配置文档](https://vitest.dev/config/)
- [Playwright配置文档](https://playwright.dev/docs/test-configuration)
- [TypeScript路径映射](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping)
