# PetStore_test **Repository Path**: yaxy1234/pet-store_test ## Basic Information - **Project Name**: PetStore_test - **Description**: 本项目是对Swagger PetStore开放API进行的端到端接口测试实践。基于Pet、Store、User三大模块接口文档,设计并执行了221条测试用例。通过Postman实现自动化测试与数据驱动,成功发现并定位一个关键后端缺陷:添加宠物接口未校验状态枚举值,导致非法数据可入库。实践涵盖了从分析、设计、自动化执行到缺陷根因定位的全流程,为开放API测试提供了可复用的方法。 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-08 - **Last Updated**: 2026-10-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

其他平台链接:CSDN项目链接-PetStore接口测试项目实操

一、项目概览与准备工作

1.1项目地址

Swagger UI:https://petstore.swagger.io/

1.2 项目简介

PetStore是一个开放在线宠物商城API项目,提供宠物信息的增删改查功能。

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-03-30%20110410.png)
1.3 接口文档结构分析

三个模块:pet,store和user

二、接口分析与测试用例设计

2.1 先通过Swagger UI手动熟悉接口

目的:熟悉项目业务流程,再对齐编写用例

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-08%20202830.png)
2.2 测试分析-分析每一个接口的测试点
2.2.1Pet板块

网页接口展示:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-03-31%20195615.png)

测试点分析:

![输入图片说明](images/pet.png)
思考:存在必填项如何找测试点?
2.2.2Store板块

网页接口展示:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-03-31%20200533.png)

测试点分析:

![输入图片说明](images/store.png)
思考:数据组无约束必填项如何找测试点?
2.2.3user板块

网页接口展示:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-03-31%20200746.png)

测试点分析:

![输入图片说明](images/user.png)
详细测试点文件可展开详细查看

2.3测试点评审

此处参考deepseek给出的个人评审方法

评审维度检查问题缺失时怎么补
正常场景核心业务能走通吗?补充“所有字段完整”的用例
异常场景必填字段缺失能处理吗?补充不传必填字段的用例
边界值有测长度/数值上下限吗?name字段:空/1字符/500字符;id字段:0/负数/超大数
枚举值所有合法枚举都覆盖了吗?status字段补充available/pending/sold三种状态
字段类型传错误类型能处理吗?补充name传数字、id传字符串
业务逻辑接口之间有依赖关系吗?补充:新增后查询、删除后再查询、重复新增
幂等性同一请求重复发送结果一致吗?补充:连续两次POST相同数据
安全基础有考虑越权或SQL注入吗?(实习岗简单验证即可)补充:id传' OR '1'='1看是否会报错

XMind测试点评审清单

2.4测试用例的编写

测试用例文件

SwaggerPetStore测试用例下载

用例数共计:221个

ps:由于swagger网站对应的Swagger需求文档并不准确详细,所以对预期结果可能存在偏差

2.5测试用例的评审

此处依旧是参考deepseek给出的自我评审方法评审的,按照方法和对照测试点又对初始用例文档和测试点文档进一步修改,提高测试点的覆盖率和用例的完全覆盖

一、需求追溯矩阵法

将XMind中的每个测试点与Excel用例ID建立映射关系,逐条核对,确保测试点100%转化为可执行用例。未被匹配的即为遗漏项,立即补充。

价值:保证测试覆盖无盲区,实现“从测试点到用例”的完整追溯。

二、正交试验法

当存在多个字段组合时,通过正交表选取代表性组合进行测试,避免全排列组合导致的用例爆炸。在保证覆盖度的前提下,将用例数量控制在可执行范围内。

价值:平衡覆盖度与执行效率,用最少用例覆盖最多组合场景。

三、错误猜测法

基于接口测试的常见高发缺陷区域(空值处理、特殊字符、重复操作、资源不存在、并发冲突等),反向审视用例是否覆盖这些易错点,针对性补充遗漏场景。

价值:弥补结构化设计的盲区,捕捉经验型缺陷。

四、静置重审法

完成用例编写后静置24小时,切换至“评审者”视角重新审视。间隔时间有助于跳出创作惯性,发现初次编写时遗漏的场景或逻辑缺陷。

价值:简单高效,利用时间差实现自我纠偏。

Excel用例评审清单

三、Postman接口测试

3.1创建测试集

创建测试集:创建测试项目,或postman支持导入swagger文档
操作测试集功能:运行测试集-批量执行接口用例,编辑,增加请求,增加文件夹,复制,导出,删除

