# 首页 Banner 设置 — 测试用例

> **依据：** 《首页banner设置功能需求.md》v1.0.1、《首页banner设置技术方案.md》v1.0  
> **范围：** 平台端 Banner CRUD/检索/行内改序；C 端 `GET /api/home/banners`；业务规则 BN1～BN14  
> **排除：** 跳转链接、定时上下线、分渠道 Banner、恢复已删、点击统计；商户/商品/订单模块联动（BN8～BN10 仅断言无影响）  
> **环境：** RuoYi v3.9.2；平台 `/agri/banner`；C 端 `/api/home/banners`；平台 Token；UI 为平台管理端 + C 端商城首页（Playwright · Chromium）

---

## 用例编号说明

| 前缀 | 类型 | 工具 |
|------|------|------|
| BAN-UT-xxx | 单元测试 | JUnit 5 + Mockito（Service / Validator） |
| BAN-API-xxx | 接口测试 | Apifox / REST Assured / MockMvc + Token |
| BAN-UI-xxx | 界面测试 | Playwright（Chromium，模拟 Chrome） |

---

## 一、单元测试

### BAN-UT-001 图片名称未删记录唯一-新增重复失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 名称唯一校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 BN3 |
| **前置条件** | 库中已有未删 `banner_name=春耕主推` |
| **测试步骤** | 调用 `insertBanner(dto)`，`bannerName=春耕主推` |
| **预期结果** | 抛 `ServiceException`；msg「图片名称已存在」 |

### BAN-UT-002 编辑名称唯一排除自身

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 名称唯一校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §6.2 |
| **前置条件** | ID=1 名「图A」；ID=2 名「图B」 |
| **测试步骤** | ① 编辑 ID=1 改名为「图B」 ② 保持「图A」 |
| **预期结果** | ① 失败 ② 通过 |

### BAN-UT-003 逻辑删除后同名可再新增

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 名称唯一范围 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证唯一仅 `del_flag=0` |
| **前置条件** | 「春耕主推」已 `del_flag=2` |
| **测试步骤** | 新增 `bannerName=春耕主推` |
| **预期结果** | 成功；新 `banner_id` |

### BAN-UT-004 图片名称为空拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §5.2 |
| **前置条件** | — |
| **测试步骤** | `validate(dto)`，`bannerName` 为空 |
| **预期结果** | 失败；「请输入图片名称」 |

### BAN-UT-005 未上传图片拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §5.2 |
| **前置条件** | — |
| **测试步骤** | `bannerImage` 为空提交 |
| **预期结果** | 失败；「请上传图片」 |

### BAN-UT-006 排序为负数拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 sortNo ≥0 |
| **前置条件** | — |
| **测试步骤** | `sortNo=-1` |
| **预期结果** | 失败；「排序须为非负整数」 |

### BAN-UT-007 enable_flag 非法值拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证仅 0/1 |
| **前置条件** | — |
| **测试步骤** | `enableFlag=2` |
| **预期结果** | 校验失败 |

### BAN-UT-008 新增默认 enable_flag=1、sort_no=0

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 默认值 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证技术方案 §5 |
| **前置条件** | Body 未传 `enableFlag`、`sortNo` |
| **测试步骤** | `insertBanner(dto)` |
| **预期结果** | 库中 `enable_flag=1`，`sort_no=0` |

### BAN-UT-009 列表排序 sort_no 升序同序 create_time

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 列表排序 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 BN4 |
| **前置条件** | 构造 sort 0/5/5 且 create_time 不同 |
| **测试步骤** | `selectBannerList(query)` |
| **预期结果** | 顺序为 sort 0 → 5(早) → 5(晚) |

### BAN-UT-010 listForApp 仅启用且未删

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | C 端列表 Service |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 BN5 |
| **前置条件** | 3 条：启用、禁用、已删各一 |
| **测试步骤** | `listBannersForApp()` |
| **预期结果** | 仅 1 条启用未删；含 `bannerImage`、`sortNo`；**无** `bannerName` |

### BAN-UT-011 updateSortNo 仅更新 sort_no

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 行内改序 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 BN12 |
| **前置条件** | 记录 bannerName/enable 已知 |
| **测试步骤** | `updateSortNo(bannerId, 99, operator)` |
| **预期结果** | 仅 `sort_no=99` 变化；其余字段不变 |

