背景介绍
对于 Android 项目来说,使用的是 Java 开发,网络请求接口的数量庞大且复杂,测试人员无法很直观的判断、得出网络请求是否存在问题。另一方面,为了验证请求接口是否能够在大负荷条件下,长时间、稳定、正常的运行,也需要我们借助工具来验证。对于上述问题,通过使用 Jmeter,可以很好的得到解决。JMeter 全称 Apache JMeter,是 Apache 组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于 Web 应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。另外,JMeter 能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter 允许使用正则表达式创建断言。
工具和方法
Fiddler
进行接口测试的第一步,是确认接口。从开发人员那里获取接口文档,接口文档应该包括完整的功能接口、接口请求方式、接口请求URL、接口请求参数、接口返回参数。如果当前项目没有接口文档,则可以使用 Fiddler 对 APP 进行抓包确认。
Fiddler 是一个 http 协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的 http 通讯,设置断点,查看所有的“进出” Fiddler 的数据(cookie,html,js,css 等文件)。在接口测试中,Fiddler 是一个非常好的工具,可以辅助 JMeter 对网络请求接口进行抓包、验证、确认。Fiddler 的安装及环境配置,本文将不详述,可参见相关文档。这里注重说明两点:
因为 Fiddler 抓包的原理就是通过代理,所以被测终端需要和安装fiddler的电脑在同一个局域网中
开启 Fiddler 的远程连接,Fiddler 主菜单 Tools -> Fiddler Options…-> Connections 页签,选中Allowremote computers to connect,并记住端口号为 8888,等会设置手机代理时需要,设置好后重启fiddler保证设置生效。手机连接热点时,修改高级选项,设置完毕后,即可使用 Fiddler 进行抓包操作。如下图所示:
JMeter
安装使用 JMeter 前,需要先配置对应的计算机环境。当前版本的 JMeter(2.11r1554548),需要安装 jdk1.7及以上版本,并配置环境变量,正确安装配置后,打开 jmeter.bat 即可显示 GUI 操作界面,如下图所示。(具体的安装配置操作,详见相应的文档)
使用 JMeter 进行接口测试的第一步,是新建一个线程组,对线程组的相关属性进行设置。线程组的属性包括:
线程数:虚拟用户数,即并发数,一个线程表示一个虚拟用户
Ramp-Up Period:所有线程启动的时间,单位 s。通过这个参数可以设置每个线程间的启动间隔,防止给电脑造成太大性能压力;例如线程数 500,Ramp-Up Period为 50,意味着 50s 内,就要完成所有的 500 次请求,平均每秒进行 10 次请求
循环次数:测试循环的次数,如果勾选了“永远”,那么所有线程会一直发送请求,直到手动停止运行脚本
第二步:添加一个 http 请求,并配置相应的 ip、端口、地址、请求类型等,如果是 GET 方法的请求,请求参数直接写在 URL 后面即可;如果是 POST 的方法,则需要在 Body Data 中填入包含请求参数的数据(Body Data 可以从 Fiddler 抓的包中获取,将 Fiddler 抓取的到数据包中 Inspectors-TextView 中的数据复制到 Body data 中即可)。另外,由于该服务接口仅接受 json 格式数据,需要设定 header 信息。此时我们在线程组中添加 Http 信息头管理器,添加 Content-Type 参数,值为 application/json。如下图所示:
第三步:为了验证接口请求数据、返回数据结果的正确性及完整性,我们需要添加一个“察看结果树”,来直观的察看请求数据及返回数据。如下图所示:
第四步:启动线程,察看结果,如下图所示:
细心同学可能会发现,以上操作步骤中,无论是请求数据还是返回数据,都是经过加密后的数据。由于保证数据传输过程中的安全性,需要对传输的数据进行加密和解密操作。对于使用 Jmeter 进行接口测试来说,可以使用一下方法,进行数据进行加密、解密操作。首先,将加密、解密算法的 jar 包,放到 jmeter 的安装路径下,例如 F:\Program Files\apache-jmeter-2.11\lib\ext。加密:创建一个前置处理器 BeanShell PreProcessor,调用加密算法,如下图所示: 解密:接口请求,返回的响应数据都是加密后的数据,要想直观的看到响应数据,需要对响应数据进行解密。创建一个后置处理器 BeanShell PostProcessor,调用解密算法:
查看测试结果时我们会发现有时候网络侧返回数据不符合要求时,Jmeter 给出的结果仍是通过的。这时候我们需要通过断言来判断网络的返回数据是否符合要求。比如,我们可以添加一个断言来检查返回信息中是否包含关键字 “errMsg” 来判断错误信息。首先添加一个相应断言,在要测试的响应字段中选择响应文本,在模式匹配规则中选择包括,勾选否,在要测试的模式中添加提一条,输入关键字“errMsg”。意思是检查网络返回结果中不包含“errMsg” 的才会判定为通过。如图所示:
我们做压力测试时,想要测试多用户登陆时要怎么做?可以在线程属性中配置多个线程,
但是这样只是同一个用户多次登录,多个不同的用户需要输入不同的用户名密码。当然我们可以写多个登录的 HTTP 请求,每个请求输入不同的参数,但是这样太傻了。这个时候我们可以通过CSV Data Set Config 来定义两个变量代表用户名和密码,然后传入不同的值即可实现多用户的登录:
在登录的 case 中添加一个 CSV Data Set Config(添加-配置元件-CSV Data Set Config)
Filename:指定读取用户名和密码的文件,我们会将所有的用户名密码写到该文件中;
File Encoding::写入用户名密码的文件编码格式,不写的时候默认为 ANSI
Varible Names:定义文本文件中的变量名用户名 =user 和密码 =pwd,变量之间逗号分隔
到上面 Filename 的路径下创建该文件并写入用户名密码,用户名和密码之间用逗号分开,不同用户名密码之间换行
到 Jmeter 的脚本中将原本的用户名密码改为变量名,由于我们使用的是 Post 方法,所以到Body Data 中修改
常见问题
使用Jmeter进行接口测试或压力测试时,可能会遇到一些问题,下面简单列举几个常见问题
JMeter异常关闭
有时候在运行 JMeter 的过程中突然 JMeter 崩溃,这种异常关闭的情况多数是由于内存溢出的原因,在不设置 JVM Heap 大小的情况下,默认是 512MB。下图是 JMeter 2.13 版本的默认设置,文件在 %JMETER_HOME%/bin/jmeter.bat 中。
可以根据实际情况适当加大,如果你的计算机有 4GB 以上的可用内存且是 64 位系统,建议把 -Xms 与 -Xmx 都设置成 2GB,其他参数都不用改变。
响应数据中有乱码
使用录制下来的测试脚本进行测试的时候,查看结果树,可能会出现响应数据中有乱码。
方法一:找到安装目录 /bin 下面的 jmeter.properties 配置文件,打开 jmeter.properties 配置文件,找到 “sampleresult.default.encoding” 这个配置项,将原来的默认值 “ISO-8859-1” 修改为 “utf-8” ,重启jmeter,重新执行测试
方法二:指定请求节点下,新建后置控制器 "BeanShell PostProcessor" ,其脚本框中输入:prev.setDataEncoding("UTF-8") ,并保存
总结
Jmeter 除了可以在本地进行压力测试和接口测试外,还可以与 Jenkins 集成,构建整体化的压力测试方案。通过 Jenkins 运行 Jmeter 脚本,测试完毕后生成格式为 xml 的测试报告,调用 Ant 打包转换成 html 格式的报告。