3.2 设置环境变量

环境变量设置:可以通过公共变量,快速切换生产环境和测试环境,提高测试效率

此处将公共url部分进行替换

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20123854.png)

使用{{baseUrl}}变量引用来替换接口的公共url部分

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20124050.png)

3.3添加断言

整体添加一个对于响应码是否为200的状态断言,可以作用于项目下的每一个接口

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20124403.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20132702.png)
3.4调试阶段

篇幅原因此处只展示pet部分

3.4.1uploads an image-添加文件附件

关键点:添加文件附件

在body部分选择file参数上传附件(如果要集成测试时,附件需要上传云端)

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20134547.png)
3.4.2Find pet by ID

正确请求可以返回一个JSON数据,所以可以使用断言对返回的JSON数据做一个结构完整性验证

根据返回的数据内容添加断言

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20135328.png)

执行结果:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20135412.png)
3.4.3Updates a pet in the store with form data-CSV数据驱动

两个需要填写的变量:name和status

但是实际上是三个变量还有一个petid

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20135800.png)

编写csv文件并且添加到Postman中

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20160709.png)

运行查看结果:

第一组和第三组失败,第二组成功,每组都有对应的响应状态码断言

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20160828.png)
3.4.4Deletes a pet-APIkey的使用认证

关键:使用API-key才能有删除权限

API Key 是最简单的 API 认证方式,通过一个唯一的标识符来识别和授权客户端。API Key 是一个唯一的字符串,用于:

API属于Authorization(授权),Authorization 用于验证发起请求的客户端是否有权限访问受保护的资源。有三种常见的传递方式:

位置示例优点缺点
HeaderX-API-Key: abc123最常用,符合HTTP规范需要修改请求头
Query Parameter?api_key=abc123简单,方便调试URL会被记录在日志中
CookieCookie: api_key=abc123浏览器自动携带仅适用于Web场景

在此处的api-key就是使用了第一种在Header中添加:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20141000.png)

对比使用正确的和错误的api-key的结果:

使用正确的api-key返回:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20141136.png)

无api-key或者错误api-key返回:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20141249.png)
3.4.5Finds Pets by status-返回数据很多是否添加断言,要怎么断言?

根据状态信息查找宠物的接口,正确返回的结果数据很多,所以我们是否可以通过断言来做一定的判断?

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20142258.png)

断言的必要性,如果存在下面的问题就会出现漏测的情况:
返回了错误状态的宠物(如 sold 混在 available 中)
响应时间过长(超过3秒)
返回的字段缺失(如部分宠物没有 photoUrls)
分页/限制失效(一次返回几千条)
数据结构被破坏(返回了字符串而非数组)

针对上面问题可以添加的一些断言——基础验证(响应码判断,响应时间判断,响应体JSON数据格式验证),数据结构验证,字段验证,状态匹配验证,抽样检测类型,以及可选将数据提取出来

使用deepseek帮助编写断言脚本,展开查看代码详细
// ============ 基础验证 ============
pm.test("Status code is 200", () => pm.response.to.have.status(200));
pm.test("Response time < 5000ms", () => pm.expect(pm.response.responseTime).to.be.below(5000));
pm.test("Response is valid JSON", () => {
    // 验证 Content-Type
    pm.response.to.be.json;
});

const pets = pm.response.json();

// ============ 结构验证 ============
pm.test("Response is array", () => pm.expect(pets).to.be.an("array"));
pm.test("Response is not empty (if expected)", () => {
    // 根据业务决定是否允许空数组
    const requestStatus = pm.request.url.query.get("status");
    if (requestStatus === "available") {
        // 如果业务上 available 状态一定有数据,才做此断言
        // pm.expect(pets.length).to.be.above(0);
    }
});

// ============ 字段验证 ============
const requiredFields = ["id", "name", "photoUrls", "status"];
pm.test("Each pet has required fields", () => {
    pets.forEach((pet, i) => {
        requiredFields.forEach(f => {
            pm.expect(pet).to.have.property(f, `Pet ${i} missing ${f}`);
        });
    });
});

// ============ 状态匹配验证(核心) ============
pm.test("Status matches query parameter", () => {
    const requestStatus = pm.request.url.query.get("status");
    const expectedStatuses = requestStatus ? requestStatus.split(",") : ["available", "pending", "sold"];
    
    pets.forEach(pet => {
        pm.expect(expectedStatuses).to.include(pet.status, 
            `Pet ${pet.id} has status "${pet.status}" but expected ${expectedStatuses.join(",")}`);
    });
});

