Files
sino-mci/docs/testing/2026-07-07-test-plan.md

15 KiB
Raw Blame History

sino-mci 测试补齐计划

日期2026-07-07
范围backendmci-server单元/集成测试、API 冒烟测试、前端手工测试、Chrome DevTools 测试场景、Docker 部署验证
执行标准命令:见第 7 节


1. 单元测试(已存在)

测试类 路径 覆盖内容
PolicyEngineTest send/service/PolicyEngineTest.java 频率限制rate_limit、时间窗time_window、黑名单blacklist及组合策略的允许/拒绝判定
SendServiceFailoverTest send/service/SendServiceFailoverTest.java 发送记录主备账号切换、全部账号不可用、无健康账号三种场景下的 SendService.dispatchRecord
AccountSelectorTest channel/service/AccountSelectorTest.java 会话发送账号选择:主号健康、主号不健康切备用、backup 策略优先、无健康账号返回 null
FlowEngineTest inbound/engine/FlowEngineTest.java 入站流程引擎:条件分支命中 webhook、未命中执行 reply、无发布流程时标记已处理
IntentRecognitionServiceTest inbound/intent/IntentRecognitionServiceTest.java 规则 + 槽位抽取的意图识别,无规则/无 LLM 时返回 unknown
InboundContextServiceTest inbound/service/InboundContextServiceTest.java 根据会话/联系人解析业务上下文,合并时优先保留会话维度字段
WebhookPayloadBuilderTest inbound/webhook/WebhookPayloadBuilderTest.java 入站 webhook payload 结构、方向映射、null 意图/空白 JSON 处理
WebhookSignatureServiceTest inbound/webhook/WebhookSignatureServiceTest.java HMAC-SHA256/512 签名、默认算法、不同 secret/算法签名差异
AccountControllerTest admin/controller/AccountControllerTest.java 租户创建接口
ChannelControllerTest channel/controller/ChannelControllerTest.java 渠道主体与渠道账号创建、企微回调 echo 校验
ChannelAccountHeartbeatTest channel/ChannelAccountHeartbeatTest.java 心跳更新账号在线/风险状态、超时离线检测
WeComSessionArchiveTest channel/controller/WeComSessionArchiveTest.java 企微 msgaudit_notify 回调、会话存档拉取并保存消息事件/媒体记录
WeComSyncTest channel/controller/WeComSyncTest.java 企微通讯录同步(人员+渠道身份)、群聊同步(会话+参与者+账号绑定)
CrmControllerTest crm/controller/CrmControllerTest.java 联系人、标签、会话的创建与列表查询
IvrFlowControllerTest flow/controller/IvrFlowControllerTest.java IVR 流程的增删改查、发布、下线生命周期
InboundFlowControllerTest inbound/controller/InboundFlowControllerTest.java 入站流程创建/发布、接收消息事件
SendControllerTest send/controller/SendControllerTest.java 发送接口:单聊发送、规则目标 and/or 逻辑、发送记录查询
SendPreviewControllerTest send/controller/SendPreviewControllerTest.java 发送预览:会话/规则目标、渠道拆分、账号用量、黑名单命中但不做限流计数
SendMessageConsumerTest send/mq/SendMessageConsumerTest.java MQ 异步消费:成功回调、失败重试、超过最大重试后的失败回调
TenantWebhookControllerTest admin/controller/TenantWebhookControllerTest.java 租户 webhook 配置查询/更新、测试推送成功/失败

2. 集成测试(补齐)

2.1 现有集成测试缺口

  • 现有 controller 级测试大多聚焦单接口或局部链路,缺少从租户创建到发送记录生成的完整出站链路。
  • 缺少从消息事件接收到 webhook 推送的完整入站链路验证。

2.2 新增集成测试

SendEndToEndTest.java

  • 路径backend/mci-server/src/test/java/com/sino/mci/send/service/SendEndToEndTest.java
  • 技术@SpringBootTest + @AutoConfigureMockMvc + @Transactional直接复用真实数据库Docker 中 MySQL
  • 覆盖步骤
    1. 创建租户并登录,获取 authToken
    2. 创建渠道主体wecom
    3. 创建渠道账号并关联主体;
    4. 创建会话并关联主体;
    5. 绑定账号为会话发送主号;
    6. 调用 /api/v1/send/test 模拟发送;
    7. 查询 /api/v1/send/{taskId}/records,校验记录数、状态、渠道类型、会话/账号 ID、内容。