### BAN-UT-012 删除无关联校验直接逻辑删

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 删除 Service |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 BN7、无 existsRef |
| **前置条件** | 正常 Banner 一条 |
| **测试步骤** | `deleteBannerByIds([id])` |
| **预期结果** | `del_flag=2`；**不** 调用商品/订单 Facade |

### BAN-UT-013 批量删除含已删 ID 跳过或汇总

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 批量删除 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §7.2 非整批失败 |
| **前置条件** | ID1 正常；ID2 已删 |
| **测试步骤** | `deleteBannerByIds([ID1,ID2])` |
| **预期结果** | ID1 `del_flag=2`；返回成功或提示跳过 1 条；**非** 商品服务式整批取消 |

### BAN-UT-014 图片后缀非法拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 图片格式 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 BN11 |
| **前置条件** | — |
| **测试步骤** | `bannerImage=xxx.gif` |
| **预期结果** | 失败；msg 含 jpg/png/jpeg |

### BAN-UT-015 非 2:1 比例返回 warnAspectRatio 仍入库

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 宽高比提示 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 BN11 不阻断 |
| **前置条件** | Mock 可读图片 800×600 |
| **测试步骤** | `insertBanner(dto)` |
| **预期结果** | 入库成功；返回 `warnAspectRatio=true` |

### BAN-UT-016 已删记录 update 抛不存在

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 编辑前置 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证详情/编辑约束 |
| **前置条件** | `del_flag=2` |
| **测试步骤** | `updateBanner(dto)` |
| **预期结果** | 失败；「Banner 不存在或已删除」 |

### BAN-UT-017 禁用记录不出现在 listForApp

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 启停与 C 端 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 BN5、BN6 |
| **前置条件** | `enable_flag=0` 未删 |
| **测试步骤** | `listBannersForApp()` |
| **预期结果** | 不包含该 `banner_id` |

---

## 二、接口测试

### BAN-API-001 列表分页与默认排序

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证列表基础能力 |
| **前置条件** | `agri:banner:list`；≥2 条未删 Banner |
| **测试步骤** | `GET /agri/banner/list?pageNum=1&pageSize=10` |
| **预期结果** | `code=200`；`rows` 按 `sortNo` 升序；不含 `del_flag=2` |

### BAN-API-002 按图片名称模糊检索

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §4.3 |
| **前置条件** | 存在名称含「春耕」记录 |
| **测试步骤** | `GET /list?bannerName=春耕` |
| **预期结果** | 返回项 `bannerName` 均含「春耕」 |

### BAN-API-003 按是否启用筛选

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 enableFlag 检索 |
| **前置条件** | 启用、禁用各一条 |
| **测试步骤** | `GET /list?enableFlag=0` |
| **预期结果** | 全部 `enableFlag=0` |

### BAN-API-004 新增 Banner 成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证新增主流程 |
| **前置条件** | `agri:banner:add`；名称未占用；已上传 jpg |
| **测试步骤** | `POST /agri/banner` 提交合法 Body（§3.4） |
| **预期结果** | `code=200`；DB 新增；列表可见 |

### BAN-API-005 新增名称重复失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 BN3 |
| **前置条件** | 已存在同名未删 Banner |
| **测试步骤** | 再次 `POST` 相同 `bannerName` |
| **预期结果** | 失败；「图片名称已存在」 |

### BAN-API-006 新增缺必填字段失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证必填 |
| **前置条件** | — |
| **测试步骤** | `POST` 仅 `bannerName`，无图 |
| **预期结果** | `code≠200`；未新增 |

### BAN-API-007 编辑改图与启停成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6 |
| **前置条件** | 已有 Banner；`agri:banner:edit` |
| **测试步骤** | `PUT` 更换 `bannerImage`；`enableFlag` 0→1 |
| **预期结果** | `code=200`；DB 已更新 |

### BAN-API-008 编辑名称与他人重复失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 BN3 排除自身 |
| **前置条件** | A、B 两条不同名 |
| **测试步骤** | A 改名为 B 的名称 |
| **预期结果** | 失败；「图片名称已存在」 |