// ============ 类型验证(抽样) ============
const sampleSize = Math.min(10, pets.length);
const samplePets = pets.slice(0, sampleSize);

pm.test("Sample pets have correct field types", () => {
    samplePets.forEach(pet => {
        pm.expect(pet.id).to.be.a("number");
        pm.expect(pet.name).to.be.a("string");
        pm.expect(pet.photoUrls).to.be.an("array");
    });
});

// ============ 性能监控 ============
console.log(`Query status: ${pm.request.url.query.get("status")}`);
console.log(`Returned ${pets.length} pets`);
console.log(`Response time: ${pm.response.responseTime}ms`);

// ============ 提取数据供后续使用 ============
if (pets.length > 0) {
    // 保存第一个宠物的 ID
    pm.environment.set("first_pet_id", pets[0].id);
    pm.environment.set("first_pet_name", pets[0].name);
    
    // 保存各状态的数量统计
    const statusCount = {
        available: 0,
        pending: 0,
        sold: 0
    };
    pets.forEach(pet => {
        if (statusCount[pet.status] !== undefined) {
            statusCount[pet.status]++;
        }
    });
    pm.environment.set("status_stats", JSON.stringify(statusCount));
}

断言结果:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20144029.png)

从结果可以看出,存在返回的字段缺失的情况,所以对此断言还是很重要

3.4.6Finds Pets by tags-关联接口出现问题

和上面的接口一样会返回很多数据,沿用上面的断言进行测试

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20150853.png)

结果发现对于响应时间超过5000ms,并且数据缺少必要字段,状态值也存在非枚举的情况。这也说明,在修改宠物状态的接口或者创建宠物状态的接口对于字段值的类型存在漏测或者bug的情况,导致在数据中出现类型不是所期待的。

前者可以将对相应时间的判断修改为一个动态的,后者需要审查相关联的接口问题。

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20151507.png)
3.4.7Add a new pet to the store-发现bug问题

接上一节出现非枚举类型的错误出现,在添加一个新的动物接口发现了问题的根源——在添加接口中,虽然对于status的说明和要求是“available,pending,sold”三选一,但是在输入非三者的字符串依然可以请求成功。

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20152526.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20152441.png)

这是一个后端问题:非枚举值被直接写入数据库,说明后端没有校验;OpenAPI 规范明确定义了枚举,后端未遵守。

如何区分是前端的问题还是后端的问题?

这种情况的产生会导致错误数据会污染数据库,影响报表和业务逻辑,以及恶意用户可以随意传入任意值,可能导致业务异常。

测试发现 Bug 后的完整工作流程

(1)复现确认

复现步骤:

1. 请求 URL: POST https://petstore.swagger.io/v2/pet
2. 请求体:
{
"name": "doggie",
"photoUrls": [
"string",
"string"
],
"id": 7440,
"category": {
"id": 2255,
"name": "string"
},
"tags": [
{
"id": 645,
"name": "string"
},
{
"id": 6967,
"name": "string"
}
],
"status": "abcdefg"
}
3. 实际响应:200 OK
4. 查询数据库:status = "abcdefg"

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20153604.png)

2.根因定位

3.影响范围评估

评估维度内容
直接影响status 字段可被任意值污染
间接影响按 status 查询接口异常、统计报表错误
影响范围POST /pet、PUT /pet 两个接口
数据风险已存在非法数据需清洗
安全风险中(可能用于注入)

4.记录与提交-缺陷管理系统的使用

打开禅道,在所属项目板块下,提交对应的bug,上传附件

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20155145.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20155320.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20155351.png)

5.沟通与跟进

缺陷认领->沟通确认->跟踪状态

6.验证与回归

验证修复->回归测试->数据一致性检查->关闭缺陷

7.总结与改进

补充测试用例->跟新测试资产->复盘总结

3.5思考与改进

在3.4.1-3.4.4四个部分中,都有重复使用petid这个变量,默认给出的是每个接口都定义一遍,可以改进为将petid定义为collection变量,在整个项目中直接使用,减少重复定义

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20161525.png)

在对应接口用{{petid}}引用变量

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-01%20161535.png)

四、Jmeter性能和压力测试

