# 商城首页 — 测试用例

> **依据：** 《商城首页功能需求.md》v1.0.1、《商城首页技术方案.md》v1.1  
> **关联：** 平台《首页banner设置测试用例.md》BAN-API-018～020（同源 `/api/home/banners`）、平台《商品分类测试用例.md》、《关联需求分析.md》§11  
> **范围：** C 端商城首页；`/api/home/banners`、`/api/home/categories`、`/api/home/hot-goods`；`HomeAppServiceImpl` / `HomeAppController`  
> **代码落位：** `baqing-shop/src/main/java/com/ruoyi/web/modules/home/`  
> **排除：** 搜索执行与结果页、商品详情可购四条件校验、Banner 平台 CRUD、下拉刷新、聚合 `/api/home/index`  
> **环境：** RuoYi v3.9.2-springboot2；MySQL 5.7.39；C 端 **无需 Token**（`@Anonymous`）；UI 使用 Playwright **`channel: 'chrome'`**

---

## 用例编号说明

| 前缀 | 类型 | 工具 |
|------|------|------|
| MHP-UT-xxx | 单元测试 | JUnit 5 + Mockito |
| MHP-API-xxx | 接口测试 | MockMvc / Apifox |
| MHP-UI-xxx | 界面测试 | Playwright（Google Chrome） |

> **命名：** **MHP** = Mall Home Page（商城首页）；Banner C 端细则与 **BAN-** 用例互补，本册 **不断重复** 平台 Banner CRUD。

---

## 测试数据约定

| 实体 | 说明 |
|------|------|
| Banner | B1 启用 sort=0；B2 启用 sort=1；B3 **禁用**；B4 已逻辑删除 |
| 平台一级分类 | C1「兽药」show=1 sort=0；C2「饲料」show=1 sort=1；C3「隐藏类」show=0；C4 店铺101一级（**不应出现**） |
| 平台二级 | C1 下 L2-A、L2-B（show=1） |
| 店铺 | S101 开业；S102 **停业**；S103 已逻辑删除 |
| 出售中商品 | G1 销量100 S101；G2 销量100 上架晚于 G1（同销量测 HM10）；G3 销量50；G4 S102 停业店；G5 stock=0；G6 待审核/已下架（**不进热销**）；G7～G12 用于凑满 >6 条 |
| 会员 | M1 正常；M2 **禁用**（首页仍可读） |

---

## 一、单元测试

### MHP-UT-001 类目仅平台一级且 show=1

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-001 |
| **测试模块** | 商城首页 |
| **测试项** | listPlatformLevel1Nav |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 HM5、HM6 |
| **前置条件** | Mock Mapper 返回 C1/C2/C3/C4 混合数据 |
| **测试步骤** | 调用 `listPlatformLevel1Nav()` |
| **预期结果** | 仅含 C1、C2；**不含** show=0、店铺分类 |

### MHP-UT-002 类目排序升序

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-002 |
| **测试模块** | 商城首页 |
| **测试项** | 类目 sort_no |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 §5.1 排序 |
| **前置条件** | C2 sort=1 在前，C1 sort=0 |
| **测试步骤** | `listPlatformLevel1Nav()` |
| **预期结果** | 顺序 C1 → C2 |

### MHP-UT-003 热销仅出售中且店铺未删

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-003 |
| **测试模块** | 商城首页 |
| **测试项** | listHotGoods 过滤 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 HM9 |
| **前置条件** | Mapper 模拟 G1～G6 多状态 |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | 仅 **出售中** 且 shop `del_flag=0`；**不含** G6、S103 商品 |

### MHP-UT-004 热销最多 6 条

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-004 |
| **测试模块** | 商城首页 |
| **测试项** | HOT_GOODS_LIMIT |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 HM8 |
| **前置条件** | Mapper 入参 `limit=6` |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | 调用 `selectHotGoodsForHome(6)`；返回 ≤6 条 |

### MHP-UT-005 热销按销量降序

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-005 |
| **测试模块** | 商城首页 |
| **测试项** | 热销排序键1 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 HM10 |
| **前置条件** | G3(50) G1(100) 同库 |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | G1 排在 G3 前 |

### MHP-UT-006 同销量按上架时间降序

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-006 |
| **测试模块** | 商城首页 |
| **测试项** | 热销排序键2 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 HM10 v1.0.1 |
| **前置条件** | G1、G2 销量均为 100；G2 `COALESCE(audit_time,submit_time)` 更晚 |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | G2 在 G1 前 |