### BAN-API-009 行内改排序 PUT /sortNo

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | PUT /sortNo |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 BN12 |
| **前置条件** | Banner ID=1，`sortNo=0` |
| **测试步骤** | `PUT /agri/banner/sortNo` body `{bannerId:1,sortNo:99}` |
| **预期结果** | `code=200`；详情 `sortNo=99` |

### BAN-API-010 改排序为负数失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | PUT /sortNo |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 sortNo 校验 |
| **前置条件** | 正常 Banner |
| **测试步骤** | `sortNo=-1` |
| **预期结果** | 失败；排序非法 |

### BAN-API-011 单独删除逻辑删除

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | DELETE /{ids} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 BN7 |
| **前置条件** | `agri:banner:remove` |
| **测试步骤** | `DELETE /agri/banner/{id}` |
| **预期结果** | `code=200`；列表不可见；DB `del_flag=2` |

### BAN-API-012 批量删除多条成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | DELETE /{ids} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7.2 无关联阻断 |
| **前置条件** | 2 条可删 Banner |
| **测试步骤** | `DELETE /agri/banner/id1,id2` |
| **预期结果** | 两条均 `del_flag=2`；**非** 整批失败 |

### BAN-API-013 详情已删或不存在失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /{id} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §3.3 |
| **前置条件** | ID 不存在或已删 |
| **测试步骤** | `GET /agri/banner/999999` |
| **预期结果** | 失败；Banner 不存在或已删除 |

### BAN-API-014 无 list 权限 403

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 权限 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 @PreAuthorize |
| **前置条件** | Token 无 `agri:banner:list` |
| **测试步骤** | `GET /list` |
| **预期结果** | HTTP 403 或 RuoYi 无权限 |

### BAN-API-015 无 add/edit/remove 权限

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 权限 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7 菜单权限 |
| **前置条件** | Token 仅 `list` |
| **测试步骤** | 分别 `POST /`、`PUT /`、`DELETE /{id}` |
| **预期结果** | 均为 403；数据无变更 |

### BAN-API-016 C 端列表无需 Token

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /api/home/banners |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 Anonymous、§8.2 |
| **前置条件** | 至少 1 条启用 Banner |
| **测试步骤** | 不带 Authorization 调用 `GET /api/home/banners` |
| **预期结果** | `code=200`；`data` 为数组 |

### BAN-API-017 C 端仅返回启用未删

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /api/home/banners |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 BN5 |
| **前置条件** | 启用 1、禁用 1、已删 1 |
| **测试步骤** | `GET /api/home/banners` |
| **预期结果** | `data.length=1`；项仅含 `bannerId`、`bannerImage`、`sortNo` |

### BAN-API-018 C 端按 sortNo 排序

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /api/home/banners |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 BN4 C 端 |
| **前置条件** | 启用 Banner sort 10、0 |
| **测试步骤** | 调用 C 端列表 |
| **预期结果** | `data[0].sortNo=0` 在前 |

### BAN-API-019 禁用后 C 端立即不可见

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 启停即时生效 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 BN6 |
| **前置条件** | Banner 启用且在 C 端可见 |
| **测试步骤** | ① `PUT` 改 `enableFlag=0` ② `GET /api/home/banners` |
| **预期结果** | ② 不包含该 `bannerId` |

### BAN-API-020 删除后 C 端不可见

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 删除与 C 端 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7.3 |
| **前置条件** | 启用 Banner |
| **测试步骤** | ① `DELETE` ② C 端列表 |
| **预期结果** | ② 不含该条 |

### BAN-API-021 全部禁用 C 端返回空数组

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | GET /api/home/banners |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证零条可展示（BN13 数据层） |
| **前置条件** | 无 `enable_flag=1` 且未删记录 |
| **测试步骤** | `GET /api/home/banners` |
| **预期结果** | `data=[]` 或 `data` 空；`code=200` |

### BAN-API-022 改排序后 C 端顺序变化

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | BN6 改序 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证即时生效 |
| **前置条件** | 两条启用 Banner A(sort0)、B(sort1) |
| **测试步骤** | `PUT /sortNo` 将 B 改为 sort0 且 A 改为 sort1 → C 端列表 |
| **预期结果** | C 端顺序与新区间一致 |

---

## 三、界面测试（Playwright）

> **通用前置：** 平台端：管理员已登录，菜单「内容管理 → 首页 Banner 设置」；C 端：可访问用户商城首页 URL。  
> **工具：** Playwright + `chromium`（`npx playwright install chromium`）。

