# 草畜平衡计算 — 测试用例

> 依据：`草畜平衡计算功能需求.md`、`草蓄平衡计算技术方案.md`  
> **接口 Base Path（示例）**：`/dataModel/grassLivestockBalance`；草场主数据 `/dataModel/grassland`。鉴权与若依一致（Cookie / Token）。

**通用前置（无特殊说明）**：已登录且具备 `dataModel:grassLivestockBalance:query`；草场下拉另需 `dataModel:grassland:list`、`dataModel:grassland:query`。库中存在有效草场（`biz_grassland`，`del_flag=0`），示例：**示范草场** `id=1`，面积 `100` 亩、亩产草量 `350` kg/亩、利用率 `0.65`。

**标准测算样本（用于核对公式）**：`areaMu=100`，`grassYieldPerMu=350`，`utilizationRate=0.65` → 可利用饲草量 `22750` kg；`sheepUnitAnnualForageKg=160` → 理论载畜量 `142.19` SU（保留 2 位）；`breedingHeadCount=100`，`sheepUnitConvertCoeff=4` → 实际载畜量 `400` SU；平衡指数约 `2.81`；超载率约 `181.41%`；等级 **严重超载（4）**。

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

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-CXPH-UT-001 | 公式计算 | 可利用饲草量 | 单元测试 | JUnit5 | 公式 1 | 无 | `calc(100,350,0.65)` | `22750.00` kg |
| ZCZX-CXPH-UT-002 | 公式计算 | 理论/实际载畜量 | 单元测试 | JUnit5 | 公式 2、3 | 样本入参 | 理论、实际 SU | `142.19`、`400.00` SU（2 位小数） |
| ZCZX-CXPH-UT-003 | 公式计算 | 指数与超载率 | 单元测试 | JUnit5 | 公式 4、5 | 样本入参 | 指数、超载率 | 指数约 `2.81`；超载率约 `181.41%` |
| ZCZX-CXPH-UT-004 | 公式计算 | 需草量/缺口/适宜头数 | 单元测试 | JUnit5 | 公式 7～10 | 样本入参 | 全年需草、缺口、适宜放牧 | 需草 `64000`；缺口 `41250`；适宜头约 `35.55` |
| ZCZX-CXPH-UT-005 | 公式计算 | 实际超载数量 | 单元测试 | JUnit5 | 公式 11 | 养殖 100、适宜约 35.55 | `actualOverloadHeads` | `64`（100−适宜，未超载为 0） |
| ZCZX-CXPH-UT-006 | 等级判定 | 四档边界 | 单元测试 | JUnit5 | §2.5、§3.2 | 无 | R=0、0.10、0.15、0.20、0.50、0.51 | 未超载/基本平衡/超载/严重超载与边界一致 |
| ZCZX-CXPH-UT-007 | 等级判定 | 指数=1 | 单元测试 | JUnit5 | 未超载 | 构造实际=理论 | `resolveLevel` | R=0%；等级 **未超载** |
| ZCZX-CXPH-UT-008 | 参数校验 | 面积与利用率 | 单元测试 | JUnit5 | §5.1 | 无 | `areaMu` 0/-1；`utilizationRate` -0.1/1.1 | 均失败 |
| ZCZX-CXPH-UT-009 | 参数校验 | 羊单位参数 | 单元测试 | JUnit5 | >0 | 无 | 年需草量、折算系数为 0 或负 | 失败 |
| ZCZX-CXPH-UT-010 | 参数校验 | 养殖数量 | 单元测试 | JUnit5 | ≥0 整数 | 无 | -1、1.5、0 | -1/小数失败；0 通过 |
| ZCZX-CXPH-UT-011 | 参数校验 | 草场 id | 单元测试 | JUnit5 | 有效草场 | Mock 草场 null/已删 | `validateForCalculate` | 失败 |
| ZCZX-CXPH-UT-012 | 边界 | 存栏为 0 | 单元测试 | JUnit5 | §5.5 | 样本产草参数；头数 0 | 计算 | 实际载畜量 0；超载率 -100%；等级未超载；超载头数 0 |
| ZCZX-CXPH-UT-013 | 边界 | 理论载畜量为 0 | 单元测试 | JUnit5 | §3.4 | 亩产草量 0；头数>0 | 计算 | `warning` 含无饲草供给；等级严重超载或指数 null |
| ZCZX-CXPH-UT-014 | 边界 | 理论为 0 且存栏 0 | 单元测试 | JUnit5 | §3.4 | 亩产草量 0；头数 0 | 计算 | 指数 0；等级未超载 |
| ZCZX-CXPH-UT-015 | 展示舍入 | 2 位小数 | 单元测试 | JUnit5 | §5.4 | 产生多位小数结果 | `scale2` | 四舍五入 2 位 |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-CXPH-API-001 | 计算 | 标准样本成功 | 接口测试 | Postman | 正常流程 | 已登录；有效 `grasslandId` | `POST .../calculate` Body 标准样本 | `code=200`；11 项结果与 **UT-001～005** 一致；`balanceLevel=4` |
| ZCZX-CXPH-API-002 | 计算 | 未超载样本 | 接口测试 | Postman | 等级 1 | 已登录 | 降低养殖数量使指数≤1 | `balanceLevel=1`；`balanceLevelName=未超载` |
| ZCZX-CXPH-API-003 | 计算 | 基本平衡样本 | 接口测试 | Postman | 等级 2 | 已登录 | 构造 0<R≤15% | `balanceLevel=2` |
| ZCZX-CXPH-API-004 | 计算 | 超载样本 | 接口测试 | Postman | 等级 3 | 已登录 | 构造 15%<R≤50% | `balanceLevel=3` |
| ZCZX-CXPH-API-005 | 计算 | 调整参数与台账不一致 | 接口测试 | Postman | 允许覆盖 | 已登录 | Body 中 `areaMu` 与台账不同 | 成功；按 Body 计算非台账值 |
| ZCZX-CXPH-API-006 | 计算 | 缺草场 id | 接口测试 | Postman | 必填 | 已登录 | 缺 `grasslandId` | 失败；`msg` 可区分 |
| ZCZX-CXPH-API-007 | 计算 | 面积≤0 | 接口测试 | Postman | §5.1 | 已登录 | `areaMu=0` | 失败 |
| ZCZX-CXPH-API-008 | 计算 | 利用率越界 | 接口测试 | Postman | 0～1 | 已登录 | `utilizationRate=1.2` | 失败 |
| ZCZX-CXPH-API-009 | 计算 | 羊单位年需草量≤0 | 接口测试 | Postman | §5.5 | 已登录 | `sheepUnitAnnualForageKg=0` | 失败 |
| ZCZX-CXPH-API-010 | 计算 | 折算系数≤0 | 接口测试 | Postman | §5.5 | 已登录 | `sheepUnitConvertCoeff=0` | 失败 |
| ZCZX-CXPH-API-011 | 计算 | 无效草场 id | 接口测试 | Postman | 主数据 | 已登录 | 不存在或已删 `grasslandId` | 失败 |
| ZCZX-CXPH-API-012 | 计算 | 存栏为 0 | 接口测试 | Postman | 边界 | 已登录 | `breedingHeadCount=0` | 成功；`actualOverloadHeads=0` |
| ZCZX-CXPH-API-013 | 计算 | 亩产草量为 0 | 接口测试 | Postman | 边界 | 已登录 | `grassYieldPerMu=0`、头数>0 | 成功；含 `warning` 或等级 4 |
| ZCZX-CXPH-API-014 | 默认值 | GET defaults | 接口测试 | Postman | §3.2 | 已配置 sys_config | `GET .../defaults` | `code=200`；含年需草量、折算系数默认值 |
| ZCZX-CXPH-API-015 | 主数据 | 草场列表复用 | 接口测试 | Postman | §3.3 | 草场 list 权限 | `GET .../grassland/list` | 返回有效草场供下拉 |
| ZCZX-CXPH-API-016 | 主数据 | 草场详情带出 | 接口测试 | Postman | §3.4 | 草场 query 权限 | `GET .../grassland/{id}` | 含 `areaMu`、`grassYieldPerMu`、`utilizationRate` |
| ZCZX-CXPH-API-017 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `POST .../calculate` | 401 或统一未登录 |
| ZCZX-CXPH-API-018 | 权限 | 无 query 权限 | 接口测试 | Postman | §6 | 无本模块权限 | `POST .../calculate` | 无权限失败 |
| ZCZX-CXPH-API-019 | 范围 | 无保存接口 | 接口测试 | Postman | 本期无 | 已登录 | `GET/PUT/DELETE` 测算记录类路径 | 404/405 或无路由 |
| ZCZX-CXPH-API-020 | 响应 | 失败可读 | 接口测试 | Postman | §7 | 已登录 | 触发面积、利用率、羊单位非法 | `code`、`msg` 可区分 |

