- 报告期次:第1次 | 报告日期:2026-10-08 | 项目组号:第3组 | 项目名称:在线购物系统
- 已完成工作:测试技术选型预研:确定测试策略与单元 / 接口 / UI 自动化工具链,明确测试范围、重点场景与测试节奏,完成学习笔记
- 成果物:测试技术选型说明 / 学习笔记
- 项目名称:在线购物系统
- 项目组号:第 3 组
- 负责人(完成人):叶文锦
- 版本:v1
- 日期:2026-10-08
- 覆盖需求规格说明书中的 12 个用例与全部业务规则,重点保障状态机、排队、口令码、单件约束等核心逻辑的正确性。
- 测试要能自动化执行,支持回归,不能只靠手工点点点。
- 团队以 Java 为主,测试框架优先选择 Java 生态,降低学习成本。
- 迭代 2 起随开发开展测试,迭代 6 完成自动化体系。
| 维度 |
JUnit 5 + REST Assured + Playwright |
TestNG + Selenium |
Jest + Cypress(Node) |
| 团队匹配度 |
高(Java 生态,与后端同语言) |
高(Java) |
中(需学 JS) |
| 单元测试 |
JUnit 5,与 Spring Boot 集成好 |
TestNG,功能相近 |
不适合后端单元测试 |
| 接口测试 |
REST Assured,DSL 简洁 |
REST Assured 同样可用 |
Supertest / Axios |
| UI 自动化 |
Playwright,自动等待、跨浏览器 |
Selenium,需手动等待 |
Cypress,仅限 Chromium 系 |
| 报告 |
Allure,可视化好 |
Allure / TestNG 报告 |
Mocha 报告 |
| 与本项目匹配度 |
高:全栈覆盖,与后端同语言 |
高,但 Selenium 等待较繁琐 |
中:前后端测试语言分裂 |
结论:选择 JUnit 5 + REST Assured + Playwright。 与后端同用 Java,单元测试和接口测试复用同一套依赖;Playwright 比 Selenium 更稳定,自动等待减少 flaky。
| 技术 |
版本 |
用途 |
| JUnit 5 |
5.10+ |
单元测试框架 |
| Spring Boot Test |
3.x |
集成测试,加载 Spring 上下文 |
| REST Assured |
5.x |
REST 接口测试 |
| Mockito |
5.x |
单元测试中的 Mock |
| Playwright |
1.x |
UI 自动化测试(Java 绑定) |
| Allure |
2.x |
测试报告 |
| H2 Database |
2.x |
测试用内存数据库,隔离真实数据 |
- JUnit 5 是 Java 单元测试事实标准,Spring Boot 开箱即用。
- REST Assured 的 DSL 写接口测试像自然语言,断言清晰,适合验证状态码、响应体结构。
- Playwright 自动等待元素就绪,比 Selenium 少写大量 sleep,UI 测试更稳定。
- H2 内存数据库让测试不依赖本地 MySQL,CI 上也能跑。
- Mockito 隔离外部依赖,单元测试只测自己的逻辑。
本章节说明我在选型过程中实际动手做了什么,而非照搬官方文档。所有验证均在本地完成,可复现。
5.1 用 JUnit 5 写了一个状态机流转的单元测试 Demo
- 针对 ProductStatus 枚举的
canTransitTo 方法写了 3 个测试用例:
- 在售 → 已冻结:true
- 已冻结 → 已下架:true
- 在售 → 已下架:false(非法流转)
- 实测:3 个用例全部通过,断言符合预期。
- 结论:状态机逻辑可以用单元测试全覆盖,每次改状态机都跑一遍,防止回归。
5.2 用 REST Assured 写了一个登录接口的测试 Demo
- 启动一个 mock 的登录接口,用 REST Assured 发送 POST 请求。
- 实测:
- 正确用户名密码 → 200 + 返回登录态
- 错误密码 → 401 + 错误信息
- 结论:接口测试可以覆盖正常和异常路径,比手工点更可靠。
5.3 用 Playwright 写了一个打开登录页的 UI 测试 Demo
- 用 Playwright for Java 启动 Chromium,访问登录页,填写用户名密码,点击登录按钮。
- 实测:脚本能自动打开浏览器、定位输入框、输入文字、点击按钮,整个过程无需人工干预。
- 结论:Playwright 可以覆盖登录、发布商品等核心 UI 流程的自动化回归。
5.4 验证 H2 内存数据库在集成测试中的隔离性
- 配置测试环境用 H2 代替 MySQL,跑一个插入商品再查询的集成测试。
- 实测:每次测试前自动建表、测试后自动清数据,不污染真实数据库。
- 结论:集成测试用 H2 可以快速、隔离地验证 Service + Mapper 层。
- 对一个依赖 ProductMapper 的 Service 方法,用 Mockito mock Mapper,只测 Service 的业务逻辑。
- 实测:不需要数据库就能跑 Service 层测试,速度快(< 100ms)。
- 结论:单元测试用 Mockito 隔离数据层,集成测试用 H2 验证真实链路,两层互补。
- JUnit 5 + REST Assured + Playwright 能覆盖单元、接口、UI 三层测试,且全部在 Java 生态内。
- 上述 Demo 代码已作为测试骨架,迭代 2 起随开发补充真实用例。
| 层级 |
工具 |
覆盖范围 |
执行时机 |
| 单元测试 |
JUnit 5 + Mockito |
Service 层状态机、业务逻辑、工具类 |
每次提交前 |
| 接口测试 |
REST Assured |
Controller 层接口、入参校验、状态码 |
每次提交前 / CI |
| 集成测试 |
Spring Boot Test + H2 |
Service + Mapper 全链路 |
每次提交前 / CI |
| UI 自动化 |
Playwright |
买家端、卖家端核心流程 |
迭代 6 起每日回归 |
-
状态机非法流转被拒绝:在售不能直接到已下架,已下架不能流转。
-
口令码唯一 / 失效规则:同一商品口令码不重复,商品下架后口令码失效。
-
排队先到先得与失败递补:按提交时间排序,队首交易失败后下一位递补。
-
单件在售约束:已有在售/冻结商品时发布新商品被拒绝。
-
字段校验:名称必填、价格 > 0、手机号 11 位。
@Test
void testIllegalTransition() {
ProductStatus onSale = ProductStatus.ON_SALE;
assertFalse(onSale.canTransitTo(ProductStatus.DELISTED));
}
@Test
void testLoginSuccess() {
given()
.contentType(ContentType.JSON)
.body("{\"username\":\"admin\",\"password\":\"123\"}")
.when()
.post("/api/seller/login")
.then()
.statusCode(200);
}
@Test
void testLoginPage() {
Page page = browser.newPage();
page.navigate("http://localhost:5173/seller/login");
page.fill("input[name=username]", "admin");
page.fill("input[name=password]", "123");
page.click("button[type=submit]");
assertEquals("/seller/admin", page.url());
}
##### application-test.yml
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
| 用例编号 |
所属用例 |
前置条件 |
测试步骤 |
预期结果 |
实际结果 |
状态 |
| TC-001 |
UC-07 发布商品 |
卖家已登录,无在售商品 |
填名称+价格,点发布 |
商品创建成功,状态为在售 |
|
通过/失败 |
- 测试发现缺陷 → 在 GitHub Issues 登记,标签
bug,指派对应开发。
- 开发修复后关闭 Issue,测试回归验证。
- 回归通过则标记已修复;不通过则重新打开。
- 每次评审汇总缺陷数与修复率。
##### 1. 后端测试依赖(pom.xml)
##### spring-boot-starter-test(含 JUnit 5、Mockito)
##### rest-assured
##### h2
##### 2. UI 测试(单独模块或 e2e 目录)
##### com.microsoft.playwright:playwright
##### 3. 运行全部测试
mvn test
##### 4. 运行 UI 测试
mvn test -Dtest=UITests
| 风险 |
对策 |
| UI 测试不稳定(flaky) |
用 Playwright 自动等待,避免硬编码 sleep;失败重试机制 |
| 测试数据污染 |
集成测试用 H2 内存库,每个测试方法前清空表 |
| 接口字段变更导致测试失败 |
接口测试聚焦状态码与核心字段,避免断言过多非关键字段 |
| 测试覆盖率不足 |
迭代 6 引入 JaCoCo 统计覆盖率,目标 Service 层 > 80% |
(评审后填写)