### BAN-UI-001 进入 Banner 列表页

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 列表页加载 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Chrome) |
| **测试目的** | 验证菜单与列表列 |
| **前置条件** | 有 `agri:banner:list` |
| **测试步骤** | 登录平台 → 进入「首页 Banner 设置」 |
| **预期结果** | 表格含图片名称、图片缩略图、是否启用、排序、操作；有查询区 |

### BAN-UI-002 高级检索按名称与启用状态

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 高级检索 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §4.3 |
| **前置条件** | 存在名称含「测试」的启用 Banner |
| **测试步骤** | 输入图片名称「测试」、启用=是 → 查询 → 重置 |
| **预期结果** | 查询后仅匹配行；重置后条件清空、列表恢复 |

### BAN-UI-003 新增 Banner 含图片上传

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 添加 Banner |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §5 主流程 |
| **前置条件** | 有 `add` 权限；准备合法 jpg ≤5MB |
| **测试步骤** | 新增 → 填名称 → 上传图 → 启用=是、排序=0 → 确定 |
| **预期结果** | 成功提示；列表出现新行且缩略图可见 |

### BAN-UI-004 新增必填项为空校验

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 添加校验 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证前端/后端必填 |
| **前置条件** | 打开新增弹窗 |
| **测试步骤** | 不填名称、不上传图直接提交 |
| **预期结果** | 表单项标红或 Toast；弹窗不关闭 |

### BAN-UI-005 编辑禁用后 C 端不展示

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 启停 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 BN6 端到端 |
| **前置条件** | Banner 在 C 端首页可见 |
| **测试步骤** | 平台编辑该条 → 是否启用=否 → 保存 → 打开 C 端首页 |
| **预期结果** | C 端轮播不含该图（或轮播区消失若仅此一条） |

### BAN-UI-006 列表行内改排序保存

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 排序操作 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 BN12 UI |
| **前置条件** | 列表≥2 条 |
| **测试步骤** | 修改某行排序值 → 失焦/点保存 → 刷新 C 端首页 |
| **预期结果** | Toast 成功；列表顺序更新；C 端轮播顺序同步 |

### BAN-UI-007 单独删除二次确认

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §7.1 |
| **前置条件** | 可删 Banner 一条 |
| **测试步骤** | 点删除 → 确认框点确定 |
| **预期结果** | 文案含「删除后不可恢复」；列表该行消失 |

### BAN-UI-008 批量删除

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 批量删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §7.2 |
| **前置条件** | 勾选 2 条 |
| **测试步骤** | 批量删除 → 确认 |
| **预期结果** | 2 条均从列表消失；C 端均不可见 |

### BAN-UI-009 无 add 权限不显示新增按钮

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 权限 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §7 菜单 |
| **前置条件** | 角色仅 `agri:banner:list` |
| **测试步骤** | 进入列表页 |
| **预期结果** | 无「新增」按钮 |

### BAN-UI-010 C 端首页无启用 Banner 不展示轮播区

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | C 端空态 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 BN13 |
| **前置条件** | 平台将全部 Banner 禁用或删除 |
| **测试步骤** | 打开用户商城首页 |
| **预期结果** | **无** 轮播区域/占位图；页面其他模块正常 |

### BAN-UI-011 C 端点击 Banner 仅预览无跳转

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | C 端交互 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 BN14 |
| **前置条件** | 首页有轮播图 |
| **测试步骤** | 点击轮播图 → 观察 URL 与弹层 |
| **预期结果** | 出现大图预览；**无** 路由跳转、无商品详情页 |

### BAN-UI-012 非 2:1 图片上传提示仍可保存

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | 图片比例提示 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 BN11 UI |
| **前置条件** | 准备 4:3 合法 jpg |
| **测试步骤** | 新增并上传 → 提交 |
| **预期结果** | 保存成功；界面提示建议使用 2:1（Toast/表单项警告） |

### BAN-UI-013 未登录访客可见首页轮播

| 要素 | 内容 |
|------|------|
| **测试模块** | 首页 Banner 设置 |
| **测试项** | C 端公开访问 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §8.2 访客 |
| **前置条件** | 至少有 1 条启用 Banner；浏览器无登录态 |
| **测试步骤** | 无痕打开 C 端商城首页 |
| **预期结果** | 轮播正常展示 |

