牦牛存栏数据填报 — 测试用例
依据:牦牛存栏数据填报功能需求.md、牦牛存栏数据填报技术方案.md
接口 Base Path(示例):/dataModel/yakHerdInventory
模板文件:2026年.xlsx 第一个 Sheet
乡镇样本:巴青乡、江绵乡、岗切乡、雅安镇、拉西镇、本塔乡、杂色镇、贡日乡、玛如乡、阿秀乡(sys_dept,parent_id=100,order_num>12)
通用前置:已登录且具备模块权限;sys_dept 已执行 sql/sys_dept_import_town.sql;测试库无冲突数据或已隔离。
一、单元测试用例
| 用例编号 |
测试模块 |
测试项 |
测试类型 |
测试工具 |
测试目的 |
前置条件 |
测试步骤 |
预期结果 |
| ZCZX-MYCLTB-UT-001 |
年份 |
可选年份范围 |
单元测试 |
JUnit5 |
§2.2 |
固定时钟 2026 |
YearOptionsResolver.resolve() |
返回 2026~2021 共 6 年 |
| ZCZX-MYCLTB-UT-002 |
乡镇 |
字典过滤 |
单元测试 |
JUnit5 |
§2.3 |
Mock dept 表 |
TownDeptSupport.listReportTowns() |
仅 parent_id=100 且 order_num>12 |
| ZCZX-MYCLTB-UT-003 |
校验 |
必填年份乡镇 |
单元测试 |
JUnit5 |
§5.2 |
无 |
validate(row) 缺 statYear |
抛 ServiceException |
| ZCZX-MYCLTB-UT-004 |
校验 |
负数拒绝 |
单元测试 |
JUnit5 |
§2.5 |
无 |
yakTotal=-1 |
校验失败 |
| ZCZX-MYCLTB-UT-005 |
唯一性 |
同年同乡镇 |
单元测试 |
JUnit5+Mockito |
§5.2 |
已存在 2026+巴青乡 |
insert 同键 |
失败「已填报」 |
| ZCZX-MYCLTB-UT-006 |
新增 |
新增成功 |
单元测试 |
JUnit5+Mockito |
§5.2 |
无同年同乡镇记录 |
insert |
成功 |
| ZCZX-MYCLTB-UT-007 |
导入解析 |
识别表头行 |
单元测试 |
JUnit5 |
§3.8.1 |
2026年.xlsx |
detectHeaderRow(sheet) |
定位含「乡镇」表头 |
| ZCZX-MYCLTB-UT-008 |
导入解析 |
乡镇名匹配 |
单元测试 |
JUnit5 |
§5.6 |
行「杂色镇」 |
resolveTownDeptId |
返回对应 dept_id |
| ZCZX-MYCLTB-UT-009 |
导入解析 |
未知乡镇 |
单元测试 |
JUnit5 |
§5.6 |
行「不存在乡」 |
解析 |
记入 failMessages |
| ZCZX-MYCLTB-UT-010 |
导入解析 |
空行终止 |
单元测试 |
JUnit5 |
§5.6 |
数据后空行 |
parseRows |
仅 10 乡镇行 |
| ZCZX-MYCLTB-UT-011 |
导入 |
upsert 新增 |
单元测试 |
JUnit5+Mockito |
§5.6 |
DB 无 2025+本塔乡 |
importYear(2025,file) |
insertCount>=1 |
| ZCZX-MYCLTB-UT-012 |
导入 |
upsert 更新 |
单元测试 |
JUnit5+Mockito |
§5.6 |
已有 2026+各乡镇 |
同一 xlsx 再导入 |
updateCount=10;insertCount=0 |
| ZCZX-MYCLTB-UT-013 |
修改 |
记录不存在 |
单元测试 |
JUnit5+Mockito |
§5.3 |
id 不存在 |
update |
抛 ServiceException |
| ZCZX-MYCLTB-UT-014 |
删除 |
物理删除 |
单元测试 |
JUnit5+Mockito |
§5.4 |
有效 id |
deleteBizYakHerdInventoryByIds |
调用 Mapper 物理删除 |
| ZCZX-MYCLTB-UT-015 |
数据权限 |
乡镇账号过滤 |
单元测试 |
JUnit5+Mockito |
§6 |
用户 dept=杂色镇 |
selectList |
仅本乡镇 |
| ZCZX-MYCLTB-UT-016 |
预留字段 |
village_dept_id 可空 |
单元测试 |
JUnit5 |
§2.4 |
无 |
insert 不传 villageDeptId |
成功 |
| ZCZX-MYCLTB-UT-017 |
预留字段 |
village_dept_id 父子校验 |
单元测试 |
JUnit5+Mockito |
§2.4 |
乡镇 A、村居 B 非子节点 |
insert 带错误 villageDeptId |
失败(若启用校验)或成功仅存 id |
| ZCZX-MYCLTB-UT-018 |
导出 |
按年填充模板 |
单元测试 |
JUnit5 |
§5.7 |
模板+1 乡镇样本 |
YakHerdInventoryExcelExporter.export |
返回 xlsx;解析含对应存栏数 |
| ZCZX-MYCLTB-UT-019 |
导出 |
全县乡镇行数 |
单元测试 |
JUnit5 |
§5.7 |
10 乡镇字典 |
export(2026, towns, map) |
解析数据行 + 合计行 |
二、接口测试用例
| 用例编号 |
测试模块 |
测试项 |
测试类型 |
测试工具 |
测试目的 |
前置条件 |
测试步骤 |
预期结果 |
| ZCZX-MYCLTB-API-001 |
列表 |
默认分页 |
接口测试 |
Postman |
§5.1 |
已登录;有样本 |
GET /list |
code=200;含所属年份、乡镇、村居数、牧户数、存栏数、公牛/母牛存栏数 |
| ZCZX-MYCLTB-API-002 |
列表 |
按年份筛选 |
接口测试 |
Postman |
§5.1 |
有 2025、2026 数据 |
statYear=2026 |
仅 2026 |
| ZCZX-MYCLTB-API-003 |
列表 |
按乡镇筛选 |
接口测试 |
Postman |
§5.1 |
已知 dept_id |
townDeptId= |
仅该乡镇 |
| ZCZX-MYCLTB-API-004 |
列表 |
组合筛选 |
接口测试 |
Postman |
§5.1 |
已登录 |
年+乡镇 |
交集结果 |
| ZCZX-MYCLTB-API-005 |
详情 |
全字段 |
接口测试 |
Postman |
§5.5 |
有效 id |
GET /{id} |
返回全部字段(含 villageDeptId、分龄、种公牛等);列表 VO 不含的字段均在详情中 |
| ZCZX-MYCLTB-API-006 |
新增 |
必填成功 |
接口测试 |
Postman |
§5.2 |
无重复 |
POST 最小必填 |
成功 |
| ZCZX-MYCLTB-API-007 |
新增 |
缺年份 |
接口测试 |
Postman |
§5.2 |
已登录 |
缺 statYear |
失败 |
| ZCZX-MYCLTB-API-008 |
新增 |
缺乡镇 |
接口测试 |
Postman |
§5.2 |
已登录 |
缺 townDeptId |
失败 |
| ZCZX-MYCLTB-API-009 |
新增 |
重复同年乡镇 |
接口测试 |
Postman |
§5.2 |
已有记录 |
再 POST 同键 |
失败 |
| ZCZX-MYCLTB-API-010 |
修改 |
更新指标 |
接口测试 |
Postman |
§5.3 |
有效 id |
PUT 改 yakTotal |
成功;详情为新值 |
| ZCZX-MYCLTB-API-011 |
删除 |
物理删除 |
接口测试 |
Postman |
§5.4 |
有效 id |
DELETE /{id} |
成功;记录从库中移除 |
| ZCZX-MYCLTB-API-012 |
下拉 |
年份选项 |
接口测试 |
Postman |
§2.2 |
已登录 |
GET /yearOptions |
6 个年份 |
| ZCZX-MYCLTB-API-013 |
下拉 |
乡镇选项 |
接口测试 |
Postman |
§2.3 |
已登录 |
GET /townOptions |
10 个乡镇;order_num>12 |
| ZCZX-MYCLTB-API-014 |
导入 |
全量乡镇 |
接口测试 |
Postman |
§5.6 |
空库 2026 |
POST /importData+2026年.xlsx+statYear=2026 |
insertCount=10;failCount=0 |
| ZCZX-MYCLTB-API-015 |
导入 |
覆盖更新 |
接口测试 |
Postman |
§5.6 |
已有 2026 全量 |
改 Excel 一行再导入 |
updateCount>=1 |
| ZCZX-MYCLTB-API-016 |
导入 |
缺填报年份 |
接口测试 |
Postman |
§5.6 |
已登录 |
仅上传文件 |
失败 |
| ZCZX-MYCLTB-API-017 |
导入 |
非 xlsx |
接口测试 |
Postman |
§5.6 |
已登录 |
上传 .csv |
失败 |
| ZCZX-MYCLTB-API-018 |
权限 |
无 add |
接口测试 |
Postman |
§6 |
仅 list 角色 |
POST / |
403 |
| ZCZX-MYCLTB-API-019 |
权限 |
无 import |
接口测试 |
Postman |
§6 |
无 import |
POST /importData |
403 |
| ZCZX-MYCLTB-API-020 |
端到端 |
导入-查-详情 |
接口测试 |
Postman |
§4 |
空库 |
导入 2026→list→detail |
数据一致 |
| ZCZX-MYCLTB-API-021 |
导出 |
按年份导出 |
接口测试 |
Postman/MockMvc |
§5.7 |
有 2026 数据 |
GET /export?statYear=2026 |
200;Content-Type 为 xlsx |
| ZCZX-MYCLTB-API-022 |
导出 |
缺 statYear |
接口测试 |
Postman |
§5.7 |
已登录 |
GET /export 无参 |
失败 |
| ZCZX-MYCLTB-API-023 |
导出 |
非法年份 |
接口测试 |
Postman |
§5.7 |
已登录 |
statYear=1999 |
失败 |
| ZCZX-MYCLTB-API-024 |
权限 |
无 export |
接口测试 |
Postman |
§6 |
无 export |
GET /export?statYear=2026 |
403 |
| ZCZX-MYCLTB-API-025 |
端到端 |
导出-再导入 |
接口测试 |
Postman |
§5.7 |
有 2026 全量 |
导出→改一行→导入 |
upsert 成功 |
三、界面测试用例(UI)
工具:Playwright + Chrome(与项目其他模块一致)。
| 用例编号 |
测试模块 |
测试项 |
测试类型 |
测试工具 |
测试目的 |
前置条件 |
测试步骤 |
预期结果 |
| ZCZX-MYCLTB-UI-001 |
列表 |
默认加载 |
UI 测试 |
Playwright |
§5.1 |
有数据 |
进入菜单 |
列标题为:所属年份、乡镇、村居数、牧户数、存栏数、公牛存栏数、母牛存栏数 |
| ZCZX-MYCLTB-UI-002 |
列表 |
年份乡镇筛选 |
UI 测试 |
Playwright |
§5.1 |
有数据 |
选择后搜索 |
结果正确 |
| ZCZX-MYCLTB-UI-003 |
列表 |
重置 |
UI 测试 |
Playwright |
§5.1 |
已筛选 |
点重置 |
条件清空 |
| ZCZX-MYCLTB-UI-004 |
新增 |
必填校验 |
UI 测试 |
Playwright |
§5.2 |
有 add 权限 |
不选乡镇提交 |
表单提示 |
| ZCZX-MYCLTB-UI-005 |
新增 |
年份下拉 6 项 |
UI 测试 |
Playwright |
§2.2 |
打开表单 |
查看年份下拉 |
当年起前 5 年 |
| ZCZX-MYCLTB-UI-006 |
新增 |
乡镇下拉 |
UI 测试 |
Playwright |
§2.3 |
打开表单 |
查看乡镇下拉 |
10 个乡镇 |
| ZCZX-MYCLTB-UI-007 |
修改 |
回显保存 |
UI 测试 |
Playwright |
§5.3 |
有记录 |
修改牧户数保存 |
列表更新 |
| ZCZX-MYCLTB-UI-008 |
删除 |
二次确认 |
UI 测试 |
Playwright |
§5.4 |
有记录 |
删除确认 |
行消失 |
| ZCZX-MYCLTB-UI-009 |
详情 |
全字段只读 |
UI 测试 |
Playwright |
§5.5 |
有完整数据 |
点查看 |
展示全部字段;列表未展示的项(如分龄母牛、种公牛)均可见 |
| ZCZX-MYCLTB-UI-010 |
导入 |
选年上传 |
UI 测试 |
Playwright |
§5.6 |
有 import 权限 |
选 2026→上传模板 |
成功摘要 |
| ZCZX-MYCLTB-UI-011 |
导入 |
未选年份 |
UI 测试 |
Playwright |
§5.6 |
有 import 权限 |
直接上传 |
前端拦截或后端失败提示 |
| ZCZX-MYCLTB-UI-012 |
权限 |
无导入按钮 |
UI 测试 |
Playwright |
§6 |
无 import |
进入页面 |
无导入入口 |
| ZCZX-MYCLTB-UI-013 |
端到端 |
导入后列表 |
UI 集成 |
Playwright |
§4 |
空库 |
导入→筛选 2026 |
10 行乡镇数据 |
| ZCZX-MYCLTB-UI-014 |
导出 |
按年份导出 |
UI 测试 |
Playwright |
§5.7 |
有 export 权限;已选年份 |
点「按年份导出」 |
下载 {年}年牦牛存栏数据.xlsx |
| ZCZX-MYCLTB-UI-015 |
导出 |
未选年份 |
UI 测试 |
Playwright |
§5.7 |
有 export 权限 |
未选年份点导出 |
提示先选择所属年份 |
| ZCZX-MYCLTB-UI-016 |
权限 |
无导出按钮 |
UI 测试 |
Playwright |
§6 |
无 export |
进入页面 |
无「按年份导出」入口 |
四、覆盖对照
| 需求章节 |
要点 |
主要用例 |
| §2.2 年份 |
向前 5 年 |
UT-001;API-012;UI-005 |
| §2.3 乡镇 |
sys_dept 二级 order_num>12 |
UT-002;API-013;UI-006 |
| §5.1 列表 |
7 数据列+操作;详情全字段 |
API-001~004、005;UI-001~003、009 |
| §5.2~5.4 CRUD |
必填、唯一、删除 |
UT-003~006、013~014;API-006~011 |
| §5.5 详情 |
全字段 |
API-005;UI-009 |
| §5.6 导入 |
2026年.xlsx |
UT-007~012;API-014~017;UI-010~011 |
| §5.7 导出 |
按年全县乡镇 |
UT-018~019;API-021~025;UI-014~015 |
| §6 权限 |
按钮级 |
API-018~019、024;UI-012、016 |
五、修订记录
| 版本 |
说明 |
| 1.0 |
初版:单元 15、接口 20、UI 13;编号前缀 ZCZX-MYCLTB |
| 1.1 |
补充 village_dept_id 预留字段用例 UT-016~017 |
| 1.2 |
补充按年份导出用例 UT-018~019、API-021~025、UI-014~016 |
| 1.3 |
补充重复导入 upsert 用例 UT-011~012 |
| 1.4 |
取消逻辑删除:UT-014 改为物理删除;移除 UT-020 |