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

547 lines
14 KiB
Markdown
Raw 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.

# 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`
**执行步骤**:
```bash
# 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**:
```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**:
```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. ✅ 获取到正确的 `app``stream`
5. ✅ 调用 ZLM 截图接口成功,返回图片数据
**验证方法**:
```javascript
// 浏览器控制台查看请求
// 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
**验证命令**:
```bash
# 连接 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
```
**配置示例**:
```json
{
"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**:
```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 数据库迁移失败回滚
**测试场景**: 迁移脚本执行失败
**可能原因**:
- 数据库权限不足
- 表不存在
- 字段已存在
**验证方法**:
```sql
-- 检查迁移是否完成
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**:
```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: 测试数据示例
**摄像头测试数据**:
```sql
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 测试数据**:
```sql
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开发团队
**审核状态**: 待审核