性能测试工具 Jmeter 录制手机 app,模拟场景进行压测做性能数据分析

周小丽 · 2017年05月26日 · 最后由 李宗旨 回复于 2018年08月24日 · 6092 次阅读

好久没发过帖子了,最近一直忙着测试,近来有个项目要求做性能测试,客户端是 app,用 loadrunner 只有 11.5 以上的版本才有 mobile 协议支持对 app 的脚本录制;但寻求了许久目前只能破解 loadrunner 11.0 及之前的版本,11.5 目前没破。非破解版的 loadrunner 11.5 及以上版本只能支持 50 个用户的测试,无奈只能用 jmeter 测试了。

使用 JMeter 录制手机 App 脚本

1、 添加线程组
 选中 “测试计划”,右键依次添加【线程组】,用于保存录制的脚本。
2、 添加 HTTP 代理服务器
 选中 “工作台”,右键依次添加【HTTP 代理服务器】。
 配置 HTTP 代理服务器,端口可以使用默认 8080,目标控制器选择 “测试计划>线程组”。
 启动 HTTP 代理服务器,弹出 “Root CA……” 的提示框,点击 “确定” 表示 HTTP 代理服务器开始工作。
3、 配置手机网络代理
 进入手机 WIFI 设置,选择一个 WIFI,长按 WIFI 名称,在弹出的提示框中,选择 “修改网络”
 在修改网络页,勾选【显示高级选项】,填写代理服务器主机名 (JMeter 软件所在的主机 IP 地址) 和代理服务器端口 (添加 HTTP 代理服务器配置的端口,默认 8080),保存配置
4、 查看 JMeter 录制的手机 App 脚本

5、 Fiddler-给手机设置代理并抓取 https 链接:https://www.cnblogs.com/qingqing-919/p/8444828.html

需要将 fiddler 抓包中的消息认证头,拷贝到 jmeter 中

备注:本人不太喜欢用 Jmeter 的录制功能,因为会录制很多无效的网络请求,但若不知道接口参数的情况下,可以采用录制方式,然后删除修改。

线程组的设置

普通线程组
1、 线程数:设置并发用户线程数量,即通常意义的并发用户数
2、 Ramp-Up Period(in seconds):设置并发用户加载时间,假设并发用户数设置为 100,此处设置为 10,则认为 jmeter 会在 10s 内加载完成 100 并发用户数,也就是说每隔 10 秒加载一个
3、 循环次数:输入框与复选框只能选择一种,不能同时被选择为场景循环方式;输入框输入数字则被认为是当前线程组所控制的脚本区域的执行次数;【永远】复选框选择后,输入框内的数字将失效,启动后脚本将一直执行下去。
4、 调度器:对于调度而言,顾名思义就是我们想在什么时间开始运行,运行多长时间自动停止诸如此类的场景需求均可以在此设置。
  • 启动时间:在设置时间点开始运行场景,比如你想在下班后开始运行,如果时间小于当前时间,启动后立即执行,大于当前时间,启动后等待本地时间到了自动运行
  • 结束时间:在设置时间点结束运行场景,比如上班前结束运行,结束时间如果小于开始时间或者当前时间,自动运行后立即终止
  • 持续时间:设置当前场景持续运行的时间
  • 启动延迟:设置场景启动后多长时间再开始真正运行,比如你想在下班后 5 分钟开始运行场景
其中持续时间和启动延迟的优先级高于启动时间和结束时间,也就是说当你设置了持续时间或者启动延迟,那么你的启动时间或者结束时间将失效,
5、 几种设置场景组合
  • 不勾选【永远】,选择【调度器】,设置完成后,启动运行也只会运行当前并发用户数循环次数,运行完成即会结束。所以此中选择可用于希望未来某时间点开始运行完成并发用户数循环次数的场景
  • 勾选【永远】,设置启动时间及结束时间,持续时间和启动延迟均为空,可用于希望未来某时间点自动运行并且到未来某时间点自动结束的场景
  • 勾选【永远】, 设置 持续时间和启动延迟, 可用于希望在启动多久后自动运行并持续多长时间的场景

另外介绍一个调试工具 Debug Sampler,会把我们自定义的变量输出在 response data 中,方便我们调试的时候使用,但在正式执行脚本时需要删除 Debug Sample

jp@gc - Stepping Thread Group


类似 loadrunner 的场景设置,解释:
 This Group will start 100 threads:这次的测试总共会起 100 个线程。
 First , wait for 0 seconds:等待 0s 后开始起线程,也就是不等待直接起线程。
 Then start 10 threads every 30 seconds:每起 10 个线程后会运行 30s,再起余下的 10 个线程,再运行 30s,以此类推。
 Using ramp-up 5 seconds:前面每起多少个线程的时候花 5s,与上面结合起来即 5s 内起 10 个线程,运行 30s,然后再再 5s 内再起 10 个线程,再运行 30s,以此类推。
 Then hold load for 60 seconds. :全部的线程起来后,运行 60s 后开始停止(跟 loadrunner 类似,从 jmeter 聚合报告里面可以看出来,这里的 hold load 的意思,其实是这些线程,一直在请求,相当于 jmeter 普通线程组里面的循环运行)。
 Finally , stop 5 threads every 1 seconds:最后停止线程,5 个线程停一次,等 1s 再停 5 个线程(当然,第一次是 hold 时间一过就先停 5 个线程,然后等 1s 再停余下的 5 个线程)。