4.1确定被测接口
接口业务含义压测理由
GET /pet/{id}查询宠物读操作,高频场景
POST /pet新增宠物写操作,验证数据写入能力
GET /pet/findByStatus按状态查询列表查询,可能有性能瓶颈
4.2性能测试与负载压力测试

项目文件结构

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20211257.png)

在用户定义的变量中,定义一个作用于全局的bseUrl

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20211425.png)
4.2.1Finds Pets by status

GET请求,参数petid

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20100634.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20211706.png)

说明:

(1)基础性能执行结果:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20212213.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20212258.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20212316.png)

结果分析:

a.整体分析

b.异常分析

样本135和246请求失败,都返回
{
"code": 1,
"type": "error",
"message": "Pet not found"
}
样本123响应时间最长,2475ms;接口返回了 200 和正确数据,但不符合业务断言预期(缺少 status 字段),所以 jmeter 判定为失败。

(2)负载压力测试:(由于是公共网站,所以采用低并发、短时间)

并发设置:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20213557.png)

执行结果:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20213916.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20213947.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20214014.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20214040.png)

结果分析:

a.整体分析

b.分组分析

接口样本数平均响应(ms)最大响应(ms)异常率状态
通过ID寻找宠物-12315130359336.67%部分失败
通过ID寻找宠物-135158263833100%全部失败
通过ID寻找宠物-246159685095100%全部失败
通过ID寻找宠物-4561594125600%全部成功
通过ID寻找宠物-7891561119050%全部成功
调试取样器75010%正常

c.异常分析

接口 135 和 246 — 全部失败(各15个,共30个错误)
错误类型:HTTP 404 Not Found
原因:服务器返回"资源不存在"
结论:这两个宠物ID在服务器中不存在或已被删除,属于业务数据问题,非系统性能问题

接口 123 — 1个失败
错误类型:断言持续时间超时
具体信息:花费 5933 ms,超过限制 3000 ms
结论:该请求响应过慢,属于性能问题

注:31个错误 = 30个(135+246的404) + 1个(123超时)

d.性能分析

响应时间波动非常大

接口最小(ms)最大(ms)波动倍数
123241593324倍
135243383315倍
246242509521倍
456239256010倍
78924119057倍

结论:系统在并发压力下响应极不稳定,存在明显性能瓶颈。

e.吞吐量分析

4.2.2Add a new pet to the store

POST请求,参数是JSON数据

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20215636.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20215752.png)

说明:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20215837.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20095914.png)

(1)基础性能执行结果

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20220159.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20220230.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20220242.png)

a.整体分析

b.异常分析

无

(2)负载压力测试:

并发设置:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20220954.png)

执行结果:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20221405.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20221052.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20221122.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-02%20221517.png)

结果分析:

a.整体分析

b.分组分析

接口样本数平均(ms)最小(ms)最大(ms)标准偏差异常率
添加一个新的宠物-0155882251837533.400%
添加一个新的宠物-115126821653531264.576.67%
添加一个新的宠物-2159202152392791.610%
添加一个新的宠物-3156422153318794.766.67%
调试取样器600010.220%

c.异常分析

总错误数为2个,为添加一个新的宠物-1:1 个失败(6.67% 异常率)何添加一个新的宠物-3:1 个失败(6.67% 异常率),响应状态码为200说明请求成功只是不满足时间断言

d.性能分析

响应时间波动大

问题严重程度建议
存在 5353ms 超慢请求高排查该请求的服务器处理链路
响应时间波动巨大(25倍)高检查是否存在 GC 停顿、锁竞争、慢SQL
宠物-1 接口平均响应最慢中分析该请求的数据特征(如 id=1 是否有特殊逻辑)
异常率 1.67%低可接受,但需关注是否随并发升高而增加

结论:系统响应极不稳定,存在明显性能抖动。

4.2.3Finds Pets by status

GET请求,参数为status

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20095521.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20095451.png)

说明:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100017.png)

(1)基础性能执行结果

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100223.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100237.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100258.png)

a.整体分析

b.异常分析

无

(2)负载压力测试:

并发设置:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100756.png)

执行结果:

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100929.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100944.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20100959.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20101020.png)

结果分析:

a.整体分析

b.分组分析

状态样本数平均(ms)最小(ms)最大(ms)标准偏差异常率平均字节数
available202816138059131437.1130%41,242
pending20188856261461310.6810%20,504
sold204025195476691419.2675%61,171

