# 牦牛资产档案管理 — 测试用例 > 依据:`牦牛资产档案管理功能需求.md`、`牦牛资产档案管理技术方案.md` > **接口 Base Path(示例)**:`/dataModel/yakAsset`;若含 `context-path` 或网关前缀须补齐。鉴权与若依一致(Cookie / Token)。 **通用前置(无特殊说明)**:具备本模块菜单与按钮权限的账号已登录;开发环境 `third-party.farming.mode=stub` 可使用 `stub-yak-entries.json`。库中已有经同步或造数的档案样本(主表 `biz_yak_asset`,`del_flag=0`)。**资产状态**(`asset_status`):`1` 正常、`2` 死淘、`3` 丢失、`4` 出栏。 **样本约定(示例)**:`externalId=90001`,`yakNo=YAK20250001`(耳标);`farmId=1` 对应已同步牧场;父编号 `YAK-F001`、母编号 `YAK-M001`。 **界面(UI)测试**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。菜单路径以 `livestockFinance/yakAsset/index` 为准。 --- ## 一、单元测试用例 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ZCZX-MYNZDA-UT-001 | 状态映射 | 第三方状态→本地 | 单元测试 | JUnit5 | §2.7 | 配置映射表 | 映射到 1~4;旧码如死亡→2、在养→1 | 未知码抛异常 | | ZCZX-MYNZDA-UT-002 | 状态映射 | 非法本地状态 | 单元测试 | JUnit5 | 1~4 | 无 | `assetStatus` 为 0、5、null | 列表入参校验失败 | | ZCZX-MYNZDA-UT-003 | 月龄计算 | 由出生日期计算 | 单元测试 | JUnit5 | §2.4 | `birthDate=2024-01-15` | `resolveAgeMonths(固定今日)` | 月龄与约定算法一致(月差或四舍五入规则固定) | | ZCZX-MYNZDA-UT-004 | 列表校验 | 关键字 trim | 单元测试 | JUnit5 | 模糊查询 | 无 | `keyword` 含前后空格 | trim 后参与 `LIKE` | | ZCZX-MYNZDA-UT-005 | 同步合并 | 按 external_id 新增 | 单元测试 | JUnit5+Mockito | §5.3 | DB 无该 cattleId | `syncBundle` 新记录 | `insert` 主表;圈舍/批次关联写入 | | ZCZX-MYNZDA-UT-006 | 同步合并 | 按 external_id 更新 | 单元测试 | JUnit5+Mockito | §5.3 | DB 已有同 cattleId | `syncBundle` 字段变更 | `update` 主表;圈舍/批次覆盖 | | ZCZX-MYNZDA-UT-006A | OpenAPI 映射 | 入栏建档字段 | 单元测试 | JUnit5 | §2.1.1 | `OpenYakEntryDto` 样例 | `YakEntryOpenApiMapper.toBundle` | `yak_no`=耳标;`farmId`→牧场编码;字段与表一致 | | ZCZX-MYNZDA-UT-007 | 同步安全 | 失败不清库 | 单元测试 | JUnit5+Mockito | §5.3 | 已有档案 A | Mock 第三方抛超时;执行 sync | 档案 A 主表及子表条数不变 | | ZCZX-MYNZDA-UT-008 | 同步安全 | 单头失败不回滚全局 | 单元测试 | JUnit5+Mockito | 事务边界 | 批次含 2 头,第 2 头校验失败 | `syncAll` | 第 1 头成功落库;`failCount≥1`;第 1 头数据保留 | | ZCZX-MYNZDA-UT-009 | 牧场映射 | 映射成功写 pasture_id | 单元测试 | JUnit5+Mockito | §5.3 | `biz_pasture` 有匹配编码 | 同步带第三方牧场码 | `pasture_id` 非空;`pasture_name` 与主数据一致 | | ZCZX-MYNZDA-UT-010 | 牧场映射 | 映射失败仅名称 | 单元测试 | JUnit5+Mockito | §5.3 | 无匹配主数据 | 同步带未知牧场码+名称 | `pasture_id` 空;`pasture_name` 为第三方名或「未关联」 | | ZCZX-MYNZDA-UT-011 | 曲线查询 | 生理近 N 天 | 单元测试 | JUnit5+Mockito | §3.4.1 | Mock 45 天数据 | `selectPhysioChart(id, days=30)` | 仅返回最近 30 天内点;按 `collect_time` 升序或实现约定 | | ZCZX-MYNZDA-UT-012 | 曲线查询 | 生长实测/预测分组 | 单元测试 | JUnit5+Mockito | §3.5.1 | 混合 data_kind | `selectGrowthChart(id, weight)` | `actual` 仅 kind=1;`forecast` 仅 kind=2 | | ZCZX-MYNZDA-UT-013 | Service | 详情组装 | 单元测试 | JUnit5+Mockito | §3.2.1 | Mock 主表+六子表 | `selectDetailById` | 返回 `asset`+六数组;含 `penRecords`/`batchRecords` | | ZCZX-MYNZDA-UT-014 | Service | 已删档案不可查 | 单元测试 | JUnit5+Mockito | del_flag | `del_flag=2` | `selectById` / `selectDetail` | null 或 `ServiceException` | | ZCZX-MYNZDA-UT-015 | Service | byNo 查询 | 单元测试 | JUnit5+Mockito | §3.3 | 有效 yak_no | `selectDetailByYakNo` | 与按 id 详情结构一致 | | ZCZX-MYNZDA-UT-016 | 并发 | 同步防重入 | 单元测试 | JUnit5 | §3.7 | 无 | 连续两次 `tryLock` 同步 | 第二次拒绝或排队;不重复写库 | | ZCZX-MYNZDA-UT-017 | Mapper | 列表过滤排序 | 单元测试 | JUnit5 | §3.8 | 无 | 检查 `BizYakAssetMapper.xml` | `del_flag='0'`;`status_change_date desc, id desc`;`keyword` 模糊 `yak_no` | | ZCZX-MYNZDA-UT-018 | Mapper | 子表按资产删除 | 单元测试 | JUnit5 | 同步删插 | 无 | 检查子表 Mapper `deleteByYakAssetId` | 同步前按 `yak_asset_id` 删除 | --- ## 二、接口测试用例 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ZCZX-MYNZDA-API-001 | 列表 | 默认分页排序 | 接口测试 | Postman/curl | §5.1 | 已登录;多条档案 | `GET /dataModel/yakAsset/list` | `code=200`;`rows`≤20;`statusChangeDate` 新在前 | | ZCZX-MYNZDA-API-002 | 列表 | 牦牛编号模糊 | 接口测试 | Postman | keyword | 已知 `YAK20250001` | `keyword=250001` | 命中含片段记录 | | ZCZX-MYNZDA-API-003 | 列表 | 资产状态精确 | 接口测试 | Postman | §2.2 | 有不同状态样本 | `assetStatus=4` | 返回均为抵押中(status=4) | | ZCZX-MYNZDA-API-004 | 列表 | 组合筛选 | 接口测试 | Postman | 多条件 | 已登录 | `keyword`+`assetStatus` | 同时满足 | | ZCZX-MYNZDA-API-005 | 列表 | 非法资产状态 | 接口测试 | Postman | 1~4 | 已登录 | `assetStatus=99` | 失败;`msg` 可区分 | | ZCZX-MYNZDA-API-006 | 列表 | 不含已删除 | 接口测试 | Postman | del_flag | 已知 id 已删 | `GET list` | 列表无该记录 | | ZCZX-MYNZDA-API-007 | 列表 | 分页参数 | 接口测试 | Postman | 分页 | 数据>20 | `pageNum=2&pageSize=10` | 第 2 页;条数≤10 | | ZCZX-MYNZDA-API-008 | 列表 | 无物联数据显示 | 接口测试 | Postman | §5.1 | 体温/步数为 null 的记录 | `GET list` | 字段为 null 或前端约定占位;接口不报错 | | ZCZX-MYNZDA-API-009 | 详情 | 有效 id 全结构 | 接口测试 | Postman | §3.2.1、§5.5 | 含子表样本 | `GET /dataModel/yakAsset/{id}` | `data` 含 `asset`(扩展字段)、六类子表数组 | | ZCZX-MYNZDA-API-010 | 详情 | 无效/已删 id | 接口测试 | Postman | 异常 | 已登录 | 不存在或 `del_flag=2` 的 id | `data` 空或业务失败 | | ZCZX-MYNZDA-API-011 | 详情 | 按编号查询 | 接口测试 | Postman | §3.3 | 已知 yak_no | `GET .../byNo/YAK20250001` | 与按 id 详情字段一致 | | ZCZX-MYNZDA-API-012 | 详情 | 编号不存在 | 接口测试 | Postman | 异常 | 已登录 | `GET .../byNo/NOT_EXIST` | 失败或 `data` 空 | | ZCZX-MYNZDA-API-013 | 生理曲线 | 默认 30 天 | 接口测试 | Postman | §3.4 | 有>30 天时序 | `GET .../{id}/physioChart` | 点数覆盖近 30 天;含 bodyTemp/steps/envTemp | | ZCZX-MYNZDA-API-014 | 生理曲线 | 自定义 days | 接口测试 | Postman | Query | 已登录 | `.../physioChart?days=7` | 仅近 7 天 | | ZCZX-MYNZDA-API-015 | 生长曲线 | 实测与预测分组 | 接口测试 | Postman | §3.5.1 | 含 kind=1、2 | `GET .../{id}/growthChart?metric=weight` | `actual`、`forecast` 数组分离;无预测时 `forecast` 空 | | ZCZX-MYNZDA-API-016 | 生长曲线 | 指标参数 | 接口测试 | Postman | metric | 有体高数据 | `metric=height` | 返回体高序列 | | ZCZX-MYNZDA-API-017 | 同步 | 成功摘要 | 接口测试 | Postman/Mock | §5.3、§3.6.1 | Mock 第三方返回 1 新 1 更 | `POST .../sync` | `insertCount`/`updateCount`/`syncTime` 正确;`failCount=0` | | ZCZX-MYNZDA-API-018 | 同步 | 第三方超时 | 接口测试 | Postman/Mock | §5.3 | Mock 超时 | `POST .../sync` | 失败;`msg` 提示第三方不可用;库内原档案不变 | | ZCZX-MYNZDA-API-019 | 同步 | 鉴权失败 | 接口测试 | Postman/Mock | 第三方 | Mock 401 | `POST .../sync` | 失败;不误删数据 | | ZCZX-MYNZDA-API-020 | 同步 | 更新后列表可见 | 接口测试 | Postman | 端到端 | 同步改 `realtimeTemp` | `POST sync`→`GET list` | 列表体温为新值 | | ZCZX-MYNZDA-API-021 | 同步 | 子表覆盖 | 接口测试 | Postman/SQL | §5.3 | 同步前子表 N 条 | 同步后子表条数与第三方一致;旧 id 不残留 | | ZCZX-MYNZDA-API-022 | 范围约束 | 无增删改接口 | 接口测试 | Postman | §3 本期无 | 已登录 | `POST/PUT/DELETE /dataModel/yakAsset`(非 sync) | 404/405 或无权限 | | ZCZX-MYNZDA-API-023 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET .../yakAsset/list` | 401 或统一未登录 | | ZCZX-MYNZDA-API-024 | 权限 | 无 list 权限 | 接口测试 | Postman | §6 | 无 list 角色 | `GET list` | 无权限失败 | | ZCZX-MYNZDA-API-025 | 权限 | 无 sync 权限 | 接口测试 | Postman | §6 | 仅有 list+query | `POST .../sync` | 403 或业务无权限 | | ZCZX-MYNZDA-API-026 | 权限 | 有 query 无 sync | 接口测试 | Postman | 分离 | query 账号 | `GET/{id}` 成功;`POST sync` 失败 | 符合权限矩阵 | | ZCZX-MYNZDA-API-027 | 端到端 | 同步-查-详情 | 接口测试 | Postman | §4 | Mock 第三方 | `POST sync`→`GET list`→`GET/{id}`→`physioChart` | 各步成功;详情与子表一致 | | ZCZX-MYNZDA-API-028 | 响应 | 失败可读 | 接口测试 | Postman | §7 | 已登录 | 触发非法状态、不存在 id、同步失败 | `code`、`msg` 可区分场景 | --- ## 三、界面测试用例(UI) **测试工具**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ZCZX-MYNZDA-UI-001 | 列表 | 默认分页排序 | UI 测试 | Playwright+Chrome | §5.1 | 已登录;数据>20 | 进入「牦牛资产档案」菜单 | 默认每页 20;变更日期新在前 | | ZCZX-MYNZDA-UI-002 | 列表 | 牦牛编号筛选 | UI 测试 | Playwright+Chrome | 模糊 | 有样本 | 输入编号片段→搜索 | 表格含匹配行 | | ZCZX-MYNZDA-UI-003 | 列表 | 资产状态筛选 | UI 测试 | Playwright+Chrome | 精确 | 有多状态 | 选择「在养」→搜索 | 状态列均为在养 | | ZCZX-MYNZDA-UI-004 | 列表 | 组合与重置 | UI 测试 | Playwright+Chrome | §5.2 | 已筛选 | 搜索→点「重置」 | 条件清空;恢复默认列表 | | ZCZX-MYNZDA-UI-005 | 列表 | 展示列完整 | UI 测试 | Playwright+Chrome | §5.1 | 有数据 | 查看表头与首行 | 含编号、牧场、性别、月龄、体温、运动量、状态、变更日期、操作 | | ZCZX-MYNZDA-UI-006 | 列表 | 无物联占位 | UI 测试 | Playwright+Chrome | §5.1 | 无体温样本 | 查看该行 | 显示「—」或「暂无」 | | ZCZX-MYNZDA-UI-007 | 列表 | 无增删改按钮 | UI 测试 | Playwright+Chrome | §3 本期无 | 有写权限其他模块账号 | 进入列表页 | 无「新增」「编辑」「删除」;操作列仅「查看」 | | ZCZX-MYNZDA-UI-008 | 同步 | 成功提示 | UI 测试 | Playwright+Chrome | §5.3 | 有 sync 权限;第三方可用 | 点「同步」→等待结束 | 成功提示含新增/更新摘要;列表数据刷新 | | ZCZX-MYNZDA-UI-009 | 同步 | 执行中防重复 | UI 测试 | Playwright+Chrome | §5.2 | 有 sync 权限 | 同步进行中快速再次点击 | 按钮禁用或二次点击无效;仅一次请求 | | ZCZX-MYNZDA-UI-010 | 同步 | 失败提示 | UI 测试 | Playwright+Chrome | §7 | Mock/断网第三方 | 点「同步」 | 明确失败提示;列表原数据仍在 | | ZCZX-MYNZDA-UI-011 | 同步 | 无权限隐藏/禁用 | UI 测试 | Playwright+Chrome | §6 | 仅 list+query 账号 | 进入列表 | 无「同步」或点击被拒绝 | | ZCZX-MYNZDA-UI-012 | 详情 | 入口与只读 | UI 测试 | Playwright+Chrome | §5.4 | 有 query 权限 | 列表点「查看」 | 进入详情;无保存/编辑按钮 | | ZCZX-MYNZDA-UI-013 | 详情 | 顶部摘要条 | UI 测试 | Playwright+Chrome | §5.4 | 有完整档案 | 打开详情 | 展示编号、牧场、状态、性别、月龄 | | ZCZX-MYNZDA-UI-014 | 详情 | 基础信息块 | UI 测试 | Playwright+Chrome | §5.5(1) | 有样本 | 滚动至基础信息 | 含批次、出生日期、入栏、来源、养殖方式等 | | ZCZX-MYNZDA-UI-015 | 详情 | 系谱信息块 | UI 测试 | Playwright+Chrome | §5.5(2) | 有父母编号 | 查看系谱区 | 显示父/母编号;无则「—」 | | ZCZX-MYNZDA-UI-016 | 详情 | 系谱跳转 | UI 测试 | Playwright+Chrome | §5.4 | 父编号库内存在 | 点击父亲编号链接 | 跳转该牛详情或新页打开 | | ZCZX-MYNZDA-UI-017 | 详情 | 系谱不存在提示 | UI 测试 | Playwright+Chrome | §7 | 父编号不在库 | 点击父亲编号 | 提示不存在或不可跳转 | | ZCZX-MYNZDA-UI-018 | 详情 | 个体生理当前值 | UI 测试 | Playwright+Chrome | §5.5(3) | 有物联数据 | 查看生理区 | 体温、运动量、环境温度、位置、采集时间正确 | | ZCZX-MYNZDA-UI-019 | 详情 | 生理曲线图 | UI 测试 | Playwright+Chrome | §5.5(3) | 有近一月数据 | 查看曲线区域 | 近一月趋势;图例区分多指标 | | ZCZX-MYNZDA-UI-020 | 详情 | 生理无数据 | UI 测试 | Playwright+Chrome | §7 | 无时序数据 | 打开详情 | 曲线区空态或「暂无数据」 | | ZCZX-MYNZDA-UI-021 | 详情 | 生长列表默认 | UI 测试 | Playwright+Chrome | §5.5(4) | 有生长记录 | 进入生长区块 | 表格列齐全;最新记录在上 | | ZCZX-MYNZDA-UI-022 | 详情 | 生长列表/曲线切换 | UI 测试 | Playwright+Chrome | §5.5(4) | 有实测+预测 | 点「切换」至曲线 | 展示曲线;实测与预测**不同颜色** | | ZCZX-MYNZDA-UI-023 | 详情 | 生长仅实测 | UI 测试 | Playwright+Chrome | §5.5(4) | 仅实测数据 | 切换曲线模式 | 仅实测线;无预测图例 | | ZCZX-MYNZDA-UI-024 | 详情 | 繁殖性能列表 | UI 测试 | Playwright+Chrome | §5.5(5) | 有繁殖数据 | 查看繁殖区块 | 含胎次、产犊间隔、成活率等列 | | ZCZX-MYNZDA-UI-025 | 详情 | 饲喂数据列表 | UI 测试 | Playwright+Chrome | §5.5(6) | 有饲喂数据 | 查看饲喂区块 | 含开始/结束日龄、日补饲量、饲料类型 | | ZCZX-MYNZDA-UI-026 | 详情 | 子块暂无数据 | UI 测试 | Playwright+Chrome | §7 | 某子表为空 | 打开对应区块 | 「暂无数据」;页面不报错 | | ZCZX-MYNZDA-UI-027 | 时效 | 最近同步提示 | UI 测试 | Playwright+Chrome | §8 | 刚完成同步 | 查看列表或详情页 | 展示「数据截至」或 `lastSyncTime` 类文案 | | ZCZX-MYNZDA-UI-028 | 端到端 | 同步-查-详情 | UI 集成 | Playwright+Chrome | §4 | sync+query 权限 | 同步→按编号搜索→查看→切换生长曲线 | 全流程无报错;数据一致 | | ZCZX-MYNZDA-UI-029 | 权限 | 无菜单 | UI 测试 | Playwright+Chrome | §6 | 无本模块角色 | 登录后浏览菜单 | 无「牦牛资产档案」入口 | | ZCZX-MYNZDA-UI-030 | 权限 | 无 query 不可看详情 | UI 测试 | Playwright+Chrome | §6 | 仅 list 无 query(若可配) | 尝试打开详情路由 | 403 或拦截 | --- ## 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('/livestockFinance/yakAsset')`(以菜单 `component` 为准)。 - 列表:`page.getByPlaceholder('牦牛编号')` 或标签相邻 input;状态下拉 `page.locator('.el-select').filter({ hasText: '资产状态' })`。 - 同步:`page.getByRole('button', { name: '同步' })`;断言 `page.locator('.el-message--success')` 含「新增」「更新」。 - 详情:`page.getByRole('button', { name: '查看' }).first().click()`;断言无 `保存`/`确定` 类编辑主按钮。 - 生长切换:`page.getByRole('button', { name: /切换|曲线/ })`;曲线 canvas/svg 存在且图例含「实测」「预测」(文案以实现为准)。 --- ## 覆盖对照 | 类别 | 单元 UT | 接口 API | 界面 UI | | --- | --- | --- | --- | | 正常流程 | UT-003、005~006、009~013、015 | API-001~004、009~011、013~017、020~021、027 | UI-001~006、008、012~025、028 | | 异常流程 | UT-002、007~008、014 | API-005、010、012、018~019、023~026、028 | UI-010、017、020、026、029~030 | | 业务约束 | UT-001~002、011~012、016~018 | API-003、005~006、015、021~022 | UI-003、007、009、022~023 | | 同步与第三方 | UT-005~010、016 | API-017~021 | UI-008~011、027~028 | | 详情六块/曲线 | UT-011~013 | API-009、013~016 | UI-012~026 | | 权限 | — | API-023~026 | UI-011、029~030 | | 只读无 CRUD | — | API-022 | UI-007、012 | --- ## 功能需求追溯(自查) | 需求章节 | 要点 | 主要对应用例 | | --- | --- | --- | | §5.1 列表 | 编号模糊、状态精确、分页、列 | API-001~008;UI-001~006 | | §5.2 工具栏 | 搜索、重置、同步防重 | UI-004、008~009;API-027 | | §5.3 同步 | 合并键、子表、失败不清库、摘要 | UT-005~010、016;API-017~021;UI-008~011 | | §5.4 详情 | 只读、摘要、系谱跳转 | API-009~012;UI-012~017 | | §5.5 六块 | 生理曲线、生长切换/预测、繁殖、饲喂 | UT-011~013;API-013~016;UI-018~026 | | §6~§7 | 权限、错误提示 | API-023~028;UI-010、011、017、029~030 | | §3 范围外 | 无手工 CRUD | API-022;UI-007 | --- ## 修订记录 | 版本 | 说明 | | --- | --- | | 1.0 | 初版:单元 18、接口 28、UI 30;对齐功能/技术方案;Playwright+Chrome;编号前缀 **ZCZX-MYNZDA** |