---

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

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

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-CXPH-UI-001 | 页面 | 布局与公式区 | UI 测试 | Playwright+Chrome | §5.7 | 已登录 | 进入「草畜平衡计算」 | 见基础参数、计算结果、公式说明（若有） |
| ZCZX-CXPH-UI-002 | 草场 | 下拉选择带出 | UI 测试 | Playwright+Chrome | §5.2 | 有草场数据 | 选择「示范草场」 | 面积、亩产草量、利用率自动填入 |
| ZCZX-CXPH-UI-003 | 草场 | 切换清空结果 | UI 测试 | Playwright+Chrome | §5.2 | 已算出结果 | 换选另一草场 | 参数更新；原结果区清空或「—」 |
| ZCZX-CXPH-UI-004 | 计算 | 标准样本成功 | UI 测试 | Playwright+Chrome | §5.3 | 已选草场 | 补全羊单位参数与养殖数量→点「计算」 | 11 项结果展示；等级 **严重超载**（样本） |
| ZCZX-CXPH-UI-005 | 计算 | 结果只读 | UI 测试 | Playwright+Chrome | §5.4 | 已计算 | 尝试编辑结果区 | 不可编辑 |
| ZCZX-CXPH-UI-006 | 计算 | 未计算前占位 | UI 测试 | Playwright+Chrome | §5.4 | 刚进页面 | 查看结果区 | 空或「—」 |
| ZCZX-CXPH-UI-007 | 校验 | 未选草场 | UI 测试 | Playwright+Chrome | §5.1 | 已登录 | 不选草场直接计算 | 提示必选；结果不更新 |
| ZCZX-CXPH-UI-008 | 校验 | 面积非法 | UI 测试 | Playwright+Chrome | §5.1 | 已登录 | 面积填 0→计算 | 校验失败提示 |
| ZCZX-CXPH-UI-009 | 校验 | 利用率越界 | UI 测试 | Playwright+Chrome | §5.1 | 界面为 % | 填 120%→计算 | 失败或自动限制在 0～100% |
| ZCZX-CXPH-UI-010 | 校验 | 羊单位≤0 | UI 测试 | Playwright+Chrome | §5.5 | 已登录 | 年需草量 0→计算 | 校验失败 |
| ZCZX-CXPH-UI-011 | 计算 | 存栏为 0 | UI 测试 | Playwright+Chrome | §5.5 | 已登录 | 养殖数量 0→计算 | 实际载畜量 0；等级未超载 |
| ZCZX-CXPH-UI-012 | 清空 | 重置表单 | UI 测试 | Playwright+Chrome | §5.6 | 已填参并计算 | 点「清空」 | 输入与结果全部清空 |
| ZCZX-CXPH-UI-013 | 计算 | 修改参数再算 | UI 测试 | Playwright+Chrome | §4 | 已计算一次 | 改养殖数量→再计算 | 结果随新参数变化 |
| ZCZX-CXPH-UI-014 | 范围 | 无保存/历史 | UI 测试 | Playwright+Chrome | §3 | 已登录 | 浏览页面按钮 | 无保存、导出、历史列表 |
| ZCZX-CXPH-UI-015 | 权限 | 无菜单 | UI 测试 | Playwright+Chrome | §6 | 无本模块角色 | 登录后找菜单 | 无「草畜平衡计算」入口 |
| ZCZX-CXPH-UI-016 | 端到端 | 选草场-计算-清空 | UI 集成 | Playwright+Chrome | §4 | 权限齐备 | 选草场→计算→清空 | 全流程无报错 |