---

## 四、用例统计

| 类型 | 数量 | 编号段 |
|------|------|--------|
| 单元测试 | 17 | BAN-UT-001～017 |
| 接口测试 | 22 | BAN-API-001～022 |
| 界面测试 | 13 | BAN-UI-001～013 |
| **合计** | **52** | — |

---

## 五、业务规则覆盖索引

| 规则 | 含义 | 用例（示例） |
|------|------|----------------|
| BN1 | 全平台一份 | BAN-UT-010（无 shop 维度） |
| BN2 | 仅平台维护 | BAN-UI-009；无商家端用例 |
| BN3 | 名称唯一 | BAN-UT-001～003；BAN-API-005/008 |
| BN4 | 排序规则 | BAN-UT-009；BAN-API-001/018/022 |
| BN5 | C 端仅启用 | BAN-UT-010/017；BAN-API-017/019 |
| BN6 | 即时生效 | BAN-API-019～022；BAN-UI-005/006 |
| BN7 | 逻辑删除 | BAN-UT-012；BAN-API-011/012/020 |
| BN8～BN10 | 无级联/无绑定 | BAN-UT-012（无 Facade 调用） |
| BN11 | 图片规格 | BAN-UT-014/015；BAN-UI-012 |
| BN12 | 行内改序 | BAN-UT-011；BAN-API-009；BAN-UI-006 |
| BN13 | 无效图/零条 UI | BAN-API-021；BAN-UI-010 |
| BN14 | 点击仅预览 | BAN-UI-011 |

| 功能域 | 正常 | 异常/约束 |
|--------|------|-----------|
| 列表检索 | BAN-API-001～003, BAN-UI-001/002 | BAN-API-014 |
| 新增 | BAN-API-004, BAN-UI-003 | BAN-API-005/006, BAN-UT-004/005 |
| 编辑 | BAN-API-007, BAN-UI-005 | BAN-API-008, BAN-UT-016 |
| 改序 | BAN-API-009/022, BAN-UI-006 | BAN-API-010 |
| 删除 | BAN-API-011/012, BAN-UI-007/008 | BAN-API-013 |
| C 端 | BAN-API-016～018, BAN-UI-013 | BAN-API-019～021, BAN-UI-010/011 |
| 权限 | — | BAN-API-014/015, BAN-UI-009 |

---

## 六、测试数据建议

| 数据 | 说明 |
|------|------|
| 启用 Banner ×2 | sort 0、10；用于排序与 C 端顺序 |
| 禁用 Banner ×1 | 用于检索与 C 端过滤 |
| 同名已删 ×1 | BAN-UT-003 复名新增 |
| 2:1 图 750×375 | 正常上传 |
| 4:3 图 | BN11 比例提示 |
| 角色仅 list | 权限 UI/API |

---

## 七、Playwright 执行说明

**依赖：** Node.js 18+；`@playwright/test`；Chromium。

```typescript
// tests/banner/banner-admin.spec.ts — 平台端示例
import { test, expect } from '@playwright/test';

test.beforeEach(async ({ page }) => {
  await page.goto(process.env.ADMIN_BASE_URL + '/login');
  await page.fill('input[name="username"]', process.env.ADMIN_USER!);
  await page.fill('input[name="password"]', process.env.ADMIN_PASS!);
  await page.click('button:has-text("登")');
  await page.getByRole('menuitem', { name: '首页 Banner 设置' }).click();
});

// BAN-UI-001
test('列表加载', async ({ page }) => {
  await expect(page.getByRole('columnheader', { name: '图片名称' })).toBeVisible();
});
```

```typescript
// tests/banner/banner-mall-home.spec.ts — C 端示例
import { test, expect } from '@playwright/test';

test('BAN-UI-010 无轮播', async ({ page }) => {
  await page.goto(process.env.MALL_BASE_URL + '/');
  await expect(page.locator('[data-testid="home-banner"]')).toHaveCount(0);
});
```

> 选择器以实际 RuoYi-Vue 与 C 端 DOM 为准；建议为轮播容器增加 `data-testid="home-banner"` 便于 UI-010/011。

---

*文档版本：v1.0 · 关联《首页banner设置功能需求.md》v1.0.1、《首页banner设置技术方案.md》v1.0*
