测试场景
在MongoDB中存有上万个ID,某个接口需要带上ID参数,且每个ID只能使用一次,测试该接口的性能。
设计思路
思路一:一个线程组中完成数据库读ID操作,用ForEach逻辑控制器来遍历ID并发送请求。
这个过程听起来似乎能够完成这个场景,但是这需要一个很长的等待测试串行执行的时间:这可是上万个ID。
思路二:多线程并行执行。
并行执行测试用例的速度肯定要大于串行执行,并且这才符合用Jmeter的初衷。
更细化一些,我需要再建一个setUp线程组,在这个线程组中读取数据库中的ID信息并存为变量;然后,通过启动大于ID数量的线程数去执行这些用例。
为了覆盖到每一个ID,我在读取数据库后存为参数时,需要为每个ID赋上唯一的Key值,同时各个线程应该读到不同的ID,所以需要一个计数器Counter。
具体实现
Jmeter 3 开启MongoDB插件
由于MongoDB插件存在性能上的问题,Jmeter 3中已经将其删除(其实只是Deprated,标记未来不可用,但是还是能够开启),我们需要先解除限制。
进入Jmeter目录,修改bin/user.properties
文件,在文件末尾添加:
1 | not_in_menu= |
重启Jmeter即可看到相关的插件。
操作MongoDB
首先需要添加一个MongoDB Source Config, 然后配置MongoDB的地址,并设置别名:
然后添加MongoDB Script, 配置数据库与MongoDB源的别名:
编写数据库查询语句:
要注意,数据库查询语句后面要跟上toArray()
将结果转换为JSON,否则查询的结果会显示为MongoDB服务器的状态而非数据库中的数据。
将ID保存为变量
在MongoDB Script下添加一个BeanShell PostProcessor, 编写代码将读取到的ID信息以“ID_number”的形式存为变量。
BeanShell 脚本:
1 | import com.alibaba.fastjson.*; |
可以看到我将ID存入的是props
(properties)而非vars
(variables),原因在于前者可以在线程组间共享。如果存入vars,在执行测试的线程组中就无法读取到ID信息了。
计数器
为了能让每个线程读取到的ID不同,需要为每个线程配置唯一的变量与ID参数对应。使用计数器Counter就能完成,他会为每个线程配置从“Starting value”开始的唯一数值,正好与ID对应。
Starting value:表示从那个数值开始递增,我们从0开始即可;
Increment:表示增量,取1;
Reference Name:用来获取Counter在当前线程中的值,设置为count
,在线程中调用${count}
就能获取到真实的counter值:
测试执行线程组
新建一个线程组,添加Debug Sampler和BeanShell Sampler,以及结果察看树。
为了方便查看结果,以及演示,就不发HTTP请求,而改为用BeanShell直接输出读取到的数据。
BeanShell中,使用${count}
获取计数器的值,再通过props.get
获取ID的值,然后打印出来:
最后Test Plan树展示
参考
- How to Load Test MongoDB with JMeter, Dmitri Tikhanski, Apr. 28th, 2015
推荐阅读
- What is different between props and vars object in JMeter, Stack Overflow