目录
(一)下载对应数据库的jdbc驱动jar包
(二)Jmeter导入对应数据库的jdbc驱动jar包
(三)JMeter连接Mysql数据库
(四)创建线程组
(五)创建数据库请求
(六)把从数据库查得的数据作为另一个请求的入参(针对只有1行数据处理)
方法一:使用后置处理器BeanShell PostProcessor处理结果集数据,重构变量
方法二:不需要使用后置处理器BeanShell PostProcessor,在JDBC Request是设置保存变量
方法三:其他
(七)查询结果集有多条数据的情况,一行行取值
方法一:采用__V函数拼接2个变量。
方法二:采用__BeanShell函数获取值,其中index是通过添加计数器count获取的;
写在前面:因为是边操作边写的,之前截的图有些注意事项没有说清楚,所以图片有些调整之后是后面补进去的,所以看着图片前后有点一样。但操作顺序说明是没问题的。
当然这个也是参考了各位网上的大神的经验并一一试验得出来的结果。如果有类似又未标明出处的地方,敬请原谅。
参考博客:https://www.cnblogs.com/FKdelphi/p/7670740.html
mysql的jdbc驱动包:mysql-connector-java-5.1.44-bin.jar;
下载地址:https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.44.zip
文件名:mysql-connector-java-5.1.44.zip
下载成功后解压到某个目录下。如:
JMeter需要连接数据库,就要导入对应的jdbc驱动jar包。操作步骤如下:
(1)选中【测试计划】,页面最下方【添加目录或jar包到ClassPath】,点击【浏览】;
(2)选择刚刚解压的目录里的mysql数据库的jdbc驱动jar包:mysql-connector-java-5.1.44-bin.jar;
(3)添加完成可看到对应的记录
(1)选择测试计划-右键添加配置元件-JDBC Connection Configuration
(2)填入对应的连接信息:
Variable Name for created pool:变量名,类似服务别名,可自行定义
DataBase URL:格式【jdbc:mysql://数据库地址:端口】,【jdbc:mysql://】是jdbc连接mysql数据库固定前缀
JDBC Driver Class:选择对应的驱动类
Username:用户名
Password:密码
(1)选中测试计划,右键添加线程组
(2)配置线程组参数
线程数:1
Ramp-Up时间(秒):1
循环次数:1
(1)选择线程组,右键【添加-取样器-jdbc request】
(2)为了方便我们看请求有没有成功,还是先新增一个察看结果树:选中【线程组】,右键【添加-监听器-察看结果树】
(3)配置jdbc request的内容
【Variable Name Bound to pool】要与(三)连接数据库时填写的【Variable Name for created pool】变量名一致。
【Query Type】:选择【Select Statement】。当然也可以选择insert、update等,不过我只是为了拿到数据库里的用户数据,用来作为接口测试的入参,所以select查询就足够了。
【Result Variable Name】:查询结果集的变量名;
【Handle ResultSet】:设置查询结果集的处理类型;
(4)这时候我们就可以允许一下看是否能查询到我们想要的值了。不过运行之前要先保存下来。
(5)点击允许,则执行线程组,发起jdbc request
(6)通过察看结果树,查看请求结果
(6.1)从【取样器结果】我们可以看到jdbc Request请求响应成功
(6.2)从【请求-Request Body】可以查看请求数据:检查是不是我们写的sql;或者如果之前写的sql是带参数的,这里就可以看到实际发起请求的时候,具体的参数值。
(6.3)从【响应数据-Response Body】则可以查看本次请求返回的数据。因为列较多,产生了折行。
(1)在JDBC Request下添加后置处理器,处理查询结果集:
(1.1)选择JDBC Request,右键【添加-后置处理器-BeanShell PostProcessor】
(1.2)用脚本将查询结果集中需要的字段放到新的变量里去
以下为脚本的代码:
Object member_result = vars.getObject("member_result"); vars.put("uname",member_result.get(0).get("uname").toString()); vars.put("name",member_result.get(0).get("name").toString()); |
var o_size = vars.getObject("member_result").size(); Object member_result = vars.getObject("member_result"); for(var i = 0;i vars.put("uname",member.get("uname").toString()); vars.put("name",member.get("name").toString()); } |
(2)新建一个http请求:选择线程组,右键【添加-取样器-HTTP请求】
这个是copy我们目前在测试的的一个接口,从app录制下来的脚本,里面的参数我就直接参照配置了,GET/POSt请求的区别在入门的时候就了解下就知道了。简单来说,Get相对简单,一般是为了获取数据;POST相对比较安全,更多用来交互数据。
(3)因为我用到的接口是带信息头的,所以还要在对应的请求下添加一个【http信息头管理器】,配置对应的信息头数据。
(3.1)选择http请求,右键【添加-配置元件-HTTP信息头管理器】
(3.2)添加信息头的参数:每个接口要求的信息头参数都不一样,所以这里只能根据各自具体的接口说明/文档来填写。
(4)填写HTTP请求的内容:
协议:HTTP
服务名称或IP:访问地址
端口:8080
方法:POST。可选择GET/POST/...还有其他的,我还不熟。
路径:填写对应的接口路径
内容编码:utf-8
消息体数据:我这个接口的参数的json格式的。对应的参数引用格式为:${变量名}
(6)保存,运行,察看结果树
(6.1)【取样器结果】:成功
(6.2)【请求-Request Body】对应的参数值,取值正确;
(6.3)【响应数据-Response Body】:响应数据返回正确;
(1)保存查询sql结果字段
参考博客:https://www.cnblogs.com/wuyonghuan/p/7479582.html
ariable Name: 数据库连接池的名字,需要与上面配置的JDBC Connection Configuration中Variable Name Bound Pool的Variable Name相同
Query:填写的sql语句未尾不要加“;”
Parameter valus:参数值
Parameter types:参数类型,可参考:Javadoc for java.sql.Types
Variable names:保存sql语句返回结果的变量名
Result variable name:创建一个对象变量,保存所有返回的结果
Query timeout:查询超时时间
Handle result set:定义如何处理由callable statements语句返回的结果
variables names设置为A,,C,那么如下变量会被设置为:
A_#=2 (总行数)
A_1=第1列, 第1行
A_2=第1列, 第2行
C_#=2 (总行数)
C_1=第3列, 第1行
C_2=第3列, 第2行
如果返回结果为0,那么A_#和C_#会被设置为0,其它变量不会设置值。
如果第一次返回6行数据,第二次只返回3行数据,那么第一次那多的3行数据变量会被清除。
可以使用${A_#}、${A_1}...来获取相应的值
(2)HTTP请求,可以直接使用JDBC Request 的设置的字段变量来进行传值,格式如图:${uname_1}、${name_1}
(3)保存、运行、察看结果树
(3.1)JDBC Request的【响应数据-Response Body】
(3.2)HTTP请求,【取样器结果】,请求响应成功
(3.3)HTTP请求,【请求-Request Body】,变量传值正确
(3.4)HTTP请求,【响应数据-Response Body】,响应数据正确
如果只是单纯为了传个值,还是很简单的,可以用正则表达式设置一个变量,也可以直接从数据库查询到数据直接把实际值代入使用就可以了。但我们更多想实现的是,从数据库获取数据,将符合条件的数据(通常不止一行)来循环调用http请求来进行接口测试/压力测试。
参考博客:
https://blog.csdn.net/defonds/article/details/41476727
https://www.cnblogs.com/beiank/p/9030792.html
2个变量的拼接,以下4种方式都是错误的:
1.${account_index} 2.${account_${index}} 3.${account}_${index} 4.${__V(${account} _${index})} |
正确的方式是:${__V(account _${index})}
(1)添加一个循环控制器:目标接口放入到循环控制器下,另外添加一个计数器,因为我们取的值是根据${username_N}来取的,那么这个N可以通过计数器递增的方式获得。
(2)将目标HTTP请求移到循环控制器里
(3)新增计数器:选择循环控制器,右键【添加-配置元件-计数器】。因为我们有2个字段作为参数,所以添加2个计数器。
(3)生成函数:选项-函数助手对话框
参考说明:https://www.cnblogs.com/wuyonghuan/p/7479582.html
函数__V可以用于执行变量名表达式,并返回执行结果。它可以被用于执行嵌套函数引用(目前JMeter不支持)。
例如,如果存在变量A1、A2和N=1,则:
${A1}:能正常工作。
${A${N}}:无法正常工作(嵌套变量引用)。
${__V(A${N})}:可以正常工作。A${N}变为A1,函数 __V返回变量值A1。
生成2个函数:${__V(uname_${N},)}、${__V(name_${N},)}
(4)将生成的函数作为变量使用,替换HTTP请求中需要参数化的参数值:
(5)JDBC Request,修改一下查询sql,查询结果集会返回多条数据;
(6)选择线程组,设置循环次数=2(我们以2条数据来举例子)
(7)保存、清除察看结果树的记录、运行、察看结果树
(7.1)第一个HTTP请求数据:【请求-Request Body】
(7.2)第一个HTTP请求的响应数据:【响应-Response Body】
(7.3)第二个HTTP请求数据:【请求-Request Body】
(7.4)第二个HTTP请求的响应数据:【响应-Response Body】
当然,如果是压测需要的话,还可以添加聚合报告来自动生成聚合报告来评估压测结果。这里就不再详细说明。
其实这个方法看起来更简单,但不知道哪里搞错了还是怎么样,这个方法我试验了几次都没出来正确的结果。待后续试验出来再补充进去吧。
参考博客:https://www.cnblogs.com/beiank/p/9030792.html
${__BeanShell(vars.getObject("result").get(${__intSum(${index},-1)}).get("account"))}
${__BeanShell(vars.getObject("result").get(${__intSum(${index},-1)}).get("password"))}