介绍几个常用的逻辑控制器

JMeter 中的 Logic Controller 分为两类:
a) 控制测试计划执行过程中节点的逻辑执行顺序,如:循环控制器(Loop Controller)、if 控制器(If Controller)等;
b) 对测试计划中的脚本进行分组、方便 JMeter 统计执行结果以及进行脚本的运行时控制等,如:吞吐量控制器(Throughput Controller)、事务控制器(Transaction Controller)。
一、ForEach 控制器(ForEach Controller)
  作用:ForEach 控制器一般和用户自定义变量一起使用,其在用户自定义变量中读取一系列相关的变量。该控制器下的采样器或控制器都会被执行一次或多次,每次读取不同的变量值。
二、包含控制器(Include Controller)
  作用:用于引用外部的 Jmx 文件;从而控制多个测试计划组合
三、事务控制器(Transaction Controller)
  作用: 事务控制器会生产一个额外的采样器,用来统计该控制器子结点的所有时间。
四、仅一次控制器(Once Only Controller)
  作用:在测试计划执行期间,该控制器下的子结点对每个线程只执行一次,登录场景经常会使用到这个控制器。
五、吞吐量控制器(Throughput Controller)
  作用:控制其下的子节点的执行次数与负载比例分配,也有两种方式:
  Total Executions:设置运行次数
  Percent Executions:设置运行比例 (1~100 之间,不用写%)
  如:设置线程组循环 5 次,吞吐量控制器 1:百分比 40,吞吐量控制器 2:百分比 60

六、If 控制器(If Controller)
  作用:根据给定表达式的值决定是否执行该节点下的子节点,默认使用 javascript 的语法进行判断

脚本参数化的几种方式

一、使用 Jmeter 自带函数获取参数值
  Jmeter 中可以产生值的函数有:Random( , , ),threadNum,CSVRead( , ),StringFromFile( , , , ) 。函数调用方法就不细说了,因为 Jmeter 中有函数助手

  然后将函数复制到需要用到随机数的地方,当我们设置的线程数超过随机数范围时,随机数将会重复生成。

不过需要重点介绍下正则表达式的使用,后续有需要用到关联测试,因为在测试过程过有些数据是经常发生变化的,要获取并使用这些数据,就要使用关联。

1、 第一个参数:用于解析服务器响应数据的正则表达式。它会找到所有的匹配项。如果测试人员希望将表达式中的某部分应用在模板字符串中,记得加上圆括号。
2、 第二个参数:这是一个模板字符串,函数会动态填写字符串的部分内容。要在字符串中引用正则表达式捕获的匹配组合,请使用语法:$[group_number]$。例如 $1$ 或者 $2$。测试人员的模板可以是任何字符串
3、 第三个参数:第 3 个参数告诉 JMeter 使用第几次匹配。测试人员的正则表达式可能会找到多个匹配项。对此,测试人员有 4 种选择:
 整数,直接告诉 JMeter 使用第几个匹配项。 “1” 对应第一个匹配,“2” 对应第二个匹配,以此类推
 RAND,告诉 JMeter 随机选择一个匹配项
 ALL,告诉 JMeter 使用所有匹配项,为每一个匹配项创建一个模板字符串,并将它们连接在一起
 浮点值 0 到 1 之间,根据公式(找到的总匹配数目 * 指定浮点值)计算使用第几个匹配项,计算值向最近的整数取整
4、 第四个参数:如果在上一个参数中选择了 “ALL”,那么这第 4 个参数会被插入到重复的模板值之间
5、 第五个参数:如果没有找到匹配项返回的默认值
6、 第六个参数:重用函数解析值的引用名,参见上面内容
7、 第七个参数:输入变量名称。如果指定了这一参数,那么该变量的值就会作为函数的输入,而不再使用前面的采样结果作为搜索对象

二、使用 CSV Data Set Config 获取参数值

三、使用用户定义的变量获取参数值

  一般配合 ForEach 控制器一起使用

参数值的传递

一、利用 Cookie 进行值的传递
  用 JMeter 进行接口调试时,有时候会遇到需要登录的情况,如请求 wetest 的 DataSearchAjax 接口:

  出现这种情况的原因很明显是未登录引起的。一个较好的解决方法就是将登录后的 cookies 保存下来,在访问 DataSearchAjax 接口的时候,带上用户登录后的 cookies 信息进行查看。
  在 JMeter 中,我们可以通过如下途径进行 cookies 的传递,如下图添加 HTPP Cookie 管理器:

  再给登录的接口添加前置处理器 Bean Shell PreProcessor,用来保存登录的 cookies:

  我们要在 Bean Shell PreProcessor 里面添加我们的 cookies 值了。
