Files
wvp-platform/docs/camera_code改造测试报告.md
16337 87c75608f1 docs: camera_code改造测试报告
添加完整的测试报告文档,包括:
- 测试概述与环境要求
- 数据库迁移验证步骤
- 功能测试用例(摄像头创建、ROI截图、配置推送)
- 数据一致性测试
- 异常测试场景
- 性能测试
- 集成测试场景
- 回归测试
- 测试清单与风险评估

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 11:49:39 +08:00

14 KiB
Raw Blame History

camera_code 改造测试报告

一、测试概述

测试目标: 验证 camera_code 全链路改造的功能完整性和数据一致性

测试时间: 2026-02-13

改造范围:

  • 后端数据库、StreamProxy模块、AIoT模块
  • 前端摄像头管理、ROI配置、API调用

测试环境要求:

  • MySQL 5.7+
  • Redis 6.0+
  • ZLMediaKit 流媒体服务器
  • 前端开发环境Node.js 18+
  • 后端 Java 环境JDK 17+

二、测试准备

2.1 数据库迁移验证

脚本位置: C:\workspace\wvp-platform\数据库\aiot\迁移-添加camera_code字段.sql

执行步骤:

# 1. 进入SQL脚本目录
cd C:\workspace\wvp-platform\数据库\aiot

# 2. 执行迁移脚本需要MySQL客户端
mysql -h localhost -u root -p your_database < 迁移-添加camera_code字段.sql

