# 管理会计OS(CMA)测试方案文档 > 项目:cma.sxbh.ltd > 后端路径:`/root/cma-management/backend/` > 前端路径:`/root/cma-management/frontend/` > 编制日期:2026-06-08 --- ## 一、现状评估 ### 1.1 后端规模 | 维度 | 数量 | |------|------| | 全部API路由 | 121个 | | API模块 | 22个 | | 已有测试模块 | 3个(auth 8例 / kpis 7例 / maps 7例 = 共22例) | | 零测试模块 | 19个 | | 工具层文件 | 6个(全部零测试) | ### 1.2 测试缺口 - **覆盖模块率**: 3/22 = **13.6%** - **用例数/API数**: 22/121 = **18.2%** - **前端**: 零测试文件,零测试脚本配置 - **工具层**: 6个文件合计约1297行代码零覆盖 ### 1.3 现有测试基础设施(conftest.py) ``` - SQLite内存数据库引擎替换(monkey-patch database._engine) - 自动setup_db fixture(create_all / drop_all) - db session fixture - TestClient+依赖覆盖的 client fixture - 3个工厂函数(create_test_user, create_test_kpi, create_test_map) - 1个token获取辅助函数(get_token_for_user) - 1个auth_header辅助函数 ``` --- ## 二、优先级分批策略 ### 第一批(P0)——核心业务流,必须立即覆盖 | 模块 | API数 | 优先级原因 | |------|-------|-----------| | alerts(预警) | 6 | 核心告警流程,依赖链上游 | | ai_analysis(AI分析) | 6 | CEO简报/分析主功能,涉及DeepSeek外部API | | dashboard(驾驶舱) | 12 | 首页核心入口,多角色视图 | | action_plans(改善行动) | 5 | 预警下游,管理闭环 | **P0小计:29个API,约90-120个测试用例** ### 第二批(P1)——关键支撑层 | 模块 | API数 | 优先级原因 | |------|-------|-----------| | notifications(通知渠道) | 7 | 多渠道推送,依赖外部服务 | | data(数据对接) | 6 | Excel导入、数据源配置 | | users(用户管理) | 4 | admin管理功能 | | cache(缓存层) | 1 | 缓存工具类 | | calc_engine(计算引擎) | 1 | KPI计算引擎 | | cost_engine(成本引擎) | 1 | 成本分析引擎 | | deviation_engine(差异引擎) | 1 | 差异预警引擎 | | predict_engine(预测引擎) | 1 | 预测模拟引擎 | | notifier(推送器) | 1 | 多渠道通知推送工具 | **P1小计:26个API + 6个工具层,约70-100个测试用例** ### 第三批(P2)——后台管理/辅助模块 | 模块 | API数 | 优先级原因 | |------|-------|-----------| | templates(KPI模板) | 6 | 模板CRUD,相对独立 | | budget(预算管理) | 10 | 预算计划CRUD+分解 | | cost(成本分析) | 14 | 成本卡片/差异分析 | | org(组织管理) | 6 | 组织树CRUD | | objectives(地图目标) | 5 | 战略目标管理 | | alignment(目标对齐) | 4 | 对齐模式管理 | | permissions(权限管理) | 3 | 角色权限配置 | | versions(版本管理) | 3 | 地图版本管理 | | alert_rules(预警规则) | 2 | 规则配置 | | thresholds(阈值设置) | 1 | 阈值配置 | | auth(补全) | ~2 | 现有8例,补全password/reset等 | | kpis(补全) | ~3 | 现有7例,补全filter/batch等 | | maps(补全) | ~3 | 现有7例,补全delete/duplicate等 | **P2小计:约64个API,约80-120个测试用例** --- ## 三、分批详细测试用例清单 ### 3.1 第一批(P0) #### 3.1.1 Alerts(预警)— 6 API → ~20 个测试用例 | 序号 | API路径 | 方法 | 测试场景 | 预估用例 | |------|---------|------|---------|---------| | A01 | `GET /api/cma/alerts` | GET | 空列表、有数据列表、按status过滤、分页 | 4 | | A02 | `POST /api/cma/alerts/{id}/process` | POST | 正常处理、缺少assignee报400、不存在的alert报404、已resolved重复处理报400 | 4 | | A03 | `POST /api/cma/alerts/{id}/resolve` | POST | 正常解决、不存在的alert、附带resolution文本 | 3 | | A04 | `POST /api/cma/alerts/{id}/escalate` | POST | yellow→red升级、red保持red、缺少assignee | 3 | | A05 | `GET /api/cma/alerts/check-timeout` | GET | 无超时项、有超时项自动升级 | 3 | | A06 | `POST /api/cma/alerts/{id}/create-action-plan` | POST | 正常创建、已关联报400、不存在的alert | 3 | **工作量:约 1.5 人天** #### 3.1.2 AI Analysis(AI分析)— 6 API → ~12 个测试用例 | 序号 | API路径 | 方法 | 测试场景 | 预估用例 | |------|---------|------|---------|---------| | B01 | `GET /api/cma/ai/dashboard-analysis` | GET | 无数据返回模板结论、有数据正常返回、缓存命中 | 3 | | B02 | `GET /api/cma/ai/kpi-analysis/{id}` | GET | 存在KPI返回分析、不存在KPI报404 | 2 | | B03 | `GET /api/cma/ai/dashboard-analysis-stream` | GET | SSE流式返回、缓存命中走缓存流 | 2 | | B04 | `POST /api/cma/ai/ask` | POST | 有效问题返回、空问题返回400 | 2 | | B05 | `POST /api/cma/ai/review-plans` | POST | 有plans返回分析、无plans返回提示 | 2 | | B06 | `GET /api/cma/ai/brief` | GET | 无数据返回默认brief、有数据解析brief | 2 | > 注:AI分析模块依赖DeepSeek外部API,测试中应mock `_call_deepseek` 函数,避免网络依赖。 **工作量:约 1 人天(含mock搭建)** #### 3.1.3 Dashboard(驾驶舱)— 12 API → ~35 个测试用例 | 序号 | API路径 | 方法 | 测试场景 | 预估用例 | |------|---------|------|---------|---------| | C01 | `GET /api/cma/dashboard/summary` | GET | 空数据库、有KPI/Alert数据、缓存命中 | 4 | | C02 | `GET /api/cma/dashboard/kpis` | GET | 无数据、有数据、period=month/quarter/year/custom | 5 | | C03 | `GET /api/cma/dashboard/my-kpis` | GET | business角色筛选、其他角色全量、无数据 | 3 | | C04 | `GET /api/cma/dashboard/finance-analysis` | GET | 无数据、有典型KPI(SALES_TOTAL等) | 3 | | C05 | `GET /api/cma/dashboard/predict` | GET | 无历史数据、<3个点跳过、3+个点正常预测 | 3 | | C06 | `GET /api/cma/dashboard/my-dashboard` | GET | 不同角色返回不同KPI、有action_plans、reminders | 4 | | C07 | `GET /api/cma/dashboard/erp-trends` | GET | 部分KPI存在、全部存在 | 2 | | C08 | `GET /api/cma/dashboard/dupont` | GET | 完整数据计算ROE、部分数据缺省 | 3 | | C09 | `GET /api/cma/dashboard/kpis/enhanced` | GET | 带趋势数据返回 | 2 | | C10 | `GET /api/cma/dashboard/trend-analysis` | GET | 多KPI趋势对比、空ids | 2 | | C11 | `GET /api/cma/dashboard/alert-stats` | GET | 按等级统计、按维度统计 | 2 | | C12 | `GET /api/cma/dashboard/export` | GET | CSV导出、指定kpi_ids过滤 | 2 | **工作量:约 2.5 人天** #### 3.1.4 Action Plans(改善行动)— 5 API → ~20 个测试用例 | 序号 | API路径 | 方法 | 测试场景 | 预估用例 | |------|---------|------|---------|---------| | D01 | `GET /api/cma/action-plans` | GET | 空列表、有数据、各种筛选参数、分页、business角色过滤 | 6 | | D02 | `GET /api/cma/action-plans/stats` | GET | 各状态和逾期统计、无数据 | 2 | | D03 | `POST /api/cma/action-plans` | POST | 正常创建、缺少必填字段、带所有字段 | 3 | | D04 | `PUT /api/cma/action-plans/{id}` | PUT | 更新各字段(title/status/progress等)、不存在报404 | 5 | | D05 | `DELETE /api/cma/action-plans/{id}` | DELETE | 正常删除、不存在报404 | 2+ | | D06 | 已存在关联alert_id的创建 | POST | 边界情况 | 2 | **工作量:约 1.5 人天** --- ### 3.2 第二批(P1) #### 3.2.1 Notifications(通知)— 7 API → ~20 个测试用例 | 序号 | API路径 | 方法 | 测试场景 | |------|---------|------|---------| | E01 | `GET /api/cma/notifications/channels` | GET | 空列表、有渠道列表 | | E02 | `POST /api/cma/notifications/channels` | POST | 创建各类型渠道(wecom/email) | | E03 | `PUT /api/cma/notifications/channels/{id}` | PUT | 更新配置、不存在报404 | | E04 | `DELETE /api/cma/notifications/channels/{id}` | DELETE | 正常删除 | | E05 | `POST /api/cma/notifications/channels/{id}/test` | POST | 正常测试推送(mock notifier) | | E06 | `POST /api/cma/notifications/alerts/push` | POST | 手动推送(mock push_pending_alerts) | | E07 | `GET /api/cma/notifications/logs` | GET | 空日志、有日志、分页 | **工作量:约 1.5 人天** #### 3.2.2 Data(数据对接)— 6 API → ~15 个测试用例 | 序号 | API路径 | 方法 | 测试场景 | |------|---------|------|---------| | F01 | `POST /api/cma/data/import-excel` | POST | 合法Excel导入、缺少列报400、部分无效行 | | F02-06 | 其他data API | 各种 | 数据源配置CRUD、操作日志查询等 | **工作量:约 1.5 人天** #### 3.2.3 Users(用户管理)— 4 API → ~10 个测试用例 | 序号 | API路径 | 方法 | 测试场景 | |------|---------|------|---------| | G01 | `GET /api/cma/users` | GET | 用户列表 | | G02 | `POST /api/cma/users` | POST | 创建用户、重复用户名报400 | | G03 | `PUT /api/cma/users/{id}` | PUT | 更新用户 | | G04 | `DELETE /api/cma/users/{id}` | DELETE | 删除用户 | **工作量:约 0.5 人天** #### 3.2.4 工具层 Utils(单元测试)— 6文件 → ~25 个测试用例 | 文件名 | 行数 | 核心函数 | 测试场景 | 用例数 | |--------|------|---------|---------|--------| | `utils/notifier.py` | 251 | send_wecom_robot, send_email, push_alert, push_pending_alerts | 各渠道发送成功/失败、无渠道跳过 | 6 | | `utils/calc_engine.py` | 93 | calculate_all | ERP数据获取、KPI计算 | 4 | | `utils/cost_engine.py` | 282 | calc_variance, get_cost_overview, get_cost_breakdown, calc_driver_rate, allocate_cost | 量差价差计算、ABC分配 | 6 | | `utils/deviation_engine.py` | 311 | calc_deviation, check_trend_anomaly | 差异额/率计算、趋势检测 | 5 | | `utils/predict_engine.py` | 260 | cvp_analysis, npv_irr, sensitivity_analysis, scenario_simulation | CVP分析、NPV/IRR、敏感性分析 | 6 | | `utils/cache.py` | 100 | get, set, delete, clear_all | Redis可用/不可用、读/写/删 | 4 | **工作量:约 2 人天(纯单元测试,不依赖HTTP)** --- ### 3.3 第三批(P2) #### 3.3.1 各模块测试用例汇总 | 模块 | API数 | 建议用例数 | 预估工作量(人天) | |------|-------|-----------|-----------------| | templates(KPI模板) | 6 | 12-15 | 1 | | budget(预算管理) | 10 | 20-25 | 2 | | cost(成本分析) | 14 | 25-30 | 2.5 | | org(组织管理) | 6 | 12-15 | 1 | | objectives(地图目标) | 5 | 10-12 | 0.8 | | alignment(目标对齐) | 4 | 8-10 | 0.5 | | permissions(权限管理) | 3 | 6-8 | 0.5 | | versions(版本管理) | 3 | 6-8 | 0.4 | | alert_rules(预警规则) | 2 | 4-6 | 0.3 | | thresholds(阈值设置) | 1 | 2-4 | 0.2 | | auth(补全) | ~2 | 3-5 | 0.3 | | kpis(补全) | ~3 | 4-6 | 0.3 | | maps(补全) | ~3 | 4-6 | 0.3 | **工作量:约 10 人天** --- ## 四、现有 conftest.py 评估与改进 ### 4.1 评估结论 **当前conftest.py基本可用,但需要以下增强:** ### 4.2 需要补充的fixture | 序号 | fixture名 | 用途 | 优先级 | |------|-----------|------|--------| | 1 | `create_test_kpi_value` | 创建KPIValue测试数据(含不同period) | P0 | | 2 | `create_test_alert` | 创建KPIAlert测试数据(含各种状态和等级) | P0 | | 3 | `create_test_action_plan` | 创建ActionPlan测试数据 | P0 | | 4 | `create_test_notification_channel` | 创建NotificationChannel测试数据 | P1 | | 5 | `create_test_budget_plan` | 创建BudgetPlan测试数据 | P2 | | 6 | `create_test_org_node` | 创建OrgNode测试数据(含父子层级) | P2 | | 7 | `create_test_template` | 创建KPITemplate测试数据 | P2 | | 8 | `mock_deepseek` | mock `_call_deepseek` 避免外部API调用 | P0 | | 9 | `mock_notifier` | mock `push_alert` 等推送函数 | P1 | | 10 | `authenticated_client` | 预置auth的client fixture,简化认证测试 | P0 | | 11 | `create_test_kpis_batch` | 批量创建KPI(for dashboard趋势测试) | P0 | | 12 | `create_test_standard_cost` | 创建标准成本卡片数据 | P2 | | 13 | `mock_erp_api` | mock ERP API HTTP调用 | P1/P2 | ### 4.3 conftest.py 需要修改的部分 ```python # 1. 补充 model 导入(已有conftest只导入部分model,需补全) from app.models import ( User, StrategicMap, KPIDefinition, KPIValue, KPIAlert, ActionPlan, OrgNode, StrategicMapVersion, NotificationChannel, NotificationLog, # 新增 BudgetPlan, # 新增 KPITemplate, # 新增 StandardCost, ActualCost, AbcActivity, # 新增 MapObjective, # 新增 RolePermission, # 新增 DataSourceConfig, OperationLog, # 新增 ) # 2. 新增 authenticated_client fixture @pytest.fixture def authenticated_client(client, db): """预创建测试用户并返回已登录的client + token""" user = create_test_user(db) token = get_token_for_user(client) client.headers.update({"Authorization": f"Bearer {token}"}) return client, user, token # 3. 新增批量创建工厂函数(P0必须) ``` --- ## 五、与现有测试框架融合方案 ### 5.1 保持架构一致 沿用现有模式: ``` tests/ ├── conftest.py # 统一fixture和工厂函数(集中扩展) ├── test_auth.py # 已有 ├── test_kpis.py # 已有 ├── test_maps.py # 已有 ├── test_alerts.py # 新增(P0) ├── test_ai_analysis.py # 新增(P0) ├── test_dashboard.py # 新增(P0) ├── test_action_plans.py # 新增(P0) ├── test_notifications.py # 新增(P1) ├── test_data.py # 新增(P1) ├── test_users.py # 新增(P1) ├── test_utils_notifier.py # 新增(P1) 工具层单元测试 ├── test_utils_calc_engine.py # 新增(P1) ├── test_utils_cost_engine.py # 新增(P1) ├── test_utils_deviation_engine.py # 新增(P1) ├── test_utils_predict_engine.py # 新增(P1) ├── test_utils_cache.py # 新增(P1) ├── test_templates.py # 新增(P2) ├── test_budget.py # 新增(P2) ├── test_cost.py # 新增(P2) ├── test_org.py # 新增(P2) ├── test_objectives.py # 新增(P2) ├── test_alignment.py # 新增(P2) ├── test_permissions.py # 新增(P2) ├── test_versions.py # 新增(P2) ├── test_alert_rules.py # 新增(P2) └── test_thresholds.py # 新增(P2) ``` ### 5.2 测试运行配置 在 `backend/` 目录下创建 `pytest.ini`(如果不存在): ```ini [pytest] testpaths = tests python_files = test_*.py python_classes = Test* python_functions = test_* addopts = -v --tb=short --strict-markers markers = slow: 慢速测试(涉及外部API) unit: 纯单元测试(不依赖HTTP) integration: 集成测试(依赖HTTP client) ``` ### 5.3 运行方式 ```bash # 全部测试 cd /root/cma-management/backend python -m pytest # 按优先级批次 python -m pytest tests/test_alerts.py tests/test_dashboard.py tests/test_ai_analysis.py tests/test_action_plans.py -v # 工具层单元测试(不依赖HTTP) python -m pytest tests/test_utils_*.py -v # 带覆盖率 python -m pytest --cov=app --cov-report=term --cov-report=html:coverage_report ``` ### 5.4 关键注意事项 1. **数据库隔离**:SQLite 不支持 MySQL 的JSON类型,conftest.py 中 `StrategicMap.dimensions` 等 JSON 字段在 SQLAlchemy 层面应使用 `Text` 或 `JSON` 类型。当前已有 `dimensions` 和 `canvas_data` 字段,测试中传入 Python dict/list 即可——SQLite 模式下 SQLAlchemy 的 JSON 类型会回退为 PickleType 或 Text。 2. **Redis依赖**:`auth_middleware.py` 和 `cache.py` 尝试连接 Redis 会优雅降级。测试环境中 Redis 不可用,token 和缓存自动走内存模式,不影响测试。 3. **DeepSeek API**:`ai_analysis.py` 所有路由在实际测试中必须 mock `_call_deepseek` 函数(用 `unittest.mock.patch`),避免真实的网络请求。 4. **ERP API**:`calc_engine.py` 等工具层调用 `http://127.0.0.1:8300` 必须在测试中 mock HTTP 响应。 5. **Notifier**:`notifier.py` 的 `send_wecom_robot` 等发送函数必须在测试中 mock。 6. **日志文件**:`dashboard.py` 中读取 `/var/log/cma-daily-sync.log`,测试环境中不会存在,需确保函数优雅处理 `FileNotFoundError`。 --- ## 六、前端测试方案建议 ### 6.1 框架选择 | 框架 | 推荐度 | 说明 | |------|--------|------| | **Vitest** | ⭐⭐⭐⭐⭐ | Vite原生,与项目vite.config.ts无缝集成,社区活跃 | | Vue Test Utils | 配合Vitest | Vue官方组件测试工具 | | Playwright | ⭐⭐⭐⭐ | E2E测试,适合CMA这样需要验证复杂交互的系统 | | Cypress | ⭐⭐⭐ | 较重,但社区成熟 | **推荐方案:Vitest + @vue/test-utils(单元测试)+ Playwright(E2E测试)** ### 6.2 安装命令 ```bash cd /root/cma-management/frontend npm install -D vitest @vue/test-utils jsdom @playwright/test # 或用 yarn/pnpm ``` 在 `vite.config.ts` 中添加: ```ts /// import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], test: { environment: 'jsdom', globals: true, setupFiles: ['./tests/setup.ts'], }, }) ``` ### 6.3 组件测试覆盖建议(按优先级) #### P0 核心组件(立即覆盖) | 组件 | 测试重点 | |------|---------| | Dashboard.vue | 各角色视图渲染、空状态、数据加载状态 | | AlertPanel.vue | 预警列表渲染、状态流转操作、空状态 | | KpiCard.vue | 数据展示、预警灯显示、趋势图标 | | LoginForm.vue | 表单验证、登录成功/失败反馈 | | StrategicMap.vue | 地图渲染、连线交互、版本切换 | | AiSidebar.vue | 分析结果展示、负载状态、错误状态 | #### P1 功能组件 | 组件 | 测试重点 | |------|---------| | ActionPlanList.vue | 列表渲染、筛选、状态更新 | | NotificationChannel.vue | 渠道配置表单验证 | | DataImport.vue | 文件上传、导入结果展示 | | MyDashboard.vue | 个人工作台数据展示 | #### P2 管理组件 | 组件 | 测试重点 | |------|---------| | UserManage.vue | 用户CRUD表格 | | OrgTree.vue | 组织树渲染、节点操作 | | BudgetForm.vue | 预算值编辑、版本切换 | | PermissionConfig.vue | 权限矩阵渲染、异步保存 | ### 6.4 E2E测试建议 使用 Playwright 覆盖以下核心用户流: 1. **登录 → 驾驶舱 → 查看KPI → 查看预警** 2. **登录 → 战略地图 → 编辑 → 发布 → 创建行动计划** 3. **预警处理:列表 → 处理 → 解决 → 创建行动计划** 4. **AI分析:打开分析面板 → 查看简报 → 提问** 5. **管理后台:用户管理 → 组织管理 → 权限配置** ### 6.5 前端测试目录结构 ``` frontend/ ├── tests/ │ ├── setup.ts # 测试环境初始化 │ ├── components/ │ │ ├── Dashboard.spec.ts │ │ ├── AlertPanel.spec.ts │ │ ├── KpiCard.spec.ts │ │ ├── LoginForm.spec.ts │ │ ├── StrategicMap.spec.ts │ │ └── ... │ ├── views/ │ │ ├── DashboardView.spec.ts │ │ └── ... │ ├── stores/ │ │ ├── authStore.spec.ts │ │ └── ... │ └── e2e/ │ ├── auth.spec.ts │ ├── dashboard.spec.ts │ └── alerts.spec.ts ├── package.json └── vite.config.ts ``` --- ## 七、总体工作量预估 | 批次 | 模块 | 测试用例数 | 工作量(人天) | |------|------|-----------|--------------| | P0 | alerts | 20 | 1.5 | | P0 | ai_analysis | 12 | 1.0 | | P0 | dashboard | 35 | 2.5 | | P0 | action_plans | 20 | 1.5 | | | **P0小计** | **87** | **6.5** | | P1 | notifications | 20 | 1.5 | | P1 | data | 15 | 1.5 | | P1 | users | 10 | 0.5 | | P1 | utils(6) | 25 | 2.0 | | | **P1小计** | **70** | **5.5** | | P2 | 其余12模块+补全 | 90-140 | 10.0 | | | **P2小计** | ~110 | **10.0** | | 前端 | 组件+E2E | 40-60 | 5.0 | | | **总计** | **~310** | **~27** | ### 建议排期 ``` 第1-2周: P0 (6.5人天) → alerts + dashboard + action_plans + ai_analysis 第3-4周: P1 (5.5人天) → notifications + data + users + utils 第5-7周: P2 (10人天) → 其余模块 第8-9周: 前端测试 (5人天) → 组件+E2E 第10周: 补丁、覆盖率优化、文档完善 ``` --- ## 八、测试质量目标 | 指标 | 当前 | 目标(P0后) | 目标(全部) | |------|------|-----------|----------| | 模块覆盖率 | 13.6% | 45% | 100% | | API覆盖率 | 18.2% | 50%+ | 90%+ | | 行覆盖率(backend) | ~5% | 30% | 70%+ | | 工具层覆盖率 | 0% | 60% | 85%+ | | 前端组件覆盖率 | 0% | 20% | 60%+ | --- ## 九、风险与缓解 | 风险 | 影响 | 缓解方案 | |------|------|---------| | SQLite与MySQL JSON字段不兼容 | 部分测试失败 | 用SQLAlchemy JSON类型;测试数据避免复杂JSON查询 | | DeepSeek API 在CI中不可用 | AI模块测试失败 | 所有AI测试强制mock外部调用 | | Redis不可用 | auth/token测试受影响 | conftest已降级到内存,无需额外处理 | | ERP HTTP API不可用 | 工具层测试失败 | 工具层测试用 `httpx.MockTransport` 或 `respx` | | 通知推送真实服务 | 测试可能触发真实推送 | 所有notifier函数在测试中mock | | 前端组件依赖Element Plus | 组件测试渲染异常 | Vitest配置global stubs | --- *文档结束,建议在执行测试开发前review确认。*