### MHP-UT-007 同销量同上架时间按商品编号升序

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-007 |
| **测试模块** | 商城首页 |
| **测试项** | 热销排序键3 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 HM10 稳定性 |
| **前置条件** | G1/G2 销量、上架时间相同；goods_sn G001<G002 |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | G001 在前 |

### MHP-UT-008 热销含停业店商品

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-008 |
| **测试模块** | 商城首页 |
| **测试项** | 浏览层不过滤店态 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 §6.2、HM13 |
| **前置条件** | G4 属于 S102 停业、出售中 |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | **包含** G4（不在 Service 层过滤 shop_status） |

### MHP-UT-009 热销含库存为 0

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-009 |
| **测试模块** | 商城首页 |
| **测试项** | 浏览层不过滤库存 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 §6.2 |
| **前置条件** | G5 stock=0、出售中 |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | **包含** G5 |

### MHP-UT-010 店铺名实时 JOIN

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-010 |
| **测试模块** | 商城首页 |
| **测试项** | shopName 映射 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 HM11 |
| **前置条件** | JOIN 返回 shop_name=「新店名」 |
| **测试步骤** | `listHotGoods()` → VO |
| **预期结果** | `shopName=新店名`（非商品快照字段） |

### MHP-UT-011 热销零条返回空列表

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-011 |
| **测试模块** | 商城首页 |
| **测试项** | 热销空态 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 §6.6 |
| **前置条件** | Mapper 返回 empty |
| **测试步骤** | `listHotGoods()` |
| **预期结果** | 空 List；**不** 抛异常 |

### MHP-UT-012 类目零条返回空列表

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UT-012 |
| **测试模块** | 商城首页 |
| **测试项** | 类目空态 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit 5 + Mockito |
| **测试目的** | 验证 §5.4 |
| **前置条件** | 无 show=1 一级 |
| **测试步骤** | `listPlatformLevel1Nav()` |
| **预期结果** | 空 List |

---

## 二、接口测试

### MHP-API-001 类目接口无需 Token

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-001 |
| **测试模块** | 商城首页 |
| **测试项** | GET /categories 匿名 |
| **测试类型** | 接口测试 |
| **测试工具** | MockMvc / Apifox |
| **测试目的** | 验证 HM2、@Anonymous |
| **前置条件** | **不传** Authorization |
| **测试步骤** | GET `/api/home/categories` |
| **预期结果** | `code=200`；返回类目数组 |

### MHP-API-002 热销接口无需 Token

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-002 |
| **测试模块** | 商城首页 |
| **测试项** | GET /hot-goods 匿名 |
| **测试类型** | 接口测试 |
| **测试工具** | MockMvc / Apifox |
| **测试目的** | 验证 HM2 |
| **前置条件** | 无 Token |
| **测试步骤** | GET `/api/home/hot-goods` |
| **预期结果** | `code=200`；`data` 为数组 |

### MHP-API-003 禁用会员 Token 仍可读首页接口

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-003 |
| **测试模块** | 商城首页 |
| **测试项** | 会员禁用不拦读 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM2、§4.2 |
| **前置条件** | M2 禁用会员 Token（若有） |
| **测试步骤** | 带 Token 调 `/categories`、`/hot-goods` |
| **预期结果** | 均 `code=200`（首页读 **不** 校验会员 status） |

### MHP-API-004 类目响应字段契约

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-004 |
| **测试模块** | 商城首页 |
| **测试项** | categories VO |
| **测试类型** | 接口测试 |
| **测试工具** | MockMvc |
| **测试目的** | 验证 §3.3 |
| **前置条件** | 存在 C1 |
| **测试步骤** | GET `/api/home/categories` |
| **预期结果** | 元素含 `categoryId/categoryName/categoryPic/sortNo` |

### MHP-API-005 类目不含店铺分类

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-005 |
| **测试模块** | 商城首页 |
| **测试项** | 平台类目隔离 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM6 |
| **前置条件** | 库中 C4 为店铺101一级 |
| **测试步骤** | GET `/categories` |
| **预期结果** | **不含** C4 |

### MHP-API-006 类目不含 show=0

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-006 |
| **测试模块** | 商城首页 |
| **测试项** | show_flag 过滤 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM5 |
| **前置条件** | C3 show=0 存在 |
| **测试步骤** | GET `/categories` |
| **预期结果** | **不含** C3 |

