Jmeter执行接口自动化测试-如何初始化清空旧数据

  • 需求分析:
  1. 每次执行完自动化测试,我们不会执行删除接口把数据删除,而需要留着手工测试,此时会导致下次执行测试有旧数据
  2. 我们手工可能也会新增数据,导致下次执行自动化测试有旧数据

下面介绍两种清空数据的方法

一、通过获取total数值进行清空
1. 实际页面、查询接口地址如下,页面有分页统计功能,能获取到总条数


2. 首先需要添加查询接口获取总条数number,如下所示

3. 在接口管理层级下新增一个循环控制器,用来控制循环的次数,变量为上个查询接口获取的number,如下所示

4. 接着在删除检查数据层级下新增一个查询接口(该接口地址和获取number变量一样),用来获取delete_id,如下所示


5. 接着新增一个删除接口,把获取的delete_id变量参数化到删除接口中
6. 执行结果如下:

7. number变量获取方法如下:

8. delete_id变量获取方法如下,每次获取第一个数值,直到循环结束:
 二、通过获取jmeter变量matchNr进行清空
1. 实际页面、查询接口地址如下,页面没有分页查询功能,无总条数,可以通过jmeter的json path匹配变量获取总条数


2. 首先需要添加查询接口获取总条数assignment_id_matchNr,如下所示


3. 在接口管理层级下新增一个循环控制器,用来控制循环的次数,变量为上个查询接口获取的assignment_id_matchNr,如下所示
4. 接着在循环控制器层级下新增一个查询接口(该接口地址和获取assignment_id_matchNr变量一样),用来获取delete_id,如下所示


5. 接着新增一个删除接口,把获取的delete_id变量参数化到删除接口中

6. 执行结果如下

三、数据安全校验

目前很多系统都是项目型,通过projectid去筛选查询接口,查询出自己需要的项目数据,其中就涉及到接口的安全测试,如果传的projectid为空,可能就会返回系统全部的数据,这种接口是有问题的,如果应用到循环删除中,就可能导致生产事故
1. 传正常的projectid,返回结果正常


2. 传projectid=null,返回系统所有数据

 

3. 怎样规避这种风险,可以增加个if控制器判断,只有project等于某个值(自己测试的项目)才能执行自动清除数据接口,project_check定义在全局变量中,跟着环境走,如下所示

 

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取