---

## Playwright 与谷歌浏览器（实施提示）

- 安装：`npm i -D @playwright/test`；`npx playwright install chromium`；本机 Chrome：`npx playwright install chrome`。  
- `playwright.config.ts`：`use: { channel: 'chrome', headless: false, locale: 'zh-CN', baseURL: 'http://localhost:80' }`；`storageState` 复用登录态。  
- 路由：`page.goto('/dataModel/grassLivestockBalance')`（以菜单 `component` 为准）。  
- 草场：`page.locator('.el-select').filter({ hasText: '草场名称' }).click()` 后选择选项。  
- 计算：`page.getByRole('button', { name: '计算' })`；断言结果区含「可利用饲草量」「草畜平衡等级」。  
- 清空：`page.getByRole('button', { name: '清空' })`。

---

## 覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常流程 | UT-001～007 | API-001～005、012、014～016 | UI-002、004、013、016 |
| 异常流程 | UT-008～011 | API-006～011、017～018 | UI-007～010 |
| 业务约束/公式 | UT-001～007、015 | API-001～004 | UI-004、005 |
| 边界 | UT-012～014 | API-012、013 | UI-011 |
| 草场联动 | UT-011 | API-015～016 | UI-002、003 |
| 清空/无落库 | — | API-019 | UI-012、014 |
| 权限 | — | API-017～018 | UI-015 |

---

## 功能需求追溯（自查）

| 需求章节 | 要点 | 主要对应用例 |
| --- | --- | --- |
| §5.1 参数校验 | 必填、范围 | UT-008～011；API-006～010；UI-007～010 |
| §5.2 草场联动 | 带出、切换清结果 | API-015～016；UI-002、003 |
| §5.3 公式 | 11 项指标 | UT-001～005；API-001；UI-004 |
| §2.5 等级 | 四档 | UT-006～007；API-002～004 |
| §5.5 边界 | 0 存栏、0 产草 | UT-012～014；API-012、013；UI-011 |
| §5.6 清空 | 前端重置 | UI-012 |
| §3 范围外 | 无保存 | API-019；UI-014 |

---

## 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：单元 15、接口 20、UI 16；对齐功能/技术方案；Playwright+Chrome；编号前缀 **ZCZX-CXPH** |