性能排序(平均响应时间):sold(最慢)> available > pending(最快)

c.异常分析

各状态异常分布

状态异常率失败数严重程度
sold75%15/20 严重
available30%6/20 较高
pending10%2/20 较低

d.性能分析

响应时间波动极大

状态最小(ms)最大(ms)波动倍数
available138059134.3倍
pending562614610.9倍
sold195476693.9倍

响应时间与数据量关系

状态平均字节数平均响应(ms)单位数据耗时(ms/KB)
pending20,50418880.092
available41,24228160.068
sold61,17140250.066

发现:pending 状态虽然数据量最小,但单位数据耗时最高,说明其处理效率可能较低。

4.3输出报告
4.3.1采用命令行方式集成测试并输出报告
![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20103223.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20103306.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20103413.png)
4.3.2使用Jenkins集成测试并输出Allure报告

基础设置

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20104303.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20105601.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20105622.png)

Python执行脚本

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20104822.png)

执行

![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-03%20105727.png)

即可查看报告

此处我的Allure生成结果存在问题,无法显示数据,问题还在找中,锚定的几个方向:

- 相关jdk和python的路径配置path(已解决)
- 浏览器广告过滤器(已解决)
- allure-results和allure-report的路径配置(已排除)
- Python脚本本身的问题
- Allure为什么运行完测试就直接生成报告,不按照我的批处理命令继续执行python脚本对数据转化(在Allure平台中)
- 在本地手动执行批处理命令打开后依旧是空的?但是Python能将数据正确转换为JSON,并且data文件夹都是有数据的,只是在index.html显示空的(本地打开无法渲染,所以可能为空)

最后问题还是从本地回到了Allure平台本身,为什么无法执行完整的批处理就直接生成Allure报告?

还在思考和寻找解决中.......

有考虑使用Jmeter+Ant+Jenkins+Allure生成Allure报告,正在尝试中.......

五、总结与思考

5.1项目成果概述

本次对 PetStore 在线宠物商城 API 项目进行了完整的接口测试实践,覆盖了从测试分析、用例设计、接口调试到性能压测的全流程。项目主要成果包括:

模块成果
测试点分析覆盖 Pet、Store、User 三大模块,包含正常/异常/边界/枚举/依赖等维度
测试用例共编写 221 条 可执行用例,实现测试点 100% 追溯覆盖
Postman 自动化完成环境变量、断言、数据驱动、API Key 认证等关键场景调试
JMeter 性能测试对核心接口(查询/新增/按状态查询)完成负载与压力测试,发现性能瓶颈
5.2关键问题与解决方案
问题类型具体问题解决方法
必填项测试接口未明确标注必填字段通过错误猜测法 + 字段缺失组合设计用例
无约束字段所有字段均为非必填采用正交试验法减少组合爆炸,覆盖核心场景
返回数据量大断言难以逐条验证编写脚本验证结构、类型、状态匹配,并抽样检查
性能抖动响应时间波动达 25 倍,存在 7.6s 超时通过 JMeter 聚合报告定位慢接口,建议优化 SQL/GC
环境复用多接口重复定义 petid改为 Postman Collection 变量,统一管理
报告生成Allure 报告无法渲染定位为路径/浏览器/平台执行顺序问题,持续排查中
5.3 测试过程中发现的典型缺陷
缺陷接口严重程度根因
status 字段可传入任意非枚举值POST /pet中后端缺少枚举校验
部分宠物缺少 photoUrls 字段GET /pet/{id}低数据写入不完整
响应时间超过 5000msGET /pet/findByStatus高查询性能瓶颈
5.4个人成长与思考

六、项目笔记

6.1测试点部分

测试点中存在几种特殊的考虑情况:

(1)存在必填项要怎么做?-pet部分的测试点

(2)没有必填项要怎么做?-store部分的测试点

6.2测试用例部分

(1)实际结果与预期结果不符合怎么办?/发现bug了要怎么做?

发现不符 → 复现确认 → 记录问题 → 分析定位 → 提交缺陷 → 跟踪修复 → 回归验证

复现确认问题测试环境是否正确,测试数据是否正确,查看断言,是否是偶发问题(偶发也需要记录)等;

搜集数据需要搜集请求四要素,响应四要素,以及断言结果,环境配置和日志等信息;

分析定位,初步判断问题是前端还是后端;

跟踪和回归,需要在开发修复完,在相同环境、相同数据下执行回归测试