### MHP-API-007 热销响应字段契约

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-007 |
| **测试模块** | 商城首页 |
| **测试项** | hot-goods VO |
| **测试类型** | 接口测试 |
| **测试工具** | MockMvc |
| **测试目的** | 验证 §3.4、HM11 |
| **前置条件** | G1 出售中 |
| **测试步骤** | GET `/api/home/hot-goods` |
| **预期结果** | 含 `goodsId/goodsSn/goodsName/mainPic/salePrice/shopId/shopName` |

### MHP-API-008 热销最多 6 条

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-008 |
| **测试模块** | 商城首页 |
| **测试项** | LIMIT 6 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM8 |
| **前置条件** | ≥7 条符合条件出售中商品 |
| **测试步骤** | GET `/hot-goods` |
| **预期结果** | `data.length=6` |

### MHP-API-009 热销不足 6 不补齐

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-009 |
| **测试模块** | 商城首页 |
| **测试项** | 实际条数 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6.6 |
| **前置条件** | 仅 3 条出售中 |
| **测试步骤** | GET `/hot-goods` |
| **预期结果** | `data.length=3` |

### MHP-API-010 热销零条空数组

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-010 |
| **测试模块** | 商城首页 |
| **测试项** | 热销空态 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6.6 |
| **前置条件** | 无出售中商品 |
| **测试步骤** | GET `/hot-goods` |
| **预期结果** | `code=200`；`data=[]` |

### MHP-API-011 热销排序销量优先

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-011 |
| **测试模块** | 商城首页 |
| **测试项** | 排序 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM10 |
| **前置条件** | G1 销量100；G3 销量50 |
| **测试步骤** | GET `/hot-goods` |
| **预期结果** | 第一条 `goodsId=G1` |

### MHP-API-012 热销含停业店商品

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-012 |
| **测试模块** | 商城首页 |
| **测试项** | 浏览层店态 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6.2 |
| **前置条件** | G4@S102 停业、出售中 |
| **测试步骤** | GET `/hot-goods` |
| **预期结果** | 列表 **含** G4 |

### MHP-API-013 平台改店名后热销 shopName 更新

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-013 |
| **测试模块** | 商城首页 |
| **测试项** | 店铺名实时 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM11 |
| **前置条件** | 平台将 S101 改名为「新店」 |
| **测试步骤** | 再次 GET `/hot-goods` |
| **预期结果** | 对应行 `shopName=新店` |

### MHP-API-014 Banner 与 home 接口独立

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-014 |
| **测试模块** | 商城首页 |
| **测试项** | HM14 三接口 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证并行加载、无聚合 |
| **前置条件** | 三接口均可达 |
| **测试步骤** | 分别 GET `/banners`、`/categories`、`/hot-goods` |
| **预期结果** | 各自 `code=200`；**无** `/api/home/index` |

### MHP-API-015 平台禁用 Banner 后 C 端列表变化

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-015 |
| **测试模块** | 商城首页 |
| **测试项** | Banner 联动 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM4、BN6 |
| **前置条件** | 平台将 B1 禁用 |
| **测试步骤** | GET `/api/home/banners` |
| **预期结果** | **不含** B1 |

### MHP-API-016 商品下架后退出热销

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-016 |
| **测试模块** | 商城首页 |
| **测试项** | 状态联动 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 HM9 |
| **前置条件** | G1 由出售中→已下架 |
| **测试步骤** | GET `/hot-goods` |
| **预期结果** | **不含** G1 |

### MHP-API-017 类目改 show=0 后退出导航

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-017 |
| **测试模块** | 商城首页 |
| **测试项** | 分类联动 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §9 |
| **前置条件** | 平台将 C1 show 改为 0 |
| **测试步骤** | GET `/categories` |
| **预期结果** | **不含** C1 |

### MHP-API-018 无效 Token 不影响匿名读

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-API-018 |
| **测试模块** | 商城首页 |
| **测试项** | 匿名优先 |
| **测试类型** | 接口测试 |
| **测试工具** | MockMvc |
| **测试目的** | 验证 @Anonymous |
| **前置条件** | 传过期/乱码 Token |
| **测试步骤** | GET `/categories` |
| **预期结果** | 仍 `code=200`（或忽略无效 Token） |

---

