21 KiB
21 KiB
管理会计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 需要修改的部分
# 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(如果不存在):
[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 运行方式
# 全部测试
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 关键注意事项
- 数据库隔离:SQLite 不支持 MySQL 的JSON类型,conftest.py 中
StrategicMap.dimensions等 JSON 字段在 SQLAlchemy 层面应使用Text或JSON类型。当前已有dimensions和canvas_data字段,测试中传入 Python dict/list 即可——SQLite 模式下 SQLAlchemy 的 JSON 类型会回退为 PickleType 或 Text。 - Redis依赖:
auth_middleware.py和cache.py尝试连接 Redis 会优雅降级。测试环境中 Redis 不可用,token 和缓存自动走内存模式,不影响测试。 - DeepSeek API:
ai_analysis.py所有路由在实际测试中必须 mock_call_deepseek函数(用unittest.mock.patch),避免真实的网络请求。 - ERP API:
calc_engine.py等工具层调用http://127.0.0.1:8300必须在测试中 mock HTTP 响应。 - Notifier:
notifier.py的send_wecom_robot等发送函数必须在测试中 mock。 - 日志文件:
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 安装命令
cd /root/cma-management/frontend
npm install -D vitest @vue/test-utils jsdom @playwright/test
# 或用 yarn/pnpm
在 vite.config.ts 中添加:
/// <reference types="vitest" />
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 覆盖以下核心用户流:
- 登录 → 驾驶舱 → 查看KPI → 查看预警
- 登录 → 战略地图 → 编辑 → 发布 → 创建行动计划
- 预警处理:列表 → 处理 → 解决 → 创建行动计划
- AI分析:打开分析面板 → 查看简报 → 提问
- 管理后台:用户管理 → 组织管理 → 权限配置
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确认。