# 测试模式 **分析日期:** 2026-05-07 ## 测试框架 **当前状态:** 未检测到测试基础设施 - **运行器:** 未配置(package.json 中无 Jest、Vitest、Playwright 等依赖) - **断言库:** 未配置 - **测试脚本:** 未在 package.json 中定义(仅有 `dev`、`build`、`start`、`lint`) ## 测试文件组织 **当前:** 无测试文件 项目中未发现 `*.test.ts`、`*.test.tsx`、`*.spec.ts`、`*.spec.tsx`、`__tests__/` 目录等标准测试文件结构。 ## 测试覆盖 **要求:** 未强制 **影响:** - 新增代码(尤其是 API 集成、表单验证、权限逻辑)缺乏自动化验证 - 技术债风险:`next.config.mjs` 中 `typescript.ignoreBuildErrors: true` 和 `eslint.ignoreDuringBuilds: true`,导致构建时不检查类型和 lint 错误 - 手动测试依赖性高 ## 关键需要测试的区域 ### API 集成层 **位置:** `lib/api/*.ts` **建议测试:** - 认证流程(`emailLogin`、`saveAuthToken`、`logout`) - API 请求拦截器(token 注入、过期处理) - 响应拦截器(401 处理、重定向) - 数据适配器(如 `mapBackendOutfit()` 将后端结构映射到前端类型) - 错误处理(`handleApiException`、`handleApiRequest` 的成功/失败路径) **示例测试需求:** ```typescript // 应测试:token 自动注入 test('请求拦截器应在请求头中添加 Bearer token', () => { // 前置条件:localStorage 中有 auth_token // 发送 API 请求 // 验证:Authorization 头包含 "Bearer " }) // 应测试:401 处理 test('响应拦截器应在收到 401 时清除 token 并重定向到登录', () => { // 前置条件:发送请求后服务器返回 401 // 验证:localStorage 中 auth_token 被移除 // 验证:浏览器重定向到 /login }) // 应测试:数据适配 test('mapBackendOutfit 应正确转换后端服装数据', () => { const backendData = { id: 1, name: '测试服装', image_url: '...' } const result = mapBackendOutfit(backendData) expect(result).toHaveProperty('imageUrl') // 字段映射 expect(result.id).toBe('1') // 类型转换 }) ``` ### 权限控制 **位置:** `lib/permissions.ts` **建议测试:** - `hasPermission(module)` 根据用户角色返回正确的权限 - `getUserRole()` 从 localStorage 获取当前角色 - `getModuleFromPath(pathname)` 正确提取路径中的模块 - `hasPathPermission(pathname)` 组合权限检查 **示例测试需求:** ```typescript test('超级管理员应有所有模块的权限', () => { // 前置:localStorage.user_role = '超级管理员' // 验证:hasPermission('users') === true // 验证:hasPermission('ai-model') === true // 等等所有模块 }) test('内容管理员应无权限访问用户管理', () => { // 前置:localStorage.user_role = '内容管理员' // 验证:hasPermission('users') === false // 验证:hasPermission('outfits') === true }) ``` ### 表单验证与提交 **位置:** `components/*/add-*-dialog.tsx`、`app/*/page.tsx` **当前模式:** - 使用 `useState` 管理表单状态 - 基本的非空检查(如 `if (!formData.name || !formData.description)` 在 `add-achievement-dialog.tsx`) - 客户端验证不完整 **建议测试:** - 必填字段验证(空值拒绝) - 表单提交成功调用正确的 API - 提交过程中加载状态变化(`isSubmitting`) - 表单重置(关闭后清空状态) - 错误显示(API 失败时显示 toast) **示例测试需求:** ```typescript test('添加服装对话框应在名称为空时禁用提交', () => { // 渲染 AddOutfitDialog // 验证:提交按钮禁用状态 }) test('提交表单应调用 createOutfit API', () => { // 填写表单字段 // 点击提交 // 验证:createOutfit 被调用,参数正确 }) ``` ### 组件交互 **位置:** `components/` **建议测试:** - 对话框打开/关闭状态 - 模态框表单的步骤导航(`step` 状态变化) - 确认对话框的确认/取消操作 - 列表分页和搜索 **示例测试需求:** ```typescript test('AddOutfitDialog 应在提交后关闭', () => { // 渲染对话框 // 填写并提交表单 // 验证:对话框关闭(open === false) }) test('多步表单应在点击"下一步"时更新步骤', () => { // 验证:初始 step === 1 // 点击"下一步"按钮 // 验证:step === 2 }) ``` ### 中间件和路由保护 **位置:** `middleware.ts` **建议测试:** - 无 token 访问受保护路由时重定向到 `/login` - 有 token 时允许访问受保护路由 - 公共路由(登录、注册)不需要 token **示例测试需求:** ```typescript test('中间件应将无 token 的请求重定向到登录', () => { // 模拟请求:GET /outfits,无 auth_token cookie // 验证:重定向到 /login?callbackUrl=/outfits }) test('中间件应允许有 token 的请求', () => { // 模拟请求:GET /users,包含有效 auth_token cookie // 验证:通过,继续处理 }) ``` ## 建议的测试设置 ### 推荐框架组合 **单元/集成测试:** - **运行器:** Vitest(与 Next.js 15 兼容,开发体验优于 Jest) - **断言:** Vitest 内置(或 @testing-library/jest-dom) - **Mock 库:** vitest 的 `vi` 模块或 `@testing-library/react` **E2E 测试(可选):** - **框架:** Playwright 或 Cypress - **用途:** 完整登录流、权限控制、多步表单 ### 安装建议 ```bash # 安装 Vitest 和相关工具 npm install -D vitest @vitest/ui @testing-library/react @testing-library/jest-dom # 创建配置文件 vitest.config.ts ``` ### 最小化配置示例 ```typescript // vitest.config.ts import { defineConfig } from 'vitest/config' import react from '@vitejs/plugin-react' import path from 'path' export default defineConfig({ plugins: [react()], test: { globals: true, environment: 'jsdom', setupFiles: ['./test/setup.ts'], }, resolve: { alias: { '@': path.resolve(__dirname, '.'), }, }, }) // test/setup.ts import '@testing-library/jest-dom' ``` ### package.json 脚本建议 ```json { "scripts": { "test": "vitest", "test:ui": "vitest --ui", "test:coverage": "vitest --coverage", "test:run": "vitest run" } } ``` ## 测试文件结构建议 ``` project-root/ ├── lib/ │ ├── api/ │ │ ├── auth.ts │ │ ├── auth.test.ts # API 认证测试 │ │ ├── outfits.ts │ │ ├── outfits.test.ts # API 服装测试 │ │ └── ... │ ├── permissions.ts │ └── permissions.test.ts # 权限逻辑测试 ├── components/ │ ├── add-outfit-dialog.tsx │ ├── add-outfit-dialog.test.tsx # 组件交互测试 │ └── ... ├── app/ │ ├── login/ │ │ ├── page.tsx │ │ └── page.test.tsx # 登录页测试 │ └── ... ├── test/ │ ├── setup.ts # 测试环境初始化 │ ├── mocks/ │ │ ├── handlers.ts # MSW 请求拦截器 │ │ └── server.ts # MSW 服务器配置 │ └── fixtures/ │ ├── auth.fixture.ts # 认证数据 fixtures │ └── outfits.fixture.ts # 服装数据 fixtures └── vitest.config.ts ``` ## 当前缺失的覆盖范围 **高优先级(生产关键):** - ✗ API 集成和数据适配 - ✗ 认证流程(登录、token 管理、登出) - ✗ 权限检查和路由保护 - ✗ 表单验证和提交 **中优先级(功能完整性):** - ✗ 错误处理和用户通知 - ✗ 组件交互(对话框、模态框) - ✗ 列表管理(分页、搜索) **低优先级(UX 细节):** - ✗ 样式和响应性 - ✗ 无障碍访问 (a11y) --- *测试分析日期:2026-05-07* **关键建议:** 该项目缺乏测试基础设施,强烈建议在新增核心功能(特别是认证、权限、API 集成)时同步添加测试。考虑从 API 层和权限控制开始,这些是最容易产生 bug 的关键区域。