添加完整的测试报告文档,包括: - 测试概述与环境要求 - 数据库迁移验证步骤 - 功能测试用例(摄像头创建、ROI截图、配置推送) - 数据一致性测试 - 异常测试场景 - 性能测试 - 集成测试场景 - 回归测试 - 测试清单与风险评估 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
14 KiB
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
预期结果:
- ✅
wvp_stream_proxy表新增camera_code字段 - ✅ 现有数据自动生成
camera_code(格式:cam_xxxxxxxxxxxx) - ✅
camera_code字段设置为 NOT NULL 和 UNIQUE 约束 - ✅
wvp_ai_roi表的camera_id字段更新为对应的camera_code - ✅ 验证查询显示无重复、无格式错误
验证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 自动生成逻辑
前置条件:
- 系统正常运行
- 流媒体服务器在线
测试步骤:
- 访问前端摄像头管理页面
- 点击"新增摄像头"按钮
- 填写摄像头信息:
- 名称:测试摄像头001
- 拉流地址:rtsp://example.com/test/stream1
- 超时时间:默认
- 注意:不需要手动填写 app 字段(系统自动生成)
- 提交保存
预期结果:
- ✅ 摄像头创建成功
- ✅ 系统自动生成
camera_code(格式:cam_xxxxxxxxxxxx) - ✅
app字段自动设置为与camera_code相同 - ✅
stream字段为系统生成的唯一标识 - ✅ 数据库
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_codecamera_code在全表唯一
3.2 ROI 截图功能 - cameraCode 参数
测试目的: 验证 ROI 截图接口改用 cameraCode 参数
前置条件:
- 摄像头已创建并在线推流
- 流媒体服务器正常
测试步骤:
- 访问 ROI 配置页面
- 选择已创建的摄像头
- 点击"获取截图"按钮
- 观察网络请求(F12开发者工具)
预期结果:
- ✅ 请求 URL:
/api/ai/roi/snap?cameraCode=cam_xxxxxxxxxxxx - ✅ 使用
cameraCode参数(而非旧的app/stream) - ✅ 后端通过
cameraCode查询StreamProxy对象 - ✅ 获取到正确的
app和stream值 - ✅ 调用 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 设备在线
测试步骤:
- 访问配置管理页面
- 创建或更新 ROI 配置
- 绑定算法模板
- 执行"配置推送"操作
- 检查 Redis 中的配置数据
预期结果:
- ✅ 配置构建时使用
camera_code查询StreamProxy - ✅ 优先使用
StreamProxy.srcUrl作为rtsp_url - ✅ Redis 配置中包含
camera_code字段 - ✅ 保留
camera_id字段向后兼容(值为app/stream) - ✅ 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 - 摄像头管理页面:
测试步骤:
- 访问摄像头管理页面
- 查看摄像头列表
- 新增/编辑摄像头
预期结果:
- ✅ 列表正确显示
cameraCode字段 - ✅ 新增表单隐藏
app输入框(自动生成) - ✅ API 调用使用新的
cameraCode字段 - ✅ 数据保存后正确回显
测试用例 3.4.2 - ROI 配置页面:
测试步骤:
- 访问 ROI 配置页面
- 选择摄像头
- 获取截图
- 配置 ROI 区域
预期结果:
- ✅ 摄像头选择器显示
cameraCode和名称 - ✅ 截图请求使用
cameraCode参数 - ✅ ROI 保存时关联正确的
cameraCode - ✅ 配置查询使用
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 新旧数据兼容性
测试场景: 系统同时存在迁移的旧数据和新创建的数据
验证点:
- ✅ 旧数据的
camera_code格式正确 - ✅ 新数据的
camera_code与旧数据不冲突 - ✅ ROI 查询同时支持新旧数据
- ✅ 配置推送对新旧数据处理一致
五、异常测试
5.1 camera_code 重复冲突
测试目的: 验证重试机制
模拟方法:
- 理论上 UUID 生成的12位哈希极低概率重复
- 系统已实现最多3次重试机制
预期结果:
- ✅ 第一次冲突时自动重试
- ✅ 3次都冲突则抛出异常
- ✅ 错误日志记录详细信息
5.2 StreamProxy 不存在
测试场景: 使用无效的 cameraCode 调用接口
测试步骤:
- 调用截图接口:
/api/ai/roi/snap?cameraCode=cam_invalid123 - 调用配置推送时 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 生成性能
测试方法: 批量创建摄像头
测试步骤:
- 使用脚本批量调用新增摄像头接口
- 创建 100 个摄像头
- 记录平均响应时间
预期结果:
- ✅ 单次生成 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: 完整业务流程
流程步骤:
- 新增摄像头(自动生成 camera_code)
- 创建 ROI 区域(关联 camera_code)
- 绑定算法模板
- 获取截图验证(使用 cameraCode 参数)
- 推送配置到 Redis(包含 camera_code)
- Edge 设备消费配置
验证点:
- ✅ 每个步骤数据传递正确
- ✅ camera_code 作为全局唯一标识贯穿全流程
- ✅ 前后端数据一致
场景2: 多摄像头配置
测试步骤:
- 创建 5 个摄像头
- 为每个摄像头配置 2-3 个 ROI
- 绑定不同算法
- 批量推送配置
验证点:
- ✅ 所有 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 风险评估
高风险项:
- 数据库迁移失败 → 建议先备份数据库
- 历史数据 camera_code 生成冲突 → 已有重试机制
- ROI 表 camera_id 更新不完整 → 迁移脚本有验证SQL
缓解措施:
- 在测试环境先完整执行一遍
- 准备回滚方案
- 监控生产环境日志
9.3 建议测试顺序
-
第一阶段(核心功能):
- 数据库迁移
- camera_code 自动生成
- 数据一致性验证
-
第二阶段(接口改造):
- ROI 截图接口
- 配置推送功能
- API 调用验证
-
第三阶段(前端集成):
- 摄像头管理页面
- ROI 配置页面
- 端到端流程测试
-
第四阶段(回归测试):
- 旧功能验证
- 性能测试
- 异常场景
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开发团队 审核状态: 待审核