预期结果:

  1. wvp_stream_proxy 表新增 camera_code 字段
  2. 现有数据自动生成 camera_code(格式:cam_xxxxxxxxxxxx
  3. camera_code 字段设置为 NOT NULL 和 UNIQUE 约束
  4. wvp_ai_roi 表的 camera_id 字段更新为对应的 camera_code
  5. 验证查询显示无重复、无格式错误

验证SQL:

-- 检查字段是否添加成功
SHOW COLUMNS FROM wvp_stream_proxy LIKE 'camera_code';

-- 检查唯一索引
SHOW INDEX FROM wvp_stream_proxy WHERE Key_name = 'uk_camera_code';

-- 检查数据完整性应返回0
SELECT COUNT(*) FROM wvp_stream_proxy WHERE camera_code IS NULL;

-- 检查格式正确性应返回0
SELECT COUNT(*) FROM wvp_stream_proxy
WHERE camera_code NOT REGEXP '^cam_[a-f0-9]{12}$';

-- 检查ROI表迁移情况
SELECT COUNT(*) FROM wvp_ai_roi r
LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code
WHERE sp.camera_code IS NULL;

三、功能测试用例

3.1 新增摄像头 - camera_code 自动生成

测试目的: 验证创建摄像头时 camera_code 自动生成逻辑

前置条件:

  • 系统正常运行
  • 流媒体服务器在线

测试步骤:

  1. 访问前端摄像头管理页面
  2. 点击"新增摄像头"按钮
  3. 填写摄像头信息:
    • 名称测试摄像头001
    • 拉流地址rtsp://example.com/test/stream1
    • 超时时间:默认
    • 注意:不需要手动填写 app 字段(系统自动生成)
  4. 提交保存

预期结果:

  1. 摄像头创建成功
  2. 系统自动生成 camera_code(格式:cam_xxxxxxxxxxxx
  3. app 字段自动设置为与 camera_code 相同
  4. stream 字段为系统生成的唯一标识
  5. 数据库 wvp_stream_proxy 表中插入新记录

验证SQL:

SELECT id, camera_code, app, stream, name, src_url
FROM wvp_stream_proxy
WHERE name = '测试摄像头001';

重点检查:

  • camera_code 格式符合 ^cam_[a-f0-9]{12}$
  • app = camera_code
  • camera_code 在全表唯一

3.2 ROI 截图功能 - cameraCode 参数

测试目的: 验证 ROI 截图接口改用 cameraCode 参数

前置条件:

  • 摄像头已创建并在线推流
  • 流媒体服务器正常

测试步骤:

  1. 访问 ROI 配置页面
  2. 选择已创建的摄像头
  3. 点击"获取截图"按钮
  4. 观察网络请求F12开发者工具

预期结果:

  1. 请求 URL/api/ai/roi/snap?cameraCode=cam_xxxxxxxxxxxx
  2. 使用 cameraCode 参数(而非旧的 app/stream
  3. 后端通过 cameraCode 查询 StreamProxy 对象
  4. 获取到正确的 appstream
  5. 调用 ZLM 截图接口成功,返回图片数据

验证方法:

// 浏览器控制台查看请求
// Network > Headers > Request URL
// 应包含 cameraCode=cam_xxxxxxxxxxxx

错误处理测试:

  • 使用不存在的 cameraCode → 返回 404 Not Found
  • 流媒体服务器离线 → 返回 503 Service Unavailable

3.3 配置推送到 Redis - camera_code 字段

测试目的: 验证配置推送使用 camera_code 查询和生成配置

前置条件:

  • Redis 服务正常
  • ROI 已配置并绑定算法
  • Edge 设备在线

测试步骤:

  1. 访问配置管理页面
  2. 创建或更新 ROI 配置
  3. 绑定算法模板
  4. 执行"配置推送"操作
  5. 检查 Redis 中的配置数据

预期结果:

  1. 配置构建时使用 camera_code 查询 StreamProxy
  2. 优先使用 StreamProxy.srcUrl 作为 rtsp_url
  3. Redis 配置中包含 camera_code 字段
  4. 保留 camera_id 字段向后兼容(值为 app/stream
  5. StreamProxy 不存在时降级使用 MediaServer 构建 URL

验证命令:

# 连接 Redis 检查配置
redis-cli

# 查看配置 key
KEYS aiot:edge:config:*

# 查看具体配置内容
GET aiot:edge:config:{edge_device_id}

# 检查配置 JSON 中的字段
# 应包含:
# - camera_code: "cam_xxxxxxxxxxxx"
# - camera_id: "app/stream" (向后兼容)
# - rtsp_url: 优先来自 StreamProxy.srcUrl

配置示例:

{
  "cameras": [
    {
      "camera_code": "cam_a1b2c3d4e5f6",
      "camera_id": "cam_a1b2c3d4e5f6/stream_12345",
      "rtsp_url": "rtsp://example.com/test/stream1",
      "rois": [
        {
          "roi_id": "roi_001",
          "coordinates": [...],
          "algorithms": [...]
        }
      ]
    }
  ]
}

3.4 前端展示和交互

测试目的: 验证前端页面正确使用 camera_code

测试用例 3.4.1 - 摄像头管理页面:

测试步骤:

  1. 访问摄像头管理页面
  2. 查看摄像头列表
  3. 新增/编辑摄像头

预期结果:

  1. 列表正确显示 cameraCode 字段
  2. 新增表单隐藏 app 输入框(自动生成)
  3. API 调用使用新的 cameraCode 字段
  4. 数据保存后正确回显

测试用例 3.4.2 - ROI 配置页面:

测试步骤:

  1. 访问 ROI 配置页面
  2. 选择摄像头
  3. 获取截图
  4. 配置 ROI 区域

预期结果:

  1. 摄像头选择器显示 cameraCode 和名称
  2. 截图请求使用 cameraCode 参数
  3. ROI 保存时关联正确的 cameraCode
  4. 配置查询使用 cameraCode 匹配

四、数据一致性测试

4.1 迁移数据验证

测试目的: 确保历史数据正确迁移

验证SQL:

-- 1. 检查所有 camera_code 都已生成
SELECT COUNT(*) AS total,
       COUNT(camera_code) AS has_code
FROM wvp_stream_proxy;
-- total 应等于 has_code

-- 2. 检查 camera_code 格式
SELECT id, camera_code
FROM wvp_stream_proxy
WHERE camera_code NOT REGEXP '^cam_[a-f0-9]{12}$';
-- 应返回空

-- 3. 检查唯一性
SELECT camera_code, COUNT(*) AS cnt
FROM wvp_stream_proxy
GROUP BY camera_code
HAVING cnt > 1;
-- 应返回空

-- 4. 检查 ROI 表关联
SELECT r.roi_id, r.camera_id, r.name
FROM wvp_ai_roi r
LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code
WHERE sp.camera_code IS NULL;
-- 应返回空(所有 ROI 都能找到对应的 camera_code

4.2 新旧数据兼容性

测试场景: 系统同时存在迁移的旧数据和新创建的数据

验证点:

  1. 旧数据的 camera_code 格式正确
  2. 新数据的 camera_code 与旧数据不冲突
  3. ROI 查询同时支持新旧数据
  4. 配置推送对新旧数据处理一致

五、异常测试

5.1 camera_code 重复冲突

测试目的: 验证重试机制

模拟方法:

  • 理论上 UUID 生成的12位哈希极低概率重复
  • 系统已实现最多3次重试机制

预期结果:

  • 第一次冲突时自动重试
  • 3次都冲突则抛出异常
  • 错误日志记录详细信息

5.2 StreamProxy 不存在

测试场景: 使用无效的 cameraCode 调用接口

测试步骤:

  1. 调用截图接口:/api/ai/roi/snap?cameraCode=cam_invalid123
  2. 调用配置推送时 ROI 关联了不存在的 camera_code

预期结果:

  • 截图接口返回 404 Not Found
  • 配置推送时跳过该摄像头或使用降级逻辑
  • 错误日志记录

5.3 数据库迁移失败回滚

测试场景: 迁移脚本执行失败

可能原因:

  • 数据库权限不足
  • 表不存在
  • 字段已存在

验证方法:

-- 检查迁移是否完成
SHOW COLUMNS FROM wvp_stream_proxy LIKE 'camera_code';

-- 如果失败,检查错误日志
SHOW ENGINE INNODB STATUS;

六、性能测试

6.1 camera_code 生成性能

测试方法: 批量创建摄像头

测试步骤:

  1. 使用脚本批量调用新增摄像头接口
  2. 创建 100 个摄像头
  3. 记录平均响应时间

预期结果:

  • 单次生成 camera_code 耗时 < 5ms
  • 数据库唯一索引查询性能正常
  • 重试机制不影响整体性能

6.2 查询性能

测试SQL:

-- 1. 按 camera_code 查询(应使用唯一索引)
EXPLAIN SELECT * FROM wvp_stream_proxy WHERE camera_code = 'cam_a1b2c3d4e5f6';
-- type: const 或 eq_ref

-- 2. ROI 关联查询
EXPLAIN SELECT r.*, sp.name, sp.src_url
FROM wvp_ai_roi r
INNER JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code
WHERE sp.camera_code = 'cam_a1b2c3d4e5f6';
-- 应使用索引

七、集成测试场景

场景1: 完整业务流程

流程步骤:

  1. 新增摄像头(自动生成 camera_code
  2. 创建 ROI 区域(关联 camera_code
  3. 绑定算法模板
  4. 获取截图验证(使用 cameraCode 参数)
  5. 推送配置到 Redis包含 camera_code
  6. Edge 设备消费配置

验证点:

  • 每个步骤数据传递正确
  • camera_code 作为全局唯一标识贯穿全流程
  • 前后端数据一致

场景2: 多摄像头配置

测试步骤:

  1. 创建 5 个摄像头
  2. 为每个摄像头配置 2-3 个 ROI
  3. 绑定不同算法
  4. 批量推送配置

验证点:

  • 所有 camera_code 唯一
  • ROI 正确关联到对应摄像头
  • Redis 配置结构正确
  • 无数据混乱

八、回归测试

8.1 旧功能验证

测试项:

  • 摄像头列表查询
  • 摄像头编辑/删除
  • 流媒体代理功能
  • 国标设备对接
  • 录像管理

预期: 所有旧功能正常工作,不受 camera_code 改造影响

8.2 API 兼容性

验证点:

  • 新接口正确处理 cameraCode
  • 旧接口(如果有)仍可用或有明确废弃提示
  • 响应数据结构兼容

九、测试总结

9.1 测试清单

测试项 优先级 状态 备注
数据库迁移脚本执行 P0 待测 需要MySQL环境
camera_code 自动生成 P0 待测 核心功能
camera_code 唯一性 P0 待测 数据完整性
ROI 截图接口 cameraCode 参数 P0 待测 API改造
配置推送 camera_code 字段 P0 待测 Redis配置
前端摄像头管理页面 P1 待测 UI交互
前端 ROI 配置页面 P1 待测 UI交互
数据一致性验证 P0 待测 迁移验证
异常处理测试 P1 待测 容错机制
性能测试 P2 待测 非阻塞

9.2 风险评估

高风险项:

  1. 数据库迁移失败 → 建议先备份数据库
  2. 历史数据 camera_code 生成冲突 → 已有重试机制
  3. ROI 表 camera_id 更新不完整 → 迁移脚本有验证SQL

缓解措施:

  • 在测试环境先完整执行一遍
  • 准备回滚方案
  • 监控生产环境日志

9.3 建议测试顺序

  1. 第一阶段(核心功能):

    • 数据库迁移
    • camera_code 自动生成
    • 数据一致性验证
  2. 第二阶段(接口改造):

    • ROI 截图接口
    • 配置推送功能
    • API 调用验证
  3. 第三阶段(前端集成):

    • 摄像头管理页面
    • ROI 配置页面
    • 端到端流程测试
  4. 第四阶段(回归测试):

    • 旧功能验证
    • 性能测试
    • 异常场景

9.4 部署前检查项

  • 数据库迁移脚本在测试环境验证通过
  • 所有 P0 测试用例通过
  • 前后端代码已同步部署
  • Redis 配置结构兼容旧版本(向后兼容)
  • 回滚方案准备就绪
  • 监控告警配置完成

十、附录

附录A: 相关代码文件清单

后端文件:

  • StreamProxy.java - 新增 cameraCode 字段
  • StreamProxyMapper.java - 新增 selectByCameraCode 查询
  • StreamProxyProvider.java - SQL 生成逻辑
  • StreamProxyServiceImpl.java - 自动生成和查询实现
  • IStreamProxyService.java - 接口声明
  • AiRoiController.java - snap 接口改造
  • AiRedisConfigServiceImpl.java - 配置推送改造

前端文件:

  • apps/web-antd/src/api/aiot/device/index.ts - API 类型定义
  • apps/web-antd/src/views/aiot/device/camera/index.vue - 摄像头管理页面
  • apps/web-antd/src/views/aiot/device/roi/index.vue - ROI 配置页面
  • apps/web-antd/src/views/aiot/device/roi/components/*.vue - ROI 子组件

数据库文件:

  • 数据库/aiot/迁移-添加camera_code字段.sql - 迁移脚本

附录B: Git 提交记录

450afb811 feat(aiot): 配置推送使用camera_code查询StreamProxy
6d1e1d0bc feat(aiot): snap接口改用cameraCode参数查询StreamProxy
3792a3061 feat(streamProxy): 实现camera_code自动生成和查询逻辑
754677e11 feat(streamProxy): Service接口新增getStreamProxyByCameraCode方法
2b61113ba feat(streamProxy): Provider增加camera_code的SQL处理
2e89c2a62 feat(streamProxy): Mapper新增selectByCameraCode查询方法
b542432dc feat(streamProxy): StreamProxy增加cameraCode字段
0c8037726 fix(aiot): 迁移脚本增加camera_code格式验证
731291217 feat(aiot): 添加camera_code字段迁移脚本
ac345a472 feat(aiot): ROI配置页面改用cameraCode参数和截图调用
4bbc4b16d feat(aiot): 摄像头管理页面改用cameraCode隐藏app输入
2583ed533 feat(aiot): Camera接口增加cameraCode字段,getSnapUrl改用cameraCode

附录C: 测试数据示例

摄像头测试数据:

INSERT INTO wvp_stream_proxy (camera_code, app, stream, name, src_url, timeout, enable)
VALUES
('cam_test1234567', 'cam_test1234567', 'stream_001', '测试摄像头001', 'rtsp://example.com/test1', 30, 1),
('cam_test7654321', 'cam_test7654321', 'stream_002', '测试摄像头002', 'rtsp://example.com/test2', 30, 1);

ROI 测试数据:

INSERT INTO wvp_ai_roi (roi_id, camera_id, name, points)
VALUES
('roi_001', 'cam_test1234567', 'ROI区域1', '[[0,0],[100,0],[100,100],[0,100]]'),
('roi_002', 'cam_test1234567', 'ROI区域2', '[[200,200],[300,200],[300,300],[200,300]]');

文档版本: v1.0 创建时间: 2026-02-13 创建人: AI开发团队 审核状态: 待审核