(2)怎么判断bug是前端还是后端?

判断前后端问题通常依赖对系统架构、业务流程和错误日志的深入理解。

错误消息和日志:

通过查看浏览器控制台的网络请求和响应信息,后端日志文件,可以初步判断问题的位置。比如,请求返回404或500,问题大概率在后端。

功能逻辑:

根据逻辑功能和业务流程,分析定位哪个环节出现问题。比如,数据展示失败,可能是前端渲染;数据处理或存储,可能是后端问题。

开发环境和工具:

使用开发环境和功能调试,模拟请求和查看响应帮助定位问题分析。比如,使用浏览器的开发者模式,或者在postman中模拟请求。

团队协作:

沟通合作,共同分析问题根源。

(3)bug的生命周期

新建New-确认Confirmed-指派Assigned-修复Fixed-验证Verified-关闭Closed

6.3postman接口功能测试部分

(1)PathVariables的必填项petid定义和用法设置,如何去优化?

多个接口都要使用petid的话,可以将petid作为集合变量或全局变量使用。多种变量对比:

变量类型作用范围生命周期优先级典型用途
全局变量所有 Collection、环境、请求持久化(直到手动删除)最低跨环境共享的数据
环境变量特定环境持久化中区分开发/测试/生产环境
集合变量特定 Collection持久化中集合内共享的数据
局部变量单个请求或脚本临时(仅当前执行)最高临时计算、数据传递
数据变量数据文件中的一行临时(单次迭代)最高CSV/JSON 数据驱动

(2)api-key的作用和方式

API Key 是最简单的 API 认证方式,通过一个唯一的标识符来识别和授权客户端。API Key 是一个唯一的字符串,用于:

API属于Authorization(授权),Authorization 用于验证发起请求的客户端是否有权限访问受保护的资源。有三种常见的传递方式:

位置示例优点缺点
HeaderX-API-Key: abc123最常用,符合HTTP规范需要修改请求头
Query Parameter?api_key=abc123简单,方便调试URL会被记录在日志中
CookieCookie: api_key=abc123浏览器自动携带仅适用于Web场景

(3)返回数据很多,是否要断言,如何断言?

要断言,但是需要改变断言策略——从验证具体数据转为验证结构、规则和抽样。

首先,基础的断言需要有,比如响应状态码的判断,返回数据类型是否符合要求,响应的时间长短等;其次,验证字段类型和有效性,也还可以抽样对数据验证;最后,根据业务逻辑可以验证接口的逻辑是否符合需求等。

6.4jmeter接口性能测试部分

(1)请求数据为JSON需要加一个请求头告诉请求是JSON数据

服务器不会"猜测"请求体的格式,必须通过请求头明确告知。

当发送一个 POST 请求,Body 里放着 {"name":"doggie"},服务器看到的是一串字节流。它需要知道:

HTTP 协议规定:客户端通过 Content-Type 请求头告诉服务器答案。

常见 Content-Type 对照表

Content-Type请求体格式服务器解析方式
application/json{"key":"value"}JSON 解析器
application/x-www-form-urlencodedkey1=value1&key2=value2URL 解码,转键值对
multipart/form-data带边界分隔符的混合内容文件上传解析器
text/plain纯文本字符串直接当字符串
application/xml<root><key>value</key></root>XML 解析器

在Postman中会在选择数据类型时自动为接口添加,但是在Jmeter中需要手动添加

6.5遗留的问题

(1)使用Jenkins集成测试或者本地终端集成测试生成的Allure报告打开后没有数据?

此处我的Allure生成结果存在问题,无法显示数据,问题还在找中,锚定的几个方向:

- 相关jdk和python的路径配置path(已解决)
- 浏览器广告过滤器(已解决)
- allure-results和allure-report的路径配置(已排除)
- Python脚本本身的问题
- Allure为什么运行完测试就直接生成报告,不按照我的批处理命令继续执行python脚本对数据转化(在Allure平台中)
- 在本地手动执行批处理命令打开后依旧是空的?但是Python能将数据正确转换为JSON,并且data文件夹都是有数据的,只是在index.html显示空的(本地打开无法渲染,所以可能为空)

最后问题还是从本地回到了Allure平台本身,为什么无法执行完整的批处理就直接生成Allure报告?

还在思考和寻找解决中.......

有考虑使用Jmeter+Ant+Jenkins+Allure生成Allure报告,正在尝试中.......