## 三、界面测试（Playwright · Chrome）

> **页面路径（建议）：** C 端商城 Tab 首页 `/#/mall/home`（以实际路由为准）  
> **配置：** `browser.newContext()` + `channel: 'chrome'`

### MHP-UI-001 首页四区块结构

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-001 |
| **测试模块** | 商城首页 |
| **测试项** | 页面结构 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 §2 顺序 |
| **前置条件** | 访客打开首页；三接口有数据 |
| **测试步骤** | 目视/断言 DOM 顺序 |
| **预期结果** | 自上而下：搜索栏 → Banner（若有）→ 类目导航 → 热销区 |

### MHP-UI-002 搜索栏占位文案

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-002 |
| **测试模块** | 商城首页 |
| **测试项** | 搜索占位 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM3 |
| **前置条件** | 进入首页 |
| **测试步骤** | 读取搜索框 placeholder |
| **预期结果** | **「搜索兽药、饲料、店铺」** |

### MHP-UI-003 点击搜索栏跳转搜索页

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-003 |
| **测试模块** | 商城首页 |
| **测试项** | 搜索入口 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 §3.2 |
| **前置条件** | 首页已加载 |
| **测试步骤** | 点击搜索栏 |
| **预期结果** | 路由至搜索输入页（URL/标题变化） |

### MHP-UI-004 有 Banner 时展示轮播区

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-004 |
| **测试模块** | 商城首页 |
| **测试项** | Banner 展示 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM4 |
| **前置条件** | ≥1 条启用 Banner |
| **测试步骤** | 打开首页 |
| **预期结果** | 可见轮播区与图片 |

### MHP-UI-005 零 Banner 不占位

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-005 |
| **测试模块** | 商城首页 |
| **测试项** | Banner 空态 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 BN13、§4.3 |
| **前置条件** | 全部 Banner 禁用或无效 |
| **测试步骤** | 打开首页 |
| **预期结果** | **无** 轮播占位块；类目/热销仍展示 |

### MHP-UI-006 点击 Banner 预览大图

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-006 |
| **测试模块** | 商城首页 |
| **测试项** | Banner 点击 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 BN14 |
| **前置条件** | 有 Banner |
| **测试步骤** | 点击当前 Banner 图 |
| **预期结果** | 弹出预览层/全屏；**无** 路由跳转 |

### MHP-UI-007 类目导航含一级与「更多」

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-007 |
| **测试模块** | 商城首页 |
| **测试项** | 类目导航 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM5、§5.2 |
| **前置条件** | C1、C2 可见 |
| **测试步骤** | 检查导航区 |
| **预期结果** | 显示 C1/C2 名称+图；**末尾有「更多」** |

### MHP-UI-008 点击一级类目跳转

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-008 |
| **测试模块** | 商城首页 |
| **测试项** | 类目跳转 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM7 |
| **前置条件** | 存在 C1 |
| **测试步骤** | 点击「兽药」类目 |
| **预期结果** | 进入一级分类商品页；URL 含 `categoryId`；可见二级 Tab |

### MHP-UI-009 点击「更多」进全部分类

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-009 |
| **测试模块** | 商城首页 |
| **测试项** | 更多入口 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM7 |
| **前置条件** | 首页已加载 |
| **测试步骤** | 点击「更多」 |
| **预期结果** | 进入全部分类页（一级+二级树） |

### MHP-UI-010 热销卡片字段展示

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-010 |
| **测试模块** | 商城首页 |
| **测试项** | 热销列表 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM11、§6.4 |
| **前置条件** | ≥1 条热销 |
| **测试步骤** | 检查首卡 |
| **预期结果** | 可见主图、名称、售价、店铺名；**不** 展示销量数字 |

### MHP-UI-011 热销最多展示 6 卡

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-011 |
| **测试模块** | 商城首页 |
| **测试项** | Top6 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM8 |
| **前置条件** | 后端 ≥7 条热销 |
| **测试步骤** | 统计热销区卡片数 |
| **预期结果** | **=6** |

### MHP-UI-012 点击热销进商品详情

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-012 |
| **测试模块** | 商城首页 |
| **测试项** | 热销跳转 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM12 |
| **前置条件** | 有 G1 |
| **测试步骤** | 点击 G1 卡片 |
| **预期结果** | 进入商品详情页；URL 含 `goodsId` |