InboundEndToEndTest.java

  • 路径backend/mci-server/src/test/java/com/sino/mci/inbound/engine/InboundEndToEndTest.java
  • 技术@SpringBootTest + @AutoConfigureMockMvc + @Transactional,通过 @TestConfigurationRestTemplate bean 替换为 mock。
  • 覆盖步骤
    1. 创建租户并登录;
    2. 配置租户入站 webhook URL 与签名密钥;
    3. 创建并发布入站流程:receive -> intent -> webhook
    4. 调用 /api/v1/inbound/receive 发送消息事件;
    5. 校验返回事件 isProcessed=1
    6. 验证 RestTemplate.exchange 被调用,且目标 URL 为租户配置的 webhook URL。

3. API 冒烟测试

基础地址:http://localhost:8080/msg-platform
所有业务接口需携带 X-Tenant-CodeAuthorization: Bearer <token>

3.1 健康检查

curl -fsS http://localhost:8080/msg-platform/api/v1/health

3.2 创建租户

curl -X POST http://localhost:8080/msg-platform/api/v1/account/tenant \
  -H 'Content-Type: application/json' \
  -d '{"tenantCode":"rescue","tenantName":"救援业务"}'

3.3 登录(获取 token

TOKEN=$(curl -s -X POST http://localhost:8080/msg-platform/api/v1/account/login \
  -H 'X-Tenant-Code: rescue' \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin123"}' | jq -r '.data.token')
echo "Bearer $TOKEN"

3.4 渠道主体 CRUD

curl -X POST http://localhost:8080/msg-platform/api/v1/channel-subject \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"channelType":"wecom","subjectCode":"sino","subjectName":"Sino"}'

curl -s http://localhost:8080/msg-platform/api/v1/channel-subject/list \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN"

3.5 渠道账号创建

curl -X POST http://localhost:8080/msg-platform/api/v1/channel-account \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"accountType":1,"channelType":"wecom","accountId":"ZhangSan","accountName":"张三"}'

3.6 会话创建与账号绑定

CONV_ID=$(curl -s -X POST http://localhost:8080/msg-platform/api/v1/conversation \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"conversationType":2,"channelType":"wecom","channelConversationId":"room-001","conversationName":"测试群"}' | jq -r '.data.id')

curl -X POST "http://localhost:8080/msg-platform/api/v1/conversation/$CONV_ID/bind-account" \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"accountId":1,"bindingType":1,"sortOrder":1}'

3.7 发送消息(模拟发送)

TASK_ID=$(curl -s -X POST http://localhost:8080/msg-platform/api/v1/send/test \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"targetType\":\"conversation\",\"targetValue\":{\"conversation_id\":$CONV_ID},\"contentType\":\"text\",\"content\":{\"text\":\"hello\"},\"channelStrategy\":{\"channel_type\":\"wecom\",\"strategy\":\"primary\"}}" | jq -r '.data.taskId')

curl -s "http://localhost:8080/msg-platform/api/v1/send/$TASK_ID/records" \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN"

3.8 入站消息接收

curl -X POST http://localhost:8080/msg-platform/api/v1/inbound/receive \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"eventId":"evt-001","channelType":"wecom","eventType":"message","messageSource":"realtime","conversationId":1,"personId":1,"content":{"type":"text","body":"我要救援"}}'

3.9 入站流程管理

curl -X POST http://localhost:8080/msg-platform/api/v1/inbound/flow \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"flowCode":"inbound_default","flowName":"默认入站流程","flowType":"inbound","definitionJson":{"nodes":[{"id":"n1","type":"receive"},{"id":"n2","type":"intent"},{"id":"n3","type":"webhook"}],"edges":[{"source":"n1","target":"n2"},{"source":"n2","target":"n3"}]}}'

curl -X POST http://localhost:8080/msg-platform/api/v1/inbound/flow/inbound_default/publish \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN"

3.10 租户 webhook 配置

curl -X POST http://localhost:8080/msg-platform/api/v1/account/tenant/webhook \
  -H 'X-Tenant-Code: rescue' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"inbound_webhook_url":"https://example.com/webhook","auth_config":{"sign_algorithm":"hmac-sha256","webhook_secret":"secret-123"}}'

4. 前端手工测试

前端地址:http://localhost

页面 路由 测试步骤 预期结果
登录 /login 输入租户编码、用户名 admin、密码 admin123 登录 跳转 /dashboard,本地存储 token
渠道主体 /channel-subject 新增 wecom 主体 → 保存 → 刷新列表 → 编辑主体名称 列表展示新增/更新后的主体,无报错
渠道账号 /channel-account 选择主体 → 新增企微内部账号 → 保存 → 触发同步通讯录/群聊 账号列表更新,同步返回成功提示
会话/群聊 /conversation 新增群聊 → 绑定发送/接收账号 → 绑定标签 会话详情正确显示绑定关系
发送策略 /send-policy 新建策略组 → 添加限流/时间窗/黑名单规则 → 保存 策略列表展示,规则 JSON 可预览
入站 Webhook /inbound-webhook 配置 URL 与签名密钥 → 点击测试推送 页面提示推送结果200/失败原因)
入站流程编排 /inbound-flow 拖拽 receive / intent / condition / webhook 节点 → 连线 → 保存并发布 流程定义持久化,发布状态变为已发布
发送记录 /send-record 发送消息后进入页面 → 按任务 ID/时间/状态筛选 列表展示发送记录及状态
IVR 流程 /ivr-flow 新建 IVR 流程 → 配置 start / menu 节点 → 保存/发布/下线 生命周期状态正常切换
消息测试 /message-test 选择会话 → 填写内容 → 点击发送 返回任务 ID发送记录可查询

5. Chrome DevTools 测试场景

5.1 通用检查项

  1. 打开 DevTools → Console,切换页面/提交表单,确认无未处理异常。
  2. 打开 Network 面板,过滤 XHR/Fetch,确认所有 API 请求:
    • 携带 X-Tenant-Code
    • 携带 Authorization: Bearer <token>
    • 返回 code: 0(业务成功)。
  3. 检查请求/响应 Payload 与架构文档字段是否一致snake_case / camelCase
  4. 模拟弱网:在 Network 面板选择 Slow 3G,观察加载状态与超时提示。
  5. 模拟后端 500Network 面板对 /api/v1/send/test 请求右键 Block request URL,观察前端错误处理。

5.2 页面级场景

页面 DevTools 操作 验证点
/login 登录后查看 Application → Local Storage auth-store 中保存 token、tenantCode、userInfo
/channel-subject 新增主体后查看 Network POST /api/v1/channel-subject 返回 code: 0,列表 GET 包含新主体
/channel-account 点击同步通讯录 POST /api/v1/channel-account/{id}/sync-contacts 返回 syncedCount
/conversation 绑定账号 POST /api/v1/conversation/{id}/bind-account 请求体字段正确
/send-policy 保存策略 POST /api/v1/policy-group 请求体 policies JSON 与表单一致
/inbound-webhook 点击测试推送 POST /api/v1/account/tenant/webhook/test 返回 successmessage
/inbound-flow 保存/发布流程 POST /api/v1/inbound/flow/publish 顺序正确payload 含 nodes/edges
/message-test 发送消息 POST /api/v1/send/test 返回 taskId,随后 GET /api/v1/send/{taskId}/records 返回状态 2
/send-record 筛选/分页 GET /api/v1/send/records 含 page/size 参数,响应 records 非空
/ivr-flow 发布/下线 POST /api/v1/flow/{code}/publish/offline 后状态码正确

6. Docker 部署测试

6.1 启动基础设施

cd /Users/marsal/Projects/sino-project/sino-mci
cp .env.example .env
# 按需编辑 .env
docker compose --profile infra up -d

等待所有 infra 服务 healthy

docker compose --profile infra ps

6.2 启动应用服务

docker compose --profile app up -d

6.3 验证健康检查

# MySQL
docker exec mci-mysql mysqladmin ping -h localhost -u root -proot

# Redis
docker exec mci-redis redis-cli ping

# RabbitMQ
docker exec mci-rabbitmq rabbitmq-diagnostics ping

# mci-server
curl -fsS http://localhost:8080/msg-platform/api/v1/health

# channel-service
curl -fsS http://localhost:8000/health

# admin-web通过首页判断
curl -fsS -o /dev/null -w '%{http_code}' http://localhost/

6.4 查看日志

docker compose --profile app logs -f mci-server
docker compose --profile app logs -f channel-service

7. 标准测试命令与结果

7.1 命令

cd /Users/marsal/Projects/sino-project/sino-mci/backend
docker run --rm --network sino-mci_mci-network --dns 8.8.8.8 \
  -v "$HOME/.m2:/root/.m2" -v "$(pwd):/app" -w /app \
  -e SPRING_DATASOURCE_URL='jdbc:mysql://mci-mysql:3306/sino_mci?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true' \
  -e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=root \
  -e SPRING_DATA_REDIS_HOST=mci-redis -e SPRING_RABBITMQ_HOST=mci-rabbitmq \
  maven:3.9-eclipse-temurin-21-alpine \
  mvn -B -pl mci-server -am test

7.2 运行结果

  • 总测试数59
  • 失败0
  • 错误0
  • 跳过0
  • 构建状态BUILD SUCCESS

新增测试类 SendEndToEndTestInboundEndToEndTest 均通过。


8. 后续可补充项

  • 引入 Testcontainers 或 H2 以支持无 Docker 环境的本地单元测试运行。
  • channel-service 增加 Python 侧端到端测试。
  • 补充前端自动化测试Playwright / Cypress覆盖第 4、5 节手工场景。
  • 增加性能/稳定性测试高并发发送、MQ 堆积恢复、会话存档大批量拉取。