# 角色测试框架迁移设计文档 **日期**: 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)