### MHP-UI-013 访客与会员首页一致可读

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-013 |
| **测试模块** | 商城首页 |
| **测试项** | 访客/会员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM2 |
| **前置条件** | ① 未登录 ② M1 登录 |
| **测试步骤** | 分别打开首页 |
| **预期结果** | 均可见 Banner/类目/热销（内容一致） |

### MHP-UI-014 Banner 接口失败不白屏

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-014 |
| **测试模块** | 商城首页 |
| **测试项** | 模块失败降级 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 HM14、§4.3 |
| **前置条件** | Mock/route 使 `/banners` 500 |
| **测试步骤** | 打开首页 |
| **预期结果** | 无 Banner 区；类目/热销 **仍加载**；整页 **不** 白屏 |

### MHP-UI-015 热销接口失败空态

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-015 |
| **测试模块** | 商城首页 |
| **测试项** | 热销失败 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 §6.7、HM14 |
| **前置条件** | Mock `/hot-goods` 失败 |
| **测试步骤** | 打开首页 |
| **预期结果** | 热销区空态或隐藏；**无** 重试按钮 |

### MHP-UI-016 无下拉刷新

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-016 |
| **测试模块** | 商城首页 |
| **测试项** | 下拉刷新 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 §7.2 v1.0.1 |
| **前置条件** | 首页已加载 |
| **测试步骤** | 模拟下拉手势 |
| **预期结果** | **不触发** 全页刷新 Loading（无 pull-refresh 组件） |

### MHP-UI-017 返回首页保留滚动位置

| 要素 | 内容 |
|------|------|
| **用例编号** | MHP-UI-017 |
| **测试模块** | 商城首页 |
| **测试项** | 返回行为 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright（Chrome） |
| **测试目的** | 验证 §7.3 |
| **前置条件** | 首页滚至热销区 |
| **测试步骤** | 进详情 → 浏览器/应用返回 |
| **预期结果** | 回到首页；滚动位置 **大致保留**（以前台 UX 为准） |

---

## 四、业务规则覆盖矩阵

| 规则 | UT | API | UI |
|------|:--:|:---:|:--:|
| HM1 全平台热销 | UT-003 | API-008 | UI-011 |
| HM2 匿名可读 | — | API-001/002/003 | UI-013 |
| HM3 搜索占位 | — | — | UI-002 |
| HM4 Banner | — | API-014/015 | UI-004/005/006 |
| HM5/HM6 平台一级类目 | UT-001 | API-005/006 | UI-007 |
| HM7 类目跳转 | — | — | UI-008/009 |
| HM8 Top6 | UT-004 | API-008/009 | UI-011 |
| HM9 出售中 | UT-003 | API-016 | — |
| HM10 排序 | UT-005/006/007 | API-011 | — |
| HM11 店铺名实时 | UT-010 | API-013 | UI-010 |
| HM12 进详情 | — | — | UI-012 |
| HM13 展示≠可购 | UT-008/009 | API-012 | — |
| HM14 模块独立/空态 | UT-011/012 | API-014 | UI-014/015 |
| HM15 无写接口 | — | — | — |

---

## 五、自动化映射

| 用例 | 代码位置 | 状态 |
|------|----------|------|
| MHP-UT-001～012 + Banner | `HomeAppServiceImplTest.java` | **已实现**（17 用例） |
| MHP-API-001～018 + Banner | `HomeAppControllerTest.java` | **已实现**（8 用例） |
| MHP-UI-001～017 | `e2e/consumer/mall-home.spec.ts`（Playwright `channel: 'chrome'`） | **待实现** |

---

## 六、用例统计

| 类型 | 数量 | 自动化 |
|------|------|--------|
| 单元测试 MHP-UT | 12 | 17（含 Banner 3） |
| 接口测试 MHP-API | 18 | 8（核心契约） |
| 界面测试 MHP-UI | 17 | 待实现 |
| **合计** | **47** | **25 已实现** |

---

## 七、修订记录

| 版本 | 说明 |
|------|------|
| **v1.0** | 首版；47 用例；覆盖 HM1～HM15、BN C 端协作、v1.0.1 排序/空态/不做下拉刷新 |
| **v1.1** | 同步技术方案 v1.1；§5 自动化映射标注 **已实现**；Banner 测试归 `HomeApp*Test` |

---

*文档版本：v1.1 · 关联《商城首页功能需求.md》v1.0.1、《商城首页技术方案.md》v1.1*
