# 畜牧监控 — 测试用例 > 依据:`畜牧监控功能需求.md`(v1.3)、`畜牧监控技术方案.md`(v1.3) > **接口 Base Path**:`/videoSurveillance/livestockMonitor`;鉴权与若依一致(Cookie / Token)。 **通用前置(无特殊说明)**:具备本模块权限的账号已登录(`videoSurveillance:livestockMonitor:list|query|add|edit|remove|sync`)。主数据宜预置: | 样本 | 类型 | 名称 | 状态 | 用途 | | --- | --- | --- | --- | --- | | **P1** | 养殖主体 `owner_type=1` | 巴青牧场 | `biz_pasture` 正常、`del_flag=0` | 关联监控 C1 | | **P2** | 养殖主体 | 停业牧场 | `biz_status=2` | 不可选/保存失败 | | **M1** | 交易市场 `owner_type=2` | 巴青县交易市场 | `operate_status=1` | 关联监控 C2 | | **M2** | 交易市场 | 注销市场 | `operate_status=3` | 不可选/保存失败 | `biz_livestock_monitor`(`del_flag=0`): | 样本 | 监控名称 | monitor_id | 所属主体 | 圈舍 | 视频来源 | 要点 | | --- | --- | --- | --- | --- | --- | --- | | **C1** | 圈舍监控1 | 50001 | P1 | 1号圈舍 | wvp | 列表/改删/实时预览主样本 | | **C2** | 东门监控 | 50002 | M1 | 东门 | ys7 | 交易市场主体 | | **C3** | 圈舍监控1 | 50003 | P1 | 2号圈舍 | wvp | 与 C1 **同名**(唯一性不校验) | **合法新增 Body 示例**:`monitorId=50099`,`monitorName=测试监控`,`videoSource=wvp`,`ownerType=1`,`ownerId={P1.id}`,`enclosureName=1号栏`,`installLocation=1号栏`。 **第三方 stub**:`thirdparty/stub-cameras.json`(同步);`stub-camera-play-urls.json`(`/playUrl` 实时预览);配置 `third-party.farming.mode=stub`。 **界面(UI)测试**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。 --- ## 一、单元测试用例 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ZCZX-XMJK-UT-001 | 参数校验 | 监控名称 | 单元测试 | JUnit5 | §3.9 | 无 | 空、纯空白、11 字、10 字 trim | 空/空白/超长失败;合法通过 | | ZCZX-XMJK-UT-002 | 参数校验 | 安装位置 | 单元测试 | JUnit5 | §3.9 | 无 | 空、11 字、10 字 | 可选;超长失败;合法通过 | | ZCZX-XMJK-UT-003 | 参数校验 | 视频来源 | 单元测试 | JUnit5 | §3.9 | 无 | 空、非法值、wvp/ys7/url | 非法失败;合法通过 | | ZCZX-XMJK-UT-004 | 参数校验 | 摄像头 ID | 单元测试 | JUnit5 | §3.9 | 无 | 空、33 字、合法 | 空/超长失败;通过 | | ZCZX-XMJK-UT-005 | 参数校验 | 主体类型 | 单元测试 | JUnit5 | §2.2 | 无 | `ownerType=0/3`;`1/2` | 非法失败;1/2 进入后续校验 | | ZCZX-XMJK-UT-006 | 主体校验 | 养殖主体正常 | 单元测试 | JUnit5+Mockito | §2.3 | Mock P1 存在且正常 | `validateOwner(1,P1.id)` | 通过;可解析 `ownerName` | | ZCZX-XMJK-UT-007 | 主体校验 | 牧场停业 | 单元测试 | JUnit5+Mockito | 需求 §2.2 | Mock P2 | `validateOwner(1,P2.id)` | 失败;主体不存在或已停用 | | ZCZX-XMJK-UT-008 | 主体校验 | 市场正常 | 单元测试 | JUnit5+Mockito | §2.3 | Mock M1 | `validateOwner(2,M1.id)` | 通过 | | ZCZX-XMJK-UT-009 | 主体校验 | 市场注销 | 单元测试 | JUnit5+Mockito | §2.3 | Mock M2 | `validateOwner(2,M2.id)` | 失败 | | ZCZX-XMJK-UT-010 | 唯一性 | 名称可重复 | 单元测试 | JUnit5+Mockito | 需求 | 库已有 C1 | 再 `validateRowForSave` 同名 | 通过 | | ZCZX-XMJK-UT-011 | Service | 新增冗余主体名 | 单元测试 | JUnit5+Mockito | §2.3 | Mock 主数据 | `insert` 合法行 | `owner_name` 与主数据名称一致 | | ZCZX-XMJK-UT-012 | Service | 逻辑删除 | 单元测试 | JUnit5+Mockito | §3.5 | Mock Mapper | `remove(id)` | `del_flag=2` | | ZCZX-XMJK-UT-013 | Service | 已删不可改 | 单元测试 | JUnit5+Mockito | 需求 §5.3 | `del_flag=2` | `update` | 失败 | | ZCZX-XMJK-UT-014 | ownerOptions | 仅正常主体 | 单元测试 | JUnit5+Mockito | §3.6 | 库含 P1/P2/M1/M2 | `listOwnerOptions(null)` | 仅含 P1、M1 | | ZCZX-XMJK-UT-015 | ownerOptions | 关键字模糊 | 单元测试 | JUnit5+Mockito | §3.6 | 有 P1「巴青」 | `keyword=巴青` | 含 P1 | | ZCZX-XMJK-UT-016 | Mapper | 名称模糊 SQL | 单元测试 | JUnit5 | §3.9 | 审阅 XML | `monitor_name LIKE CONCAT` | | ZCZX-XMJK-UT-017 | Mapper | 主体精确 SQL | 单元测试 | JUnit5 | §3.9 | 审阅 XML | `owner_type` AND `owner_id` 成对 | | ZCZX-XMJK-UT-018 | Mapper | 列表范围 | 单元测试 | JUnit5 | §3.9 | 审阅 XML | `del_flag='0'`;含 `monitor_id`;**无** `video_url` | | ZCZX-XMJK-UT-019 | 第三方同步 | 空列表 | 单元测试 | JUnit5+Mockito | §3.7 | stub 空 | `syncFromThirdParty` | insert/update=0 | | ZCZX-XMJK-UT-020 | 第三方同步 | 新增与更新 | 单元测试 | JUnit5+Mockito | §3.7 | 2 条摄像头 | `sync` | insert=1, update=1 | | ZCZX-XMJK-UT-021 | 第三方同步 | 并发拒绝 | 单元测试 | JUnit5+Mockito | §3.7 | 同步进行中 | 再次 `sync` | 「正在同步,请稍候」 | | ZCZX-XMJK-UT-022 | 第三方同步 | 单条落库失败 | 单元测试 | JUnit5+Mockito | §3.7 | persist 抛错 | `sync` | failCount+1 | | ZCZX-XMJK-UT-023 | 播放地址 | 按 monitorId 成功 | 单元测试 | JUnit5+Mockito | §3.8 | C1 存在;Mock play-url | `getPlayUrlByMonitorId('50001')` | 返回 `videoUrl` | | ZCZX-XMJK-UT-024 | 播放地址 | 点位不存在 | 单元测试 | JUnit5+Mockito | §3.8 | 无记录 | `getPlayUrlByMonitorId('99999')` | 失败 | | ZCZX-XMJK-UT-025 | 播放地址 | 已删不可预览 | 单元测试 | JUnit5+Mockito | §3.8 | `del_flag=2` | `getPlayUrlByMonitorId` | 失败 | --- ## 二、接口测试用例 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ZCZX-XMJK-API-001 | 列表 | 默认分页排序 | 接口测试 | Postman | §3.1 | 有 C1~C3 | `GET /list` | `code=200`;含 `ownerTypeName`;时间倒序 | | ZCZX-XMJK-API-002 | 列表 | 名称模糊 | 接口测试 | Postman | §5.1 | 有 C1 | `monitorName=圈舍` | 含 C1、C3 | | ZCZX-XMJK-API-003 | 列表 | 主体精确 | 接口测试 | Postman | §5.1 | 有 C2 | `ownerType=2&ownerId={M1.id}` | 仅含 C2 | | ZCZX-XMJK-API-004 | 列表 | 组合筛选 | 接口测试 | Postman | §5.1 | 有 C1 | `monitorName=圈舍`+P1 主体参数 | 含 C1、C3 | | ZCZX-XMJK-API-005 | 列表 | 不含已删除 | 接口测试 | Postman | §5.5 | 某 id 已删 | `GET /list` | 无该 id | | ZCZX-XMJK-API-006 | 列表 | 含监控字段 | 接口测试 | Postman | §3.1 | 有 C1 | `GET /list` | 行含 `monitorId`、`videoSource`;**无** `videoUrl` | | ZCZX-XMJK-API-007 | ownerOptions | 全量选项 | 接口测试 | Postman | §3.6 | 有 P1/M1 | `GET /ownerOptions` | `code=200`;项含 `ownerType/ownerId/ownerName` | | ZCZX-XMJK-API-008 | ownerOptions | 关键字 | 接口测试 | Postman | §3.6 | 有 P1 | `keyword=巴青` | 含 P1 | | ZCZX-XMJK-API-009 | 新增 | 养殖主体监控 | 接口测试 | Postman | §5.2 | 已登录 | `POST` 合法 Body 绑 P1 | `code=200`;`ownerName` 与 P1 一致 | | ZCZX-XMJK-API-010 | 新增 | 交易市场监控 | 接口测试 | Postman | §5.2 | 已登录 | `POST` `ownerType=2`+M1 | 成功 | | ZCZX-XMJK-API-011 | 新增 | 同名允许 | 接口测试 | Postman | 需求 | 已有 C1 | `POST` 与 C1 同名 | `code=200`(第二条) | | ZCZX-XMJK-API-012 | 新增 | 缺监控名称 | 接口测试 | Postman | §5.2 | 已登录 | 缺 `monitorName` | 失败 | | ZCZX-XMJK-API-013 | 新增 | 名称超长 | 接口测试 | Postman | §5.2 | 已登录 | `monitorName` 11 字 | 失败 | | ZCZX-XMJK-API-014 | 新增 | 视频来源非法 | 接口测试 | Postman | §3.9 | 已登录 | `videoSource=invalid` | 失败 | | ZCZX-XMJK-API-015 | 新增 | 停业牧场主体 | 接口测试 | Postman | §2.2 | 已登录 | `ownerType=1`+P2.id | 失败 | | ZCZX-XMJK-API-016 | 新增 | 注销市场主体 | 接口测试 | Postman | §2.2 | 已登录 | `ownerType=2`+M2.id | 失败 | | ZCZX-XMJK-API-017 | 详情 | 有效 id | 接口测试 | Postman | §3.2 | 有 C1 | `GET /{id}` | 含 `monitorId`、主体类型名称;**无** `videoUrl` | | ZCZX-XMJK-API-018 | 详情 | 已删/不存在 | 接口测试 | Postman | §8 | 已登录 | 已删或 999999 | 失败;记录不存在或已删除 | | ZCZX-XMJK-API-019 | 修改 | 改圈舍 | 接口测试 | Postman | §3.4 | 有 C1 | `PUT` 改 `enclosureName` | 成功 | | ZCZX-XMJK-API-020 | 修改 | 更换主体 | 接口测试 | Postman | §5.3 | 有 C1 | `PUT` 改绑 M1(type=2) | 成功;`ownerName` 更新为市场名 | | ZCZX-XMJK-API-021 | 修改 | 已删记录 | 接口测试 | Postman | §5.3 | C1 已删 | `PUT` | 失败 | | ZCZX-XMJK-API-022 | 删除 | 单条逻辑删 | 接口测试 | Postman | §5.5 | 新建行无依赖 | `DELETE /{id}` | 成功;`list` 不可见 | | ZCZX-XMJK-API-023 | 删除 | 批量删除 | 接口测试 | Postman | §3.5 | 两条新行 | `DELETE /id1,id2` | 均不可见 | | ZCZX-XMJK-API-024 | 删除 | 重复删除 | 接口测试 | Postman | 幂等 | 已删 id | 再次 `DELETE` | 失败或 0 条 | | ZCZX-XMJK-API-025 | 端到端 | CRUD 串联 | 接口测试 | Postman | §4 | 已登录 | `POST`→`list`→`GET`→`PUT`→`DELETE` | 关键步 `code=200` | | ZCZX-XMJK-API-026 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET /list` | 401 或统一未登录 | | ZCZX-XMJK-API-027 | 权限 | 无新增 | 接口测试 | Postman | §6 | 仅 list | `POST` | 无权限失败 | | ZCZX-XMJK-API-028 | 权限 | 无删除 | 接口测试 | Postman | §6 | 无 remove | `DELETE` | 无权限失败 | | ZCZX-XMJK-API-029 | 同步 | stub 全量同步 | 接口测试 | Postman | §3.7 | `mode=stub` | `POST /sync` | `insertCount`+`updateCount`≥0;**不**写 `video_url` | | ZCZX-XMJK-API-030 | 同步 | 并发拒绝 | 接口测试 | Postman | §3.7 | 同步进行中 | 再次 `POST /sync` | 失败;正在同步 | | ZCZX-XMJK-API-031 | 同步 | 无 sync 权限 | 接口测试 | Postman | §4 | 无 sync | `POST /sync` | 无权限失败 | | ZCZX-XMJK-API-032 | playUrl | stub 成功 | 接口测试 | Postman | §3.8 | C1;`mode=stub` | `GET /playUrl?monitorId=50001` | `videoUrl` 非空 | | ZCZX-XMJK-API-033 | playUrl | 无 monitorId | 接口测试 | Postman | §3.8 | 已登录 | 缺参数 | 失败 | | ZCZX-XMJK-API-034 | playUrl | 未登记摄像头 | 接口测试 | Postman | §3.8 | 已登录 | `monitorId=99999` | 监控点位不存在 | | ZCZX-XMJK-API-035 | playUrl | 无 query 权限 | 接口测试 | Postman | §4 | 无 query | `GET /playUrl` | 无权限失败 | | ZCZX-XMJK-API-036 | 响应 | 失败可读 | 接口测试 | Postman | §8 | 已登录 | 触发缺名称、非法 videoSource | `msg` 可区分场景 | --- ## 三、界面测试用例(UI) **测试工具**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ZCZX-XMJK-UI-001 | 列表 | 默认展示 | UI 测试 | Playwright+Chrome | §5.1、原型 | 已登录;有 C1 | 进入「畜牧监控」 | 列:监控名称、所属主体、安装位置、操作 | | ZCZX-XMJK-UI-002 | 列表 | 名称模糊搜索 | UI 测试 | Playwright+Chrome | §5.1 | 有 C1 | 监控名称填「圈舍」→**搜索** | 含 C1、C3 | | ZCZX-XMJK-UI-003 | 列表 | 主体筛选 | UI 测试 | Playwright+Chrome | §5.1 | 有 C2 | 所属主体选 M1→搜索 | 仅 C2 | | ZCZX-XMJK-UI-004 | 列表 | 重置 | UI 测试 | Playwright+Chrome | §5.1 | 已筛选 | 搜索→**重置** | 条件清空;列表恢复 | | ZCZX-XMJK-UI-005 | 列表 | 未点搜索不筛 | UI 测试 | Playwright+Chrome | 平台惯例 | 有数据 | 仅改名称不点搜索 | 列表不变 | | ZCZX-XMJK-UI-006 | 同步 | stub 同步 | UI 测试 | Playwright+Chrome | §3.3 | 有 sync | 点击**同步** | 成功提示;列表出现 stub 数据 | | ZCZX-XMJK-UI-007 | 新增 | 主体下拉模糊 | UI 测试 | Playwright+Chrome | §2.2 | 有 P1 | 所属主体输入「巴青」 | 可选 P1;显示类型标签 | | ZCZX-XMJK-UI-008 | 新增 | 缺必填校验 | UI 测试 | Playwright+Chrome | §5.2 | 新增弹窗 | 空名称或未选 videoSource→确定 | 校验失败;弹窗不关闭 | | ZCZX-XMJK-UI-009 | 新增 | 名称超 10 字 | UI 测试 | Playwright+Chrome | §5.2 | 新增 | 名称输入超 10 字 | `maxlength` 或保存失败 | | ZCZX-XMJK-UI-010 | 新增 | 取消 | UI 测试 | Playwright+Chrome | §5.2 | 新增 | 填一半→取消 | 无新行 | | ZCZX-XMJK-UI-011 | 查看 | 详情只读 | UI 测试 | Playwright+Chrome | §5.4 | 有 C1 | 点击**查看** | 只读;含主体类型、`monitorId` | | ZCZX-XMJK-UI-012 | 编辑 | 修改字段 | UI 测试 | Playwright+Chrome | §5.3 | 有 C1 | 编辑→改安装位置→保存 | 列表/详情已更新 | | ZCZX-XMJK-UI-013 | 编辑 | 更换主体 | UI 测试 | Playwright+Chrome | §5.3 | 有 C1 | 编辑→改选 M1→保存 | 所属主体显示为 M1 | | ZCZX-XMJK-UI-014 | 删除 | 确认删除 | UI 测试 | Playwright+Chrome | §5.5 | 无依赖新行 | 删除→确认 | 行消失 | | ZCZX-XMJK-UI-015 | 删除 | 取消删除 | UI 测试 | Playwright+Chrome | §5.5 | 任意行 | 删除→取消 | 行仍在 | | ZCZX-XMJK-UI-016 | 实时监控 | stub 播放 | UI 测试 | Playwright+Chrome | §5.6 | 有 C1;stub | 点击**查看实时监控** | 弹窗打开;LivePlayer 有地址 | | ZCZX-XMJK-UI-017 | 实时监控 | 无 monitorId | UI 测试 | Playwright+Chrome | §5.6 | 行缺 monitorId | 点击**查看实时监控** | 提示缺少摄像头 ID | | ZCZX-XMJK-UI-018 | 权限 | 只读角色 | UI 测试 | Playwright+Chrome | §6 | 仅 list/query | 进入模块 | 无新增/编辑/删除/同步按钮 | | ZCZX-XMJK-UI-019 | 端到端 | 全流程 | UI 集成 | Playwright+Chrome | §4 | 权限齐备 | 同步→搜索→实时预览→编辑→删 | 无报错 | | ZCZX-XMJK-UI-020 | 主体 | 停业不可选 | UI 测试 | Playwright+Chrome | §2.2 | 有 P2 停业 | 新增→主体下拉搜 P2 | 无选项或不可选 | --- ## Playwright 与谷歌浏览器(实施提示) - 安装:`npm i -D @playwright/test`;`npx playwright install chrome`。 - 配置:`use: { channel: 'chrome', locale: 'zh-CN', baseURL: 'http://localhost:80' }`;`storageState` 复用登录态。 - 路由:`page.goto('/videoSurveillance/livestockMonitor')`(以菜单 `component` 为准)。 - 筛选:`page.getByPlaceholder('请输入监控名称').fill('圈舍')`;所属主体用 `el-select` + 远程搜索。 - 同步:`page.getByRole('button', { name: '同步' }).click()`;`expect(page.getByText('同步完成')).toBeVisible()`。 - 新增:`page.getByRole('button', { name: '新增' }).click()`;填 `monitorId`、名称、视频来源等;`确定`。 - 实时监控:`page.getByRole('button', { name: '查看实时监控' }).first().click()`;`expect(page.locator('.live-player-wrap')).toBeVisible()`。 --- ## 覆盖对照 | 类别 | 单元 UT | 接口 API | 界面 UI | | --- | --- | --- | --- | | 正常 CRUD | UT-011 | API-009~010、017、019~020、025 | UI-011~013、019 | | 列表筛选 | UT-016~018 | API-001~004 | UI-002~005 | | 主体约束 | UT-006~009、014~015 | API-007~008、015~016 | UI-007、020 | | 字段校验 | UT-001~005 | API-012~014 | UI-008~009 | | 唯一性不校验 | UT-010 | API-011 | — | | 逻辑删除 | UT-012~013 | API-005、022~024 | UI-014~015 | | 第三方同步 | UT-019~022 | API-029~031 | UI-006 | | 实时播放 | UT-023~025 | API-032~035 | UI-016~017 | | 鉴权权限 | — | API-026~028、031、035 | UI-018 | | ownerOptions | UT-014~015 | API-007~008 | UI-007 | | 监控字段 | UT-003~004 | API-006 | UI-001 | --- ## 修订记录 | 版本 | 说明 | | --- | --- | | 1.0 | 初稿:对齐功能需求 v1.1、技术方案 v1.0;UT/API/UI;Playwright+Chrome | | 1.1 | 对齐 v1.2 实现:新字段、移除 IP;增加第三方同步 UT/API/UI 用例 | | 1.2 | 对齐 v1.3:移除 `video_url` 与同步阶段二;新增 `/playUrl` UT/API/UI;实时预览 LivePlayer |