Files

535 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 管理会计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 fixturecreate_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_analysisAI分析) | 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数 | 优先级原因 |
|------|-------|-----------|
| templatesKPI模板) | 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 AnalysisAI分析)— 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 | 无数据、有典型KPISALES_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数 | 建议用例数 | 预估工作量(人天) |
|------|-------|-----------|-----------------|
| templatesKPI模板) | 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` | 批量创建KPIfor 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(单元测试)+ PlaywrightE2E测试)**
### 6.2 安装命令
```bash
cd /root/cma-management/frontend
npm install -D vitest @vue/test-utils jsdom @playwright/test
# 或用 yarn/pnpm
```
`vite.config.ts` 中添加:
```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 覆盖以下核心用户流:
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确认。*