二、利用正则匹配提取上一个接口的返回数据作为下个请求的输入
  用 JMeter 进行接口调试时,经常会遇到上一接口的返回值中的某个字段,要作为下一接口的输入,这种情况下,我们需要利用正则匹配来提取我们需要的值。
  例如,若要提取相应数据中的 userid 字段作为下个接口的输入的话,可以在该接口请求后面添加正则表达式提取器:

  我们给正则表达式提取器命名为 get_userid,并填写引用名称、正则表达式、模板、匹配数值、缺省值,填写后的如如下:

  填写完成后,在添加新的 HTTP 请求,来测试提取到的 user_id 字段:

介绍几个定时器的用法,类于 loadrunner 中的 thinktime,集合点的设置

一、固定定时器(Constant Timer)

  这是一个很重要的定时器,如果你需要让每个线程在请求之前按相同的指定时间停顿,那么可以使用这个定时器;需要注意的是,固定定时器的延时不会计入单个 sampler 的响应时间,但会计入事务控制器的时间。
  对于 “java 请求” 这个 sampler 来说,定时器相当于 loadrunner 中的 pacing(两次迭代之间的间隔时间);
  对于 “事务控制器” 来说,定时器相当于 loadrunner 中的 think time(思考时间:实际操作中,模拟真实用户在操作过程中的等待时间)。
二、高斯随机定时器(Gaussian Random Timer)

  如果需要让每个线程在请求之前按随机的时间停顿,那么可以使用这个定时器,上图表示暂停时间会分布在 100 到 400 之间
三、同步定时器(Synchronizing Timer)

  这个定时器和 loadrunner 当中的集合点(rendezvous point)作用相似,其作用是:阻塞线程,直到指定的线程数量到达后,再一起释放,可以瞬间产生很大的压力
(1)Number of Simulated Users to Group by:模拟用户的数量,即指定同时释放的线程数数量
(2)Timeout in milliseconds:超时时间,即超时多少毫秒后同时释放指定的线程数

监听器配置

  将下载的 JMeterPlugins.jar 包复制到 Jmeter 的 lib 目录下面的 ext 目录下面,重新启动 Jmeter,我们点击添加就可以看到出现了很多的 jp@gc-开头的文件。这里监控内存我们使用的是:jp@gc - PerfMon Metrics Collectot
  在使用之前,我们需要下载 ServerAgent-2.2.1,然后运行/serverAgent/startAgent.bat 这个文件,我们需要将 serverAgent 目录及下面的文件复制到我们测试的服务器上,然后点击打开,它的默认端口为 4444。
  常用的监听器还有如下 jp@gc - Active Threads Over Time,jp@gc - Transactions per Second,jp@gc - Response Times Over Time,jp@gc - Composite Graph,保存响应到文件,聚合报告,察看结果树

其中 jp@gc - Composite Graph 可以将多个监听视图进行合并分析

最后测试报告的生成

  使用 jmeter 进行性能测试,运行完毕后生成 html 格式的测试报告,需要进行如下操作(3.0 含及以上的版本):
一、在 jmeter.properties 或者 user.properties 确认如下配置项

• jmeter.save.saveservice.bytes = true
• jmeter.save.saveservice.label = true
• jmeter.save.saveservice.latency = true
• jmeter.save.saveservice.response_code = true
• jmeter.save.saveservice.response_message = true
• jmeter.save.saveservice.successful = true
• jmeter.save.saveservice.thread_counts = true
• jmeter.save.saveservice.thread_name = true
• jmeter.save.saveservice.time = true
• jmeter.save.saveservice.timestamp_format = ms
• jmeter.save.saveservice.timestamp_format = yyyy/MM/dd HH:mm:ss

o 如果希望在 Errors 报告中展示更详细数据,需要确保如下配置: jmeter.save.saveservice.assertion_results_failure_message = true
o 如果使用了事务控制器 (Transaction Controller),确认 Generate parent sample 为未勾选状态

运行 jmeter 程序,在命令行输入如下信息
1)Windows 系统
输入格式如下:jmeter.bat -n -t -l -e -o
实际输入:C:\apache-jmeter-3.0\bin\jmeter.bat -n -t Movie.jmx -l movie.jtl -e -o test

2)Linux 系统
输入格式如下:jmeter -n -t -l -e -o
实际输入:/opt/apache-jmeter-3.0/bin/jmeter -n -t final-result.jmx -l final-result.jtl -e -o /opt/apache-jmeter-3.0/test

共收到 9 条回复 时间 点赞

其实可以用 LR 的, LR11 也有办法获取到手机上的请求的。

不错,很基础😁

菠萝蜜 回复

LR11,你用什么协议录制的手机?

周小丽 回复

通过代理录制还是 http 的协议

为什么我不能录制脚本。Problem with SSL certificate for 'api.weibo.com'? Ensure browser is set to accept the JMeter proxy cert: Remote host closed connection during handshake 这个怎么解决

周小丽 回复

不用 LR 自带的录制, 通过抓包工具抓包,然后放入 LR 里。

王宏雁 回复

感觉是你们协议加密了,你可以试着让开发给你单独编译一个去除加密的版本试试

菠萝蜜 回复

谢谢指点,我试试

可以自动控制手机模拟点击?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册