# 畜牧监控 — 测试用例

> 依据：`畜牧监控功能需求.md`（v1.1）、`畜牧监控技术方案.md`（v1.0）  
> **接口 Base Path**：`/videoSurveillance/livestockMonitor`；鉴权与若依一致（Cookie / Token）。

**通用前置（无特殊说明）**：具备本模块权限的账号已登录（`videoSurveillance:livestockMonitor:list|query|add|edit|remove`）。主数据宜预置：

| 样本 | 类型 | 名称 | 状态 | 用途 |
| --- | --- | --- | --- | --- |
| **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`）：

| 样本 | 监控名称 | 所属主体 | 安装位置 | IP | 要点 |
| --- | --- | --- | --- | --- | --- |
| **C1** | 圈舍监控1 | P1 | 1号圈舍 | 192.168.1.101 | 列表/改删主样本 |
| **C2** | 东门监控 | M1 | 东门入口 | 192.168.2.10 | 交易市场主体 |
| **C3** | 圈舍监控1 | P1 | 2号圈舍 | 192.168.1.101 | 与 C1 **同名同 IP**（唯一性不校验） |

**合法新增 Body 示例**：`monitorName=测试监控`，`ownerType=1`，`ownerId={P1.id}`，`installLocation=1号栏`，`ipAddress=192.168.0.88`。

**界面（UI）测试**：**Playwright** + **Chromium**（`channel: 'chrome'` 使用本机 **Google Chrome**）。

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-XMJK-UT-001 | 参数校验 | 监控名称 | 单元测试 | JUnit5 | §3.7 | 无 | 空、纯空白、11 字、10 字 trim | 空/空白/超长失败；合法通过 |
| ZCZX-XMJK-UT-002 | 参数校验 | 安装位置 | 单元测试 | JUnit5 | §3.7 | 无 | 空、11 字、10 字 | 空/超长失败；通过 |
| ZCZX-XMJK-UT-003 | 参数校验 | IPv4 | 单元测试 | JUnit5 | §3.7、需求 §5.2 | 无 | `256.1.1.1`、`abc`、`192.168.1.1`、21 字符 | 非法/超长失败；合法通过 |
| ZCZX-XMJK-UT-004 | 参数校验 | 主体类型 | 单元测试 | JUnit5 | §2.3 | 无 | `ownerType=0/3`；`1/2` | 非法失败；1/2 进入后续校验 |
| ZCZX-XMJK-UT-005 | 主体校验 | 养殖主体正常 | 单元测试 | JUnit5+Mockito | §2.4 | Mock P1 存在且正常 | `validateOwner(1,P1.id)` | 通过；可解析 `ownerName` |
| ZCZX-XMJK-UT-006 | 主体校验 | 牧场停业 | 单元测试 | JUnit5+Mockito | 需求 §2.2 | Mock P2 | `validateOwner(1,P2.id)` | 失败；主体不存在或已停用 |
| ZCZX-XMJK-UT-007 | 主体校验 | 市场正常 | 单元测试 | JUnit5+Mockito | §2.4 | Mock M1 | `validateOwner(2,M1.id)` | 通过 |
| ZCZX-XMJK-UT-008 | 主体校验 | 市场注销 | 单元测试 | JUnit5+Mockito | §2.4 | Mock M2 | `validateOwner(2,M2.id)` | 失败 |
| ZCZX-XMJK-UT-009 | 唯一性 | 名称/IP 可重复 | 单元测试 | JUnit5+Mockito | 需求 §5.2 | 库已有 C1 | 再 `validateRowForSave` 同名同 IP | 通过（不抛唯一性异常） |
| ZCZX-XMJK-UT-010 | Service | 新增冗余主体名 | 单元测试 | JUnit5+Mockito | §2.4 | Mock 主数据 | `insert` 合法行 | `owner_name` 与主数据名称一致 |
| ZCZX-XMJK-UT-011 | Service | 逻辑删除 | 单元测试 | JUnit5+Mockito | §3.5 | Mock Mapper | `remove(id)` | `del_flag=2` |
| ZCZX-XMJK-UT-012 | Service | 已删不可改 | 单元测试 | JUnit5+Mockito | 需求 §5.3 | `del_flag=2` | `update` | 失败 |
| ZCZX-XMJK-UT-013 | ownerOptions | 仅正常主体 | 单元测试 | JUnit5+Mockito | §3.6 | 库含 P1/P2/M1/M2 | `listOwnerOptions(null)` | 仅含 P1、M1；不含停业/注销 |
| ZCZX-XMJK-UT-014 | ownerOptions | 关键字模糊 | 单元测试 | JUnit5+Mockito | §3.6 | 有 P1「巴青」 | `keyword=巴青` | 含 P1；不含无关主体 |
| ZCZX-XMJK-UT-015 | Mapper | 名称模糊 SQL | 单元测试 | JUnit5 | §3.8 | 审阅 XML | `monitor_name LIKE CONCAT` |
| ZCZX-XMJK-UT-016 | Mapper | 主体精确 SQL | 单元测试 | JUnit5 | §3.8 | 审阅 XML | `owner_type` AND `owner_id` 成对 |
| ZCZX-XMJK-UT-017 | Mapper | 列表范围 | 单元测试 | JUnit5 | §3.8 | 审阅 XML | `del_flag='0'`；`create_time DESC, id DESC` |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 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 | 列表 | 列表无 IP 字段 | 接口测试 | Postman | 需求 §5.1 | 有 C1 | `GET /list` 看 `rows[0]` | 行对象无 `ipAddress` 或前端不使用（以实现为准） |
| 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 | 新增 | 同名同 IP 允许 | 接口测试 | Postman | 需求 §5.2 | 已有 C1 | `POST` 与 C1 同名同 IP | `code=200`（第二条） |
| ZCZX-XMJK-API-012 | 新增 | 缺监控名称 | 接口测试 | Postman | §5.2 | 已登录 | 缺 `monitorName` | 失败 |
| ZCZX-XMJK-API-013 | 新增 | 名称超长 | 接口测试 | Postman | §5.2 | 已登录 | `monitorName` 11 字 | 失败 |
| ZCZX-XMJK-API-014 | 新增 | IP 非法 | 接口测试 | Postman | §5.2 | 已登录 | `ipAddress=999.1.1.1` | 失败；msg 含 IP |
| 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 含 IP | 接口测试 | Postman | §5.4 | 有 C1 | `GET /{id}` | 含 `ipAddress`、主体类型名称 |
| ZCZX-XMJK-API-018 | 详情 | 已删/不存在 | 接口测试 | Postman | §8 | 已登录 | 已删或 999999 | 失败；记录不存在或已删除 |
| ZCZX-XMJK-API-019 | 修改 | 改安装位置与 IP | 接口测试 | Postman | §5.3 | 有 C1 | `PUT` 改 `installLocation`、`ipAddress` | 成功；详情已更新 |
| 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 | 响应 | 失败可读 | 接口测试 | Postman | §8 | 已登录 | 触发缺名称、IP 错、停业主体 | `msg` 可区分场景 |

---

## 三、界面测试用例（UI）

**测试工具**：**Playwright** + **Chromium**（`channel: 'chrome'` 使用本机 **Google Chrome**）。

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-XMJK-UI-001 | 列表 | 默认展示 | UI 测试 | Playwright+Chrome | §5.1、原型 | 已登录；有 C1 | 进入「畜牧监控」 | 列：监控名称、所属主体、安装位置、操作；**无 IP 列** |
| 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 | 新增 | 必填与 IP 字段 | UI 测试 | Playwright+Chrome | §5.2 | 有 add | 新增→选 P1→填名称/位置/IP→确定 | 成功；列表见新行 |
| ZCZX-XMJK-UI-007 | 新增 | 主体下拉模糊 | UI 测试 | Playwright+Chrome | §2.2 | 有 P1 | 所属主体输入「巴青」 | 可选 P1；显示类型标签 |
| ZCZX-XMJK-UI-008 | 新增 | 缺必填校验 | UI 测试 | Playwright+Chrome | §5.2 | 新增弹窗 | 不选主体或空名称→确定 | 校验失败；弹窗不关闭 |
| ZCZX-XMJK-UI-009 | 新增 | IP 非法 | UI 测试 | Playwright+Chrome | §5.2 | 新增 | IP 填 `abc`→确定 | 提示 IP 格式错误 |
| ZCZX-XMJK-UI-010 | 新增 | 名称超 10 字 | UI 测试 | Playwright+Chrome | §5.2 | 新增 | 名称输入超 10 字 | `maxlength` 或保存失败 |
| ZCZX-XMJK-UI-011 | 新增 | 取消 | UI 测试 | Playwright+Chrome | §5.2 | 新增 | 填一半→取消 | 无新行 |
| ZCZX-XMJK-UI-012 | 查看 | 详情含 IP | UI 测试 | Playwright+Chrome | §5.4 | 有 C1 | 点击**查看** | 只读；含 IP、主体类型；无编辑控件或只读 |
| ZCZX-XMJK-UI-013 | 编辑 | 修改字段 | UI 测试 | Playwright+Chrome | §5.3 | 有 C1 | 编辑→改安装位置→保存 | 列表/详情已更新 |
| ZCZX-XMJK-UI-014 | 编辑 | 更换主体 | UI 测试 | Playwright+Chrome | §5.3 | 有 C1 | 编辑→改选 M1→保存 | 所属主体显示为 M1 |
| ZCZX-XMJK-UI-015 | 删除 | 确认删除 | UI 测试 | Playwright+Chrome | §5.5 | 无依赖新行 | 删除→确认 | 行消失 |
| ZCZX-XMJK-UI-016 | 删除 | 取消删除 | UI 测试 | Playwright+Chrome | §5.5 | 任意行 | 删除→取消 | 行仍在 |
| ZCZX-XMJK-UI-017 | 实时监控 | 点击提示 | UI 测试 | Playwright+Chrome | §5.6 v1.1 | 有 C1 | 点击**查看实时监控** | 弹出「实时监控功能暂未开放…」；无播放页 |
| 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()`；填名称、选主体、安装位置、IP；`确定`。  
- 实时监控：`page.getByRole('button', { name: '查看实时监控' }).first().click()`；`expect(page.getByText('实时监控功能暂未开放')).toBeVisible()`。

---

## 覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常 CRUD | UT-010 | API-009～010、017、019～020、025 | UI-006、012～014、019 |
| 列表筛选 | UT-015～017 | API-001～004 | UI-002～005 |
| 主体约束 | UT-005～008、013～014 | API-007～008、015～016 | UI-007、020 |
| 字段校验 | UT-001～004 | API-012～014 | UI-008～010 |
| 唯一性不校验 | UT-009 | API-011 | — |
| 逻辑删除 | UT-011～012 | API-005、022～024 | UI-015～016 |
| 实时监控占位 | — | — | UI-017 |
| 鉴权权限 | — | API-026～028 | UI-018 |
| ownerOptions | UT-013～014 | API-007～008 | UI-007 |
| 列表无 IP | — | API-006 | UI-001、012 |

---

## 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初稿：对齐功能需求 v1.1、技术方案 v1.0；UT/API/UI 共 66 条；Playwright+Chrome |
