# xzs-api-test **Repository Path**: liu66547/xzs-api-test ## Basic Information - **Project Name**: xzs-api-test - **Description**: 学之思开源考试系统接口自动化测试项目,基于 TestNG + RestAssured 实现 API 自动化。 被测系统仓库: https://gitee.com/mindskip/xzs-mysql https://github.com/mindskip/xzs-mysql - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-15 - **Last Updated**: 2026-09-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

xzs-api-test

学之思考试系统(MySQL 版) · 管理端接口自动化测试

Java 8 Maven TestNG RestAssured Allure Jenkins

Coverage 21/21 Tests 35 Passed Data Zero Residue

GitHub 仓库 · Gitee 仓库

--- > 基于 **Java + RestAssured + TestNG** 构建的接口自动化测试工程:以学之思(xzs)开源考试系统管理端为被测对象,覆盖 **21 个接口**;测试数据全链路自造、执行后零残留;产出缺陷与系统级质量观察;配套 Allure 报告与 Jenkins 持续集成。 ## 目录 - [1. 项目简介](#1-项目简介) - [2. 技术栈](#2-技术栈) - [3. 架构设计与项目结构](#3-架构设计与项目结构) - [4. 测试设计原则](#4-测试设计原则) - [5. 接口覆盖矩阵(21/21)](#5-接口覆盖矩阵2121) - [6. 缺陷与系统级发现](#6-缺陷与系统级发现) - [7. 如何运行](#7-如何运行) - [8. 持续集成与测试报告](#8-持续集成与测试报告) - [9. 已知限制与后续规划](#9-已知限制与后续规划) - [10. 项目声明](#10-项目声明) ## 1. 项目简介 **被测系统**:学之思开源考试系统(xzs)——基于 Spring Boot 的在线考试系统,含管理端与学生端。 **测试范围**:管理端(admin)REST API,6 个模块、21 个接口:登录 / 登出、学科、题目、任务、试卷、答卷。 **项目目标**: - 完整走通接口自动化测试工程链路:分层设计 → 造数链路 → 断言体系 → 清理策略 → 报告 → CI; - 在实践中检验测试设计方法论:过滤验证双侧证据、契约型 / 记录型断言、数据治理规范; - 以黑盒为主、白盒(日志 / 表结构)为辅,对发现的异常完成"定性分级"(缺陷 / 系统级观察 / 设计特性)。 **成果概览**: | 指标 | 结果 | | --- | --- | | 接口覆盖 | 21 / 21(100%) | | 用例规模 | 35 条(失败 0) | | 环境依赖 | 0 —— 测试数据由用例现场自造,clone 后可直接运行 | | 数据残留 | 0 —— 全套执行后 `zz_%` 前缀对账为空 | | 持续集成 | Jenkins 构建 #20 全绿(2026-09-26),Allure 报告与 JUnit 结果自动归档 | ## 2. 技术栈 | 类别 | 选型 | | --- | --- | | 语言 / 构建 | Java 8 / Maven | | 测试框架 | TestNG | | 接口调用 | RestAssured | | 断言 | Hamcrest | | 测试报告 | Allure 2 + Surefire | | 持续集成 | Jenkins(Declarative Pipeline) | | 版本管理 | Git(GitHub / Gitee) | ## 3. 架构设计与项目结构 **四层分层,职责单一:** | 分层 | 核心类 | 职责 | | --- | --- | --- | | 用例层 | `XxxTest` | 测试意图:造数 → 调用 → 断言 → 清理注册 | | 接口层 | `XxxApi` | HTTP 封装:路径 / 参数 / 请求发送 | | 造数层 | `CreateData` | 数据工厂:`subject → question → paper → task` 逐级组合 | | 基础层 | `RequestUtil` / `SessionManager` / `CleanupRegistry` 等 | 会话管理、请求公共处理、栈式清理、登录态前置 | **项目结构:** ```text xzs-api-test/ ├── pom.xml ├── testng.xml # 测试套件(按类并行) ├── Jenkinsfile # Jenkins 流水线定义 └── src/test/ ├── resources/ │ ├── config.properties # base.uri、admin 账号密码 │ └── allure.properties └── java/com/xzs/ ├── api/ # 接口封装层,一个类对应一个模块 │ ├── LoginApi / SubjectApi / QuestionApi │ └── TaskApi / PaperApi / ExamPaperAnswerApi ├── common/ │ ├── ConfigReader # 读取配置文件 │ ├── SessionManager # 登录态管理(ThreadLocal 存 JSESSIONID) │ ├── RequestUtil # 请求公共处理 │ └── CleanupRegistry # 清理注册表(栈式逆序清理) ├── data/ │ └── CreateData # 测试数据工厂:造学科 / 题目 / 试卷 / 任务 └── test/ # 测试用例 ├── BaseTest / PreLoginInBaseTest ├── LoginTest / LogoutTest ├── SubjectTest / QuestionTest └── TaskTest / PaperTest ``` **关键设计说明:** 1. **接口层与用例层解耦**:接口变更只需修改 Api 类,用例零感知; 2. **CleanupRegistry 栈式清理**:按"造数即注册"顺序入栈,`@AfterMethod / @AfterClass` 逆序执行——天然满足"下游先删、上游后删"的依赖顺序,把规则内化进数据结构; 3. **造数链自给自足**:`CreateData` 支持 `subject → question → paper → task` 逐级组合,已消除对任何环境预置数据的依赖;如 task 用例现场自造"学科 → 题目 → 试卷 → 任务"全链; 4. **参数化环境**:`base.uri` 通过 `-Dbase.uri=` 注入,本地 / 测试 / 预发一键切换。 ## 4. 测试设计原则 - **过滤验证黄金法则**:每个过滤条件必须给出"阳性(该来的来了)+ 阴性(不该来的没来)"双侧证据; - **契约型 vs 记录型断言**:主键唯一查询断言"恰好一条"(契约型);对系统数据现状(如答卷表为空)采用记录型断言锁定现状,现状变化即产生告警; - **同通道对照**:删除 / 编辑前后的对照必须走同一查询通道、同一参数口径,避免口径差异导致假绿; - **禁止条件断言**:断言不允许藏在不被验证的 `if` 条件里——前提破坏时用例会静默通过; - **禁裸字面量**:断言中的期望值必须来自变量或本用例刚造的数据,杜绝与环境数据巧合耦合; - **数据治理规范**:测试数据统一 `zz_` 前缀 + 时间戳保证唯一;执行后以 SQL 对账(`zz_%` 且 `deleted=0` 应为空)验收清理效果。 ## 5. 接口覆盖矩阵(21/21) | 模块 | 接口数 | 覆盖 | 重点场景 | | --- | --- | --- | --- | | 登录 / 登出 | 2 | ✅ | 会话保持、登录态前置 | | 学科 subject | 5 | ✅ | 增删改查、分页过滤、删除可见性 | | 题目 question | 4 | ✅ | 题型分支与校验差异、分页过滤、编辑字段可变性 | | 任务 task | 4 | ✅ | 分页过滤、引用 + 派生结构、换试卷编辑 | | 试卷 exam/paper | 5 | ✅ | 嵌套组卷(`titleItems → questionItems`)、任务选卷查询 | | 答卷 examPaperAnswer | 1 | ✅(结构级) | 连通性 + 空集契约(理由见第 9 节) | | **合计** | **21** | **100%** | — | ## 6. 缺陷与系统级发现 > 全部发现均经可复现实验确认(请求 / 响应、后端异常堆栈、SQL 日志已留存)。 ### 6.1 缺陷候选(可复现) | # | 描述 | 证据 | | --- | --- | --- | | 1 | 编辑不存在的资源,错误处理三极不一致:学科编辑静默返回"成功";试卷编辑直接 NPE 500;无明确业务错误码 | 实测 + 后端堆栈 | | 2 | 引用完整性校验缺失,异常延迟到"使用点"以 500 崩溃:任务引用不存在的试卷、试卷引用不存在的题目 / 学科等 | 4 组堆栈(如 `savePaperFromVM:105`、`levelBySubjectId:47` NPE) | | 3 | 关键枚举 / 值域零校验:`questionType=999`、`gradeLevel=999` 等非法值静默入库 | 实测 | | 4 | 同类字段空值校验不一致:多选题 `items` 为空 → 500 兜底;单选题 `items` 为空 → 接受 | 对照实测 | | 5 | 删除后文本内容表(`t_text_content`)残留孤儿数据 | SQL 实证 | | 6 | 错误信息质量三级并存:字段级精准 501 / 框架级 500 / 静默成功——同一系统三张脸 | 全程采集 | ### 6.2 系统级一致性观察 | # | 观察 | | --- | --- | | 1 | "已删过滤"三层不统一:分页查询过滤已删;按 id 查询(select)不过滤已删;联表读取不过滤已删(软删试卷仍可被任务引用并读回)。学科 / 题目 / 任务 / 试卷四模块复现 | | 2 | 请求 / 响应共用 DTO:响应中的只读派生字段(如任务 `paperItems.name`、`frameTextContentId`)在契约上表现为"可填",实际写入被忽略 | | 3 | 主键查询 SQL 不带 deleted 过滤(`selectByPrimaryKey` 系列) | ### 6.3 设计特性确认(经实验验明为正身,避免误报) - **引用 + 派生结构家族**:`paperItems` / `questionItems` 中唯一有效字段为 `id`,其余字段读时联表派生(传任意值被静默忽略); - **可变性图谱**:question 的 `questionType` / `gradeLevel` 不可改(静默忽略),`title` / `subjectId` / `correct` 可改;paper 全字段可改(含换学科并重算 level、换题);task 可换试卷; - **写时类型宽容**:score 传数字 / 字符串均可; - **软删数据可被引用**:如题目可引用软删学科。 ### 6.4 值得肯定的设计 - 501 字段级校验文案精确到字段路径(如 `titleItems[0].questionItems[0].score : 不能为空`)——错误信息标杆; - 事务兜底:编辑中途异常自动回滚,不留半截脏数据; - 分页输出结构全站统一(MyBatis 分页插件),空集形状一致。 ## 7. 如何运行 **前置条件**:JDK 8+、Maven 3.x、本地已启动的 xzs 服务(默认 `http://localhost:8000`)及 MySQL。 ```bash # 全量执行(默认 base.uri = http://localhost:8000) mvn clean test # 指定被测环境 mvn clean test -Dbase.uri=http://test.example.com:8000 # 单模块执行 mvn test -Dtest=TaskTest # 查看 Allure 报告 allure serve target/allure-results ``` **数据对账**(执行后应全部为 0 行): ```sql SELECT id FROM t_subject WHERE name LIKE 'zz_%' AND deleted = 0; SELECT id FROM t_question WHERE title LIKE 'zz_%' AND deleted = 0; SELECT id FROM t_exam_paper WHERE name LIKE 'zz_%' AND deleted = 0; SELECT id FROM t_task_exam WHERE title LIKE 'zz_%' AND deleted = 0; ``` ## 8. 持续集成与测试报告 **Jenkins Declarative Pipeline**(仓库根目录 `Jenkinsfile`): - **参数化构建**:`BASE_URI` 下拉多环境选择(本地 / 测试 / 预发),一套用例多环境执行; - **触发策略**:SCM 轮询(每小时)+ 夜间定时构建(每日); - **构建与测试**:`mvn clean test -Dbase.uri=${BASE_URI}`; - **报告归档**:JUnit 结果(Surefire XML)与 Allure 报告自动发布;Allure 报告同时打包为构建工件(`allure-report.zip`)可直接下载; - **通知**:构建失败发送告警邮件;由失败恢复正常时发送恢复通知(状态未变化不打扰),通知邮箱:2746167445@qq.com。 > **最近构建**:#20(2026-09-26)全绿——35 条用例 0 失败,Allure Report 与 Tests 结果页均已归档。 **Allure 报告**:按 Epic / Feature / Story 分层组织,标注 Severity;本地查看方式见第 7 节。 ## 9. 已知限制与后续规划 1. **答卷模块为结构级覆盖**:答卷数据由学生端"考试提交"流程产生,管理端无造数通道;后续可扩展学生端"开考 → 交卷 → 成绩"全流程用例; 2. **CI 运行形态**:当前 Jenkins 与被测服务均为本地 / 内网环境(Windows 节点);后续规划将被测服务容器化(Docker Compose),实现任意环境一键全链路回归; 3. **后续方向**:业务流联动用例(一条流程串联多接口)、被测服务日志自动关联到测试报告。 ## 10. 项目声明 - **项目成员**:本项目为个人独立项目,全部架构设计、编码实现、用例执行、缺陷发现与文档撰写均由本人独立完成,无其他协作成员; - **关于 AI 工具的使用**:本 README 依据作者在测试过程中沉淀的缺陷发现与复盘记录整理成文,部分行文经 AI 工具辅助润色;测试代码、缺陷定位、实验数据、缺陷证据与结论均来源于本人的实际测试过程。 ---

作者:刘德啉
GitHub:liu66547 / xzs-api-test · Gitee:liu66547 / xzs-api-test
联系邮箱:2746167445@qq.com