<think>嗯,用户需要的是如何使用JMeter配置批量请求,每个请求体包含100条CSV数据的方法。从用户引用的站内资料来看,ta已经掌握了基础的单条数据参数化操作(比如CSVDataSetConfig组件),现在需要扩展为批量处理。用户可能正在做接口压力测试,比如需要模拟批量提交订单或批量创建用户。这类场景的特点是:单次请求需要携带大量数据,但传统参数化只能逐行读取CSV。用户引用[4]提到JSR223脚本和结果存储,说明ta可能还关心结果收集效率。需要解决的核心问题是:如何将100行CSV数据合并为一个请求体。现有组件无法直接实现,得用脚本处理。比较合理的方案是参考用户引用[4]的Groovy脚本思路,但需要改造为累加多行数据。另外用户没提数据是否需要去重或特殊排序,暂时按顺序累加处理。线程组循环控制是个易错点:CSV默认逐行读取,但我们需要每100行才发一次请求。所以循环次数应该是总行数/100,这个计算逻辑最好在脚本里自动处理。用户引用[5]的RecycleonEOF参数也要注意,防止数据不足100时出错。响应数据量大的话,直接存CSV可能影响JMeter性能,要提醒用户控制结果保存字段。另外批量请求失败时的排查更困难,建议ta先在少量数据(比如10条)验证脚本逻辑。</think> 好的,下面讲解如何使用 JMeter 读取 CSV 文件,并将每 **100 条数据组合成一个请求体** 进行批量请求的配置方法。 **核心思路:** 1. 使用 **CSV Data Set Config** 逐行读取 CSV 文件中的单条数据。 2. 使用 **JSR223 脚本(推荐 Groovy)** 或 **BeanShell Sampler** 收集一定数量的行(本例中是 100 行),并将这些数据组装成最终需要的大请求体。 3. 使用一个 **控制器**(如 While Controller 或 Loop Controller)配合计数器来控制收集多少条数据组装一次请求。 4. 配置 **HTTP 请求** 来发送组装好的大请求体。 5. (可选)保存批量请求的结果。 **详细配置步骤:** ### 1. 准备 CSV 文件 * 确保你的 CSV 文件包含所需的数据字段,例如:`id,name,limit,status` 等。 * 文件第一行通常定义为列名(Header)。例如: ```csv userId,userName,email,productId 1001,UserA,a@example.com,P001 1002,UserB,b@example.com,P002 1003,UserC,c@example.com,P003 ... (至少准备 100 行或更多) ``` * **重要:** 确认文件编码(通常 UTF-8)和分隔符(通常逗号 `,`)。 ### 2. 添加线程组 * 右键点击 `测试计划` -> `添加` -> `线程(用户)` -> `线程组`。 * 设置 `线程数 (Users)`: 你需要发起多少个 *批量请求*。例如,如果你有 1000 条记录,每组 100 条,那么需要 10 次批量请求,设置`线程数`为 `10`。 * 设置 `循环次数`: `1` (我们通过脚本内部计数来控制读 100 行发一次)。 ### 3. 添加 CSV Data Set Config * 右键点击 `线程组` -> `添加` -> `配置元件` -> `CSV 数据文件设置`。 * 配置如下: * **文件名 (Filename):** CSV 文件的 *完整路径* (或相对于 JMeter 脚本的路径)。 * **文件编码 (File Encoding):** 与 CSV 文件一致 (如 `UTF-8`)。 * **变量名称 (Variable Names):** CSV 文件 *列名* 对应的 JMeter 变量名,**以逗号分隔**。例如 `csv_userId,csv_userName,csv_email,csv_productId`。JMeter 会按行读取文件,并将每一列的赋给对应的变量。 * **忽略首行?(Ignore first line):** `True` (如果 CSV 有标题行)。 * **分隔符 (Delimiter):** CSV 实际使用的分隔符,如 `,`。 * **遇到文件结束符再次循环?(Recycle on EOF):** `True` (如果测试数据不足且需要循环使用)。 * **遇到文件结束符停止线程?(Stop thread on EOF):** `False`。 * **变量名称是否共享?(Sharing mode):** `All threads`(通常情况)。 [^1][^2][^5] ### 4. 添加计数器 (Counter) * 右键点击 `线程组` -> `添加` -> `配置元件` -> `计数器`。 * **目的:** 在脚本中知道我们当前收集到了第几条数据(准备凑齐 100 条发一次)。 * 配置如下: * **起始 (Start):** `1` * **最大 (Maximum):** `100` (每次批量请求收集的数据条数) * **引用名称 (Reference Name):** 给计数器一个变量名用于后续脚本访问,例如 `itemCount`。 * **每次迭代后递增?(Increment each iteration?)** 保持默认勾选。 ### 5. 添加 While Controller * 右键点击 `线程组` -> `添加` -> `逻辑控制器` -> `While Controller`。 * **目的:** 控制循环读取 CSV 文件,直到收集满 100 条数据(或者文件尾)。其条件基于计数器和 CSV 文件是否还有数据。 * **条件 (Condition):** 输入 `"${__jexl3("${itemCount}" != "${itemCount_max}" && "${csv_userId}" != "<EOF>",)}"}` * **解释:** * `"${itemCount}" != "${itemMax}"`:判断计数器当前是否还没达到最大 100 (即还没收集满 100 条)。 * `&&`:并且。 * `"${csv_userId}" != "<EOF>"`:判断 CSV 文件是否没有读到结尾(CSV Data Set Config 在读取完所有行后,会将变量设置为 `<EOF>`)。 ### 6. 添加 JSR223 采样器 (或 BeanShell 采样器) - *收集单行数据* * 右键点击 `While 控制器` -> `添加` -> `取样器` -> `JSR223 Sampler`(选择 Groovy 语言)。 * **目的:** 在循环内部,每次读取 CSV 文件的一行数据,并将该条数据存储到一个列表变量(`itemsList`)中。同时更新计数器。 * 编写 **Groovy 脚本**: ```groovy import org.apache.jmeter.threads.JMeterContextService; // 1. 获取当前线程的变量空间 def ctx = JMeterContextService.getContext(); def vars = ctx.getVariables(); // 2. 初始化存储数据行的 List (每次批量请求开始时,List 应该是空的) // 利用 vars.getObject("itemsList") 或直接操作 vars.putObject if (vars.get("itemCount") == "1") { // 如果是本次批量请求的第一条数据 vars.putObject("itemsList", new java.util.ArrayList()); // 新建一个空 List } // 3. 获取当前行读取的 CSV 变量 // 假设 CSV 列名对应的变量名如配置: csv_userId, csv_userName, csv_email, csv_productId def currentItem = [ userId: vars.get("csv_userId"), userName: vars.get("csv_userName"), email: vars.get("csv_email"), productId: vars.get("csv_productId") ]; // 4. 将当前行数据 Map 添加到 itemsList 中 def itemsList = vars.getObject("itemsList"); itemsList.add(currentItem); vars.putObject("itemsList", itemsList); // 更新回变量空间 // 5. 增加计数器 (这一步由计数器本身自动完成,脚本里通常不需要操作,但可以获取其记录日志) def currentCount = vars.get("itemCount").toInteger(); // 6. 模拟执行一次采样器 (如果脚本作为采样器存在,需要有有效的 SampleResult) SampleResult.setResponseData("Collecting item ${currentCount}", "UTF-8"); // 重要:确保 While Controller 能继续进行下一次迭代(计数器自增在下一次迭代前自动发生) ``` * **关键点:** * 使用 `vars.putObject("itemsList", ...)` 和 `vars.getObject("itemsList")` 来存储和操作复杂的 List 对象。 * `if (vars.get("itemCount") == "1")` 确保在收集第一条数据初始化 `itemsList`。 * 每次迭代创建一条数据的 `Map` (`currentItem`) 并加入 `itemsList`。 * `SampleResult.setResponseData(...)` 确保脚本能返回一个有效结果。 [^3] (概念相关: 循环控制) ### 7. 添加 JSR223 PostProcessor - *组装批量请求体并清除临时数据* * 右键点击 `While 控制器` -> `添加` -> `后置处理器` -> `JSR223 PostProcessor`(选择 Groovy 语言)。 * **位置:** 放在 `While 控制器` 内部的 **最后面**(在 JSR223 采样器之后,但在退出 `While 控制器` 之前)。 * **目的:** 1. 在收集完一批数据(100 条)退出 `While 控制器` 后,将 `itemsList` 中的数据组装成最终的批量请求体(通常是 JSON 或 XML 格式字符串)。 2. 将组装好的请求体字符串放入一个 JMeter 变量(如 `batchRequestBody`),供后面的 HTTP 请求使用。 3. 清空 `itemsList` 和计数器变量(可选,但建议做,为下一次批量请求做准备)。 * 编写 **Groovy 脚本**: ```groovy import groovy.json.JsonOutput // 1. 获取存储的数据行 List def itemsList = vars.getObject("itemsList"); if (itemsList == null || itemsList.isEmpty()) { log.error("ItemsList is empty! Batch request body cannot be generated."); vars.put("batchRequestBody", '{"error": "No items collected"}'); // 或者可以考虑设置一个标记跳过 HTTP 请求 return; } // 2. 根据 API 要求的格式,组装批量请求体 // 示例: 生成一个包含 itemsList 中所有对象的 JSON 数组 def batchPayload = [ data: itemsList // 假设 API 要求的数据字段名是 "data" ]; // 使用 JsonOutput 将 Groovy Map/List 转换为 JSON 字符串 def jsonPayload = JsonOutput.toJson(batchPayload); def prettyPayload = JsonOutput.prettyPrint(jsonPayload); // 美化可读,可选 // 3. 将 JSON 字符串放入 JMeter 变量 vars.put("batchRequestBody", prettyPayload); // 或者直接用 jsonPayload // 4. (重要) 清除临时变量,为下一次批量请求做准备 (放在线程组下的计数器负责重置计数) // 方法 1: 清除 itemsList 对象 // vars.putObject("itemsList", null); // 可以但可能不够彻底 // 方法 2: 更安全移除变量 vars.remove("itemsList"); // 如果需要,也可以在这里重置计数器到起点(虽然计数器配置元件默认行为是每次迭代重置) // vars.put("itemCount", "1"); ``` * **关键点:** * 使用 Groovy 的 `JsonOutput` 方便地转换对象为 JSON。 * 脚本逻辑执行在 `While 控制器` 的循环结束后(即达到 100 条或文件尾)。 * 组装好的请求体字符串放入 `batchRequestBody` 变量。 * **强烈建议清除 `itemsList` 变量 (`vars.remove("itemsList")`)**,避免影响下一次迭代。 ### 8. 添加 HTTP 请求 * 右键点击 `线程组` -> `添加` -> `取样器` -> `HTTP 请求`。 * **配置:** * **协议**: `http` 或 `https` * **服务器名称或 IP**: API 服务地址。 * **端口号**: API 端口(如有)。 * **方法**: 通常是 `POST` 或 `PUT` (用于批量创建/更新)。 * **路径**: API 端点路径。 * **请求体:** (关键) * 切换到 `Body Data` 标签页。 * 将上一步 `JSR223 PostProcessor` 生成的 `batchRequestBody` 变量填入: `${batchRequestBody}` * **请求头:** * 切换到 `消息头管理器`,添加必要的 Header,特别是: * `Content-Type: application/json` (如果请求体是 JSON) * `Authorization: Bearer <token>` (如果需要认证) * 其他 API 要求的 Header。 ### 9. (可选) 添加监听器保存结果 * 右键点击 `线程组` -> `添加` -> `监听器` -> `用表格查看结果` (查看概要)。 * 右键点击 `线程组` -> `添加` -> `监听器` -> `保存响应到文件`。**注意:** 如果批量返回的数据很大,保存到文件可能会影响性能并生成庞大的结果文件。仅在有明确分析需求时使用。 * 更常见的做法是使用 **Simple Data Writer** 保存关键响应信息到 CSV: * 右键点击 `线程组` -> `添加` -> `监听器` -> `Simple Data Writer`。 * 配置 `文件名`。 * 勾选你感兴趣的字段,如 `timeStamp`, `elapsed`, `label`, `responseCode`, `responseMessage`, `failureMessage`, `bytes`, `isSuccess`, `requestData`, `responseData` (注意 `responseData` 通常很大)。 * 设置 `Separator` (如 `,`)。 * 如果使用 `保存响应到文件`,可以在文件名中使用变量(如 `${__time()}`)避免覆盖: * 在 `保存响应到文件` 的 `File` 字段填入类似:`results/Batch_Response_${__time(yyyyMMdd-HHmmss)}.dat`。 [^4] ## 工作流程总结 1. 线程组初始化,启动指定线程数(批量请求次数)。 2. 每个线程开始执行: * 计数器初始化为 1。 * 进入 `While 控制器`。 * *条件检查*:计数器 `< 100` *且* CSV 数据有效 (`!= <EOF>`)? * *条件为真*: * 执行 `JSR223 采样器`:将 CSV 读取的当前行存储到 `itemsList` (List 中)。 * 计数器自增(自动)。 * 回到循环条件检查。 * *条件为假*(计数器到 100 或文件尾):退出 `While 控制器`。 * 执行 `JSR223 PostProcessor`: * 将 `itemsList` 中的数据组装成 JSON (或其他格式) 的 `batchRequestBody` 字符串。 * 清除 `itemsList` 变量。 * 执行 `HTTP 请求`:将 `${batchRequestBody}` 作为请求体发送。 * 处理并记录响应(可选)。 * 线程结束。 ## 注意事项 1. **文件尾处理:** 逻辑需要能处理文件结尾时不足 100 条数据的情况(`While` 条件中的 `<EOF>` 判断会保证即使不足 100 条也正常退出循环并生成请求体)。 2. **性能:** `While 控制器` + Groovy 脚本本身会有一定开销。对于极高并发的压测场景,需评估是否成为瓶颈。 3. **内存:** 脚本中在内存中累积 `itemsList`。每组 100 条数据通常问题不大,但要注意数据量和结构复杂度。避免在一个测试中累积非常大的对象列表。 4. **JSON 库:** `JsonOutput` 是 Groovy 的标准库。如果遇到特殊字符或序列化问题,可以尝试使用其他库(如 `import groovy.json.JsonBuilder`)。 5. **调试:** 使用 `Debug Sampler` 和 `View Results Tree` 监听器检查 `itemsList` 和 `batchRequestBody` 的是否正确。在脚本中使用 `log.info(...)` 输出调试信息(可以在 JMeter `bin/jmeter.log` 中查看)。 6. **数据清洗:** CSV 文件中可能有 JMeter 无法直接处理的特殊字符(如换行符、引号),在 Groovy 脚本中组装 JSON 时需要注意转义处理。必要时在读取 CSV 后对数据进行清洗。 7. **线程安全:** 确保 `itemsList` 的初始化、操作、清理只发生在单个线程内(不要跨线程共享),本配置方案默认是每个线程有自己的副本。 按照上述步骤配置完成后,运行测试计划,JMeter 就会按照要求,每读取 CSV 文件的 100 行数据(或到文件尾),就组装成一个包含 100 条数据的请求体并发起一次 HTTP 请求。 [^1][^2][^3][^4][^5]: 以上配置参考并融合了 CSV 数据文件设置、循环控制、脚本处理和结果保存的相关原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值