4. JMeter 脚本录制:HTTP代理服务器录制、Badboy录制、手动编写HTTP请求脚本
在性能测试脚本开发中,脚本的获取方式直接影响测试效率与维护成本。本章聚焦三种主流脚本构建方法:HTTP代理服务器录制、Badboy录制以及手动编写HTTP请求脚本。每种方法适用于不同的场景,理解其原理与适用边界,是脚本编排的基础能力。
4.1 三种脚本获取方式对比
| 方法 | 原理 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| HTTP代理服务器录制 | JMeter作为中间代理,拦截浏览器与服务器之间的HTTP/HTTPS请求 | Web应用、前后端分离项目、快速生成基础脚本 | 无需手动编写,覆盖完整请求流程 | 可能录制大量静态资源,需手动过滤;HTTPS需证书配置 |
| Badboy录制 | Badboy内置浏览器,录制用户操作并导出为JMeter脚本 | 复杂业务流程、多步骤表单、需要可视化的操作路径 | 可视化录制,支持断言与参数化预配置 | Badboy仅支持Windows;导出后需二次清理 |
| 手动编写HTTP请求脚本 | 基于接口文档,直接配置HTTP请求的协议、方法、参数、头信息 | API接口测试、微服务压测、已有接口文档的场景 | 脚本精确可控,无冗余请求,易于维护 | 对接口文档依赖度高,初期编写耗时 |
选型建议: 对于已有完整接口文档的微服务或API项目,优先选择手动编写;对于Web端业务流程压测,推荐使用HTTP代理服务器录制;若需要可视化操作路径且使用Windows环境,Badboy可作为辅助工具。
4.2 HTTP代理服务器录制详解
JMeter内置的HTTP代理服务器组件,通过设置浏览器代理指向JMeter,实现请求的实时捕获与脚本生成。核心配置步骤如下:
- 添加HTTP代理服务器: 在测试计划中右键添加“非测试元件 → HTTP代理服务器”。
- 配置端口与目标控制器: 设置端口(默认8888),指定录制脚本存放的目标线程组。
- 设置排除模式: 在“排除模式”中添加正则表达式,过滤掉图片、CSS、JS等静态资源(如
.*\.(png|jpg|css|js|ico))。 - 配置HTTPS证书: 若录制HTTPS请求,需在JMeter中生成并导入根证书(选项 → SSL管理器)。
- 启动录制: 点击“启动”按钮,浏览器设置代理为
127.0.0.1:8888,开始操作被测应用。 - 停止与保存: 录制完成后停止代理,脚本自动生成在目标线程组中,进行后续参数化与断言调整。
关键过滤策略: 录制后务必检查“取样器结果”中的请求列表,删除重复的静态资源请求、预检请求(OPTIONS)以及非业务核心的第三方请求,避免压测时产生无效负载。
4.3 Badboy录制与导出
Badboy是一款基于IE内核的Web测试录制工具,支持录制用户操作并导出为JMeter兼容的脚本格式。其核心优势在于可视化录制过程中的断言添加与参数提取。
- 启动Badboy: 打开Badboy,在地址栏输入被测应用URL,开始录制。
- 操作业务流程: 在Badboy内置浏览器中完成登录、查询、提交等操作,Badboy自动记录所有HTTP请求。
- 添加断言与参数: 在请求节点上右键添加“断言检查”或“提取正则表达式”,用于后续验证。
- 导出为JMeter脚本: 选择“File → Export to JMeter”,保存为
.jmx文件。 - 导入JMeter: 在JMeter中打开导出的
.jmx文件,检查线程组与取样器配置。
注意事项: Badboy导出的脚本可能包含大量冗余的Cookie管理器、缓存管理器等元件,建议在JMeter中清理不必要的配置元件,并统一使用HTTP Cookie管理器。
4.4 手动编写HTTP请求脚本
手动编写脚本是性能测试工程师的核心技能,尤其适用于接口文档完善、需要精确控制请求参数的场景。以下是一个标准的HTTP请求脚本结构示例:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="手动编写示例">
<elementProp name="TestPlan.user_defined_variables">
<collectionProp name="arguments">
<elementProp name="base_url">
<stringProp name="Argument.value">https://api.example.com</stringProp>
</elementProp>
</collectionProp>
</elementProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="用户线程组">
<intProp name="ThreadGroup.num_threads">10</intProp>
<intProp name="ThreadGroup.ramp_time">5</intProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="GET用户信息">
<stringProp name="HTTPSampler.domain">${base_url}</stringProp>
<stringProp name="HTTPSampler.path">/api/v1/users/1001</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
</HTTPSamplerProxy>
<hashTree/>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="POST创建订单">
<stringProp name="HTTPSampler.domain">${base_url}</stringProp>
<stringProp name="HTTPSampler.path">/api/v1/orders</stringProp>
<stringProp name="HTTPSampler.method">POST</stringProp>
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
<elementProp name="HTTPsampler.Arguments">
<collectionProp name="Arguments.arguments">
<elementProp name="">
<stringProp name="Argument.value">{"userId":1001,"productId":2002,"quantity":1}</stringProp>
</elementProp>
</collectionProp>
</elementProp>
</HTTPSamplerProxy>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
手动编写核心要点:
- 变量化: 将域名、端口、路径中的可变部分提取为变量(如
${base_url}),便于环境切换。 - 请求体: POST请求使用
postBodyRaw模式,直接粘贴JSON字符串,避免参数编码问题。 - 头信息: 手动添加
Content-Type: application/json、Authorization: Bearer ${}等必要头。 - 断言: 添加响应断言,验证HTTP状态码或响应体中的关键字段。
4.5 三种方法的综合选型矩阵
| 评估维度 | HTTP代理服务器录制 | Badboy录制 | 手动编写HTTP请求脚本 |
|---|---|---|---|
| 脚本生成速度 | 快(实时录制) | 中(需导出转换) | 慢(需逐条编写) |
| 脚本冗余度 | 高(需大量过滤) | 中(需清理元件) | 低(精确可控) |
| 参数化支持 | 需后期手动添加 | 录制时可预配置 | 编写时直接集成 |
| HTTPS支持 | 需导入证书 | 内置支持 | 直接配置 |
| 跨平台 | 全平台(Java) | 仅Windows | 全平台 |
| 维护成本 | 高(依赖录制环境) | 中(依赖Badboy版本) | 低(文档驱动) |
实战建议: 在课程项目中,推荐采用“混合模式”——先用HTTP代理服务器录制生成基础脚本,再手动清理冗余请求并添加参数化与断言,最后导出为可复用的压测脚本模板。对于新增接口,直接手动编写并集成到已有脚本中。