性能测试实战:JMeter + Badboy 从入门到认证通过
2017年年初,由于工作需要,我开始学习性能测试相关的技术。那时候团队正准备对核心业务系统进行全面的性能评估,而我被安排负责这块工作。从零开始学习JMeter和Badboy,经过几个月的学习和实践,最终成功输出了专业的性能测试报告,并通过了某大厂的认证审核。
性能测试是软件质量保障的重要环节,它通过模拟真实用户负载,验证系统在各种压力条件下的表现。
性能测试不仅是为了发现系统缺陷,更是为了评估系统的承载能力,为容量规划和性能优化提供数据支撑。
性能测试类型:
性能测试(Performance Testing)验证系统在预期负载下的响应时间和吞吐量,确保满足性能需求。
负载测试(Load Testing)逐步增加负载,观察系统在不同负载级别下的表现,找出性能瓶颈。
压力测试(Stress Testing)在超过正常负载的极端条件下测试,观察系统的稳定性和恢复能力。
稳定性测试(Endurance Testing)在较长时间内持续施加负载,验证系统的长期稳定运行能力。
当时团队主要考虑两款工具:LoadRunner 和 JMeter。
最终选择 JMeter + Badboy 组合的原因:
经过综合评估,我们决定采用JMeter作为主要性能测试工具,Badboy作为辅助录制工具。这套组合完全能够满足我们的性能测试需求。
工欲善其事,必先利其器。首先需要准备好以下软件环境:
软件清单:
| 软件 | 版本 | 用途 | 下载地址 |
|---|---|---|---|
| JDK | 1.8+ | JMeter运行依赖 | oracle.com |
| JMeter | 3.3+ | 性能测试主工具 | jmeter.apache.org |
| Badboy | 2.2 | 脚本录制工具 | badboy.com.au |
建议优先安装JDK,因为JMeter是基于Java开发的,JDK是必需的环境。推荐使用JDK 1.8或更高版本。
JMeter 安装步骤:
java -versionjmeter -v 查看JMeter版本了解JMeter的目录结构,有助于后续的配置和插件管理:
apache-jmeter-3.3/├── bin/ # 启动脚本和配置文件│ ├── jmeter.bat # Windows启动脚本│ ├── jmeter.sh # Linux启动脚本│ └── jmeter.properties # JMeter配置文件├── docs/ # API文档├── extras/ # 附加功能├── lib/ # JMeter核心库│ └── ext/ # JMeter扩展插件├── printable_docs/ # 可打印文档└── LICENSE # 许可证Badboy是一款强大的Web测试和录制工具,支持Windows和Mac系统。它可以录制用户在浏览器中的操作,并生成可重放的测试脚本。
Badboy最大的优势在于可以”所见即所得”地录制脚本,操作简单直观。录制完成后可以导出为JMeter格式,大幅减少手工编写脚本的工作量。
Badboy 录制流程:
打开Badboy,点击工具栏的红色录制按钮(或者按F9),开始录制。
在地址栏输入要测试的网站地址,如 http://www.example.com Badboy会自动打开内置浏览器访问该页面。
在Badboy内置浏览器中进行正常的业务操作,如登录、搜索、下单等。 Badboy会自动记录每一步操作,生成测试步骤。
完成所有操作后,点击停止按钮(或者按F9)。 可以在左侧的树形结构中查看录制的所有步骤。
录制完成的脚本通常需要进行一些优化才能用于正式测试:
常见优化项:
将硬编码的用户名、密码等数据替换为参数化变量,便于数据驱动测试。
# Badboy支持从CSV文件读取参数var username = "${username}";var password = "${password}";对于需要动态获取的数据(如SessionID、Token),需要进行关联处理。
// 从响应中提取SessionIDvar sessionId = response.getText().match(/JSESSIONID=([^;]+)/)[1];添加检查点验证关键元素,确保脚本执行正确。
// 验证登录后是否显示用户名if (pageContains("欢迎," + username)) { log.info("Login successful");}将多个相关步骤封装为一个事务,便于统计整体响应时间。
transaction("UserLogin");// ... 登录相关步骤 ...transactionEnd();脚本优化完成后,可以导出为JMeter格式:
JMeter使用测试计划(Test Plan)来组织和管理测试。一个完整的测试计划包含以下主要组件:
测试计划结构:
Test Plan (测试计划)├── Thread Group (线程组)│ ├── Once Only Controller (仅一次控制器)│ │ └── Login Request (登录请求)│ ├── Http Cookie Manager (Cookie管理器)│ ├── Transaction Controller (事务控制器)│ │ ├── Search Product (搜索商品)│ │ ├── View Detail (查看详情)│ │ └── Add to Cart (加入购物车)│ ├── Gaussian Random Timer (高斯随机定时器)│ └── View Results Tree (查看结果树)├── Config Element (配置元件)│ ├── Http Request Defaults│ ├── CSV Data Set Config│ └── User Defined Variables├── Listener (监听器)│ ├── Summary Report│ ├── Graph Results│ └── Aggregate Report└── Non-Test Elements (非测试元素) └── HTTP Mirror Server线程组定义了虚拟用户的行为模式,是性能测试的核心配置:
关键参数:
| 参数 | 说明 | 建议值 |
|---|---|---|
| Number of Threads | 虚拟用户数 | 根据目标并发设置 |
| Ramp-Up Period | 启动时间 | 总时长/线程数 |
| Loop Count | 循环次数 | 根据测试时长设置 |
| Duration | 持续时间 | 稳定测试时长 |
Ramp-Up Period决定了虚拟用户的启动速度。如果设置过短,可能造成瞬时压力过大;设置过长,则无法达到目标并发。建议设置为总时长的1/3到1/2。
HTTP请求是JMeter模拟用户操作的核心组件:
请求配置要点:
常用配置项:
定时器用于控制请求的发送节奏,模拟真实的用户行为:
常用定时器:
每次请求之间固定等待一定时间。
设置 Constant Delay = 1000ms(每次请求间隔1秒)
等待时间服从高斯正态分布,更接近真实用户行为。
Deviation = 300ms(标准差)
Offset = 1000ms(基准延迟)
控制请求的吞吐量(每分钟请求数),用于精确控制负载。
Throughput = 600(每分钟600个请求)
积压一定数量的线程后同时释放,模拟瞬间并发。
Number of Simulated Users to Group by = 50(50个用户同时释放)
监听器用于收集和展示测试结果,是分析性能数据的重要工具:
核心监听器:
| 监听器 | 用途 | 重要指标 |
|---|---|---|
| View Results Tree | 查看每个请求的详细响应 | 响应内容、状态码 |
| Summary Report | 汇总统计报告 | Avg、Min、Max、Error% |
| Aggregate Report | 聚合报告 | 90%、95%、99%分位数 |
| Graph Results | 图形化展示 | 实时吞吐量、响应时间 |
| Response Times Over Time | 响应时间趋势 | 性能稳定性 |
根据业务需求,设计完整的测试场景:
测试场景设计:
单用户单循环,验证脚本正确性,确保无错误发生。
逐步增加用户数,观察系统性能变化。
模拟业务高峰期的高并发场景。
长时间持续负载,验证系统可靠性。
JMeter 命令行执行:
# 基本执行命令jmeter -n -t testplan.jmx -l result.jtl -e -o output
# 参数说明# -n: 非GUI模式运行# -t: 指定测试计划文件# -l: 指定结果文件# -e: 生成HTML报告# -o: 报告输出目录命令行模式比GUI模式消耗更少资源,适合执行大批量测试。建议在正式测试时使用命令行模式。
测试执行过程中需要持续监控系统资源:
监控指标:
JMeter 3.0之后支持自动生成HTML报告:
报告生成命令:
# 执行测试并生成报告jmeter -n -t testplan.jmx -l result.jtl -e -o ./report报告包含内容:
核心性能指标定义:
| 指标 | 定义 | 合格标准 |
|---|---|---|
| 平均响应时间 | 所有请求响应时间的平均值 | < 3秒 |
| 90%分位响应时间 | 90%请求的响应时间上限 | < 5秒 |
| 吞吐量 | 每秒处理的请求数 | 根据业务需求 |
| 错误率 | 失败请求占总请求的比例 | < 1% |
| 并发用户数 | 同时发起请求的用户数量 | 根据目标设计 |
一份专业的性能测试报告应包含以下内容:
报告大纲:
在完成内部性能测试后,我们需要将系统提交给某大厂进行认证审核。这家大厂对性能有严格的要求,我们需要证明系统能够承受预期的业务负载。
系统需要能够承受500用户并发,峰值响应时间不超过5秒,错误率不超过0.5%,且在持续1小时的压力测试中保持稳定。
认证前准备事项:
确保测试环境与生产环境配置一致,包括服务器、网络、数据库等。如有差异需要明确说明。
测试脚本需要经过充分验证,确保能够正确模拟用户行为,响应结果符合预期。
测试数据需要覆盖各种业务场景,包括正常数据和异常数据,确保测试的全面性。
性能测试报告需要专业、完整,包括测试方法、结果分析、问题和建议等所有必要内容。
认证审核流程:
提交完整的性能测试报告,包括测试方案、环境配置、测试结果、问题分析等内容。
大厂技术团队对提交的文档进行审核,确认测试方法的合理性和结果的准确性。
在大厂技术人员的监督下,执行现场性能测试,全程录像记录。
对审核过程中的疑问进行解答,提供更详细的测试数据和日志。
确认测试结果符合要求后,颁发性能认证证书。
认证通过经验总结:
经验教训:
认证审核不仅是考核,更是一次学习机会。认真对待审核过程中的每一个问题,都会让你对性能测试有更深入的理解。
经过团队的努力,我们最终顺利通过了认证审核,各项指标均达到要求:
认证结果:
| 指标 | 要求 | 实际结果 | 状态 |
|---|---|---|---|
| 响应时间(90分位) | < 5秒 | 3.2秒 | ✅ 通过 |
| 吞吐量 | > 100 TPS | 156 TPS | ✅ 通过 |
| 错误率 | < 0.5% | 0.12% | ✅ 通过 |
| CPU使用率 | < 80% | 67% | ✅ 通过 |
| 内存使用率 | < 85% | 72% | ✅ 通过 |
这次性能测试认证经历让我深刻认识到,性能测试不仅是技术工作,更需要严谨的态度和规范的方法。感谢团队的共同努力,我们顺利通过了认证!
通过这次学习JMeter和Badboy并通过认证的经历,我有以下收获:
学会了从测试计划设计、脚本开发、测试执行到报告输出的完整流程。
深入理解了响应时间、吞吐量、并发数、错误率等核心指标的含义和计算方法。
了解了认证审核的流程和要求,积累了应对认证审核的经验。
通过对测试结果的分析,提升了定位性能瓶颈和优化建议的能力。
性能测试是一个需要持续学习的领域:
性能测试是一项需要不断实践和积累经验的技能。多做项目、多分析数据、多总结经验,能力自然会不断提升。
JMeter学习建议:
性能测试之路刚刚开始,未来还有更多的知识和技能等待学习和探索。