新手区 对 Jenkins+ANT+Jmeter 接口测试的实践

terrychow · 2016年06月24日 · 最后由 srw123 回复于 2022年04月16日 · 5055 次阅读
本帖已被设为精华帖!

1、前言

最近感觉大家都在讲 Jenkins+jmeter+ant 或 maven 的使用,但没有说到具体怎么投入到项目使用,只有比较基本的流程说说,所以我今天要说的就是我是怎么将这个方案投入到实际中使用的,先说明一下,本人是今年 4 月份才开始学 jmeter 和 ant,之前做性能测试是用 loadrunner,接口测试使用 RobotFramework+Request 来做的,loadrunner 用来做简单接口测试太笨重而且成效不高,RobotFramework+Request 虽然可以使用数据驱动模式,但测试报告就会显示很鸡肋,因为基本是一个测试用例在循环,所以后面使用了 Jenkins+jmeter+ant 的方案

2、框架与数据准备

在做接口测试框架之前,我研究了一下 jmeter 工具特征和本身项目接口的特征,jmeter 是以请求为单位,不是以脚本或测试用例为单位,既然这样,我就可以每次循环获取接口或对应数据进行测试了,加上之前在 testerhome 上看到一些大神写的接口测试框架,其实框架是死的,思想是活的,利用这个活的特点,后面就想了一套比较简单的框架,可以看下图

是的,我的测试数据是用 Excel 管理的,Excel 的测试数据可看下图


从数据格式可以看出,做了用例的执行标识,选中为 YES 时才执行,NO 时不执行,这是一个用例选择执行的简单设计,还有请求的方法也是可以选择的,目前项目中的主要用 POST 和 GET,除此之外之后要获取的还有用例名,调用的接口和具体的测试请求数据,这就是使用 excel 管理测试用例的模块
数据准备好以后做一些全局或初始的配置,一般就是改 jmeter.properties 里面对应的配置


是的,里面这行本来是默认指定为 user.properties,但有自己个性化的需求,例如服务器和测试账号

配置基本完成,之后就是项目的目录架构,conf 就是放配置文件的,如 myuser.properties,jmx 就是对应的脚本,report 是输出的测试报告路径,res 是一些上传文件所用的测试资源等,test_data 是为后期性能测试作准备的,现在先忽略,test_suite 就是放 excel 表格的,build.xml 就不多说了,就是 ant 的执行文件

3、脚本设计

好吧,接下来就是 jmx 脚本的设计,如下图,这是一些变量的设置

还有上文提到用 myuser.properties 配置的,这些在 jmeter 中作为变量来使用

然后对于读取数据,我是用了 beanshell 写了简单的 java 读取 excel 的脚本构建起与测试数据的连接,首先是先获取测试用例数,用于设置执行循环请求的次数,这里是用前置处理器的方式获取数据的,前置处理器需要 sampler 紧接着在其后使用,不然是不会执行的,所有我把它放在了登录的请求里面


具体的代码:

String filename=vars.get("test_data");
String [] datalist=new String[20];
String content;
InputStream openfile = new FileInputStream(filename); 
Workbook wb = Workbook.getWorkbook(openfile);
Sheet FirstSheet = wb.getSheet(0);
int totalRows=FirstSheet.getRows();
int rows=totalRows-1;    //减1是因为我标题行不取,为了后面从第二行开始取
String data=rows.toString();
vars.put("row",data);   //用例行数
wb.close();

然后获取正常的测试数据是用 beanshell sampler,这个有个大坑,就是用 sampler 来获取数据的话到时在测试报告会显示出来,但实际上其不是测试用例,后面会说我目前是怎么破的,反正取数据的操作最好就是不要显示在测试报告的统计上,这里就是取到刚才所说的测试用到的值,执行标识 load,用例名称 testcase,调用接口 inter,请求方法 method,请求数据 request 以及预期结果断言 response,之前就将他们作为变量传到脚本当中


具体的代码(补充说明一下,取 excel 我是用 jxl.jar 去读的,但有部分小伙伴喜欢用 POI 去读,反正原理都是一样的,像在平时编写代码那样导入包就好了):

int i;
int k=0;
String [] datalist=new String[20];
String content;
String filename=vars.get("test_data");
String str=vars.get("rownum");
int row = Integer.parseInt(str); 
InputStream openfile = new FileInputStream(filename);  
    Workbook wb = Workbook.getWorkbook(openfile);
    Sheet FirstSheet = wb.getSheet(0);
    for(i=1;i<9;i++){                    //9是因为我表格就是9列的
        if (i!=5&&i!=6){            //表格中白色的两行不取
        Cell oCell= FirstSheet.getCell(i,row);
        content=oCell.getContents();
        datalist[k]=content;
        k++;
        }
    }
        vars.put("load",datalist[0]);     //标识
        vars.put("testcase",datalist[1]);   //用例名称
        vars.put("inter",datalist[2]);     //接口
        vars.put("method",datalist[3]);    //请求方法
        vars.put("request",datalist[4]);      //请求数据
        vars.put("response",datalist[5]);   ///断言校验
    return content;

执行的效果如下图,开始在登录完之后拿到测试用例的数量,作为循环的次数,做个计数器用来 excel 行的遍历,使用 if 控制器判断执行方法,如果是 YES 的话才执行请求,如果 method 是 POST 就是执行 POST 请求的 http sampler,GET 就执行 GET 请求的 http sampler,然后输出的请求结果会有对应的用例名称,最后在响应断言中填上 response 变量,基本的脚本设计就完成了


具体 http 请求也是很简单的


4、整理测试报告

脚本设计完以后,用 ant 去执行 jmx 就可以了,至于怎么用 ant 去执行我就不多说了,去网上搜一下大把的教程,我这里是同时输出了两份测试报告,一份是作简单的统计用,就是 jmeter-results-detail-report_21.xsl 那份


6 月 28 日更新的测试报告,统计线程组执行的请求数,更符合当前脚本测试用例的统计形式


8 月 5 日更新测试报告样式,继续慢慢优化


还有是查看测试数据详情用的,就是 jmeter-results-shanhe-me.xsl,两份报告之间做了一个比较简单的跳转,方便查看


其实在这里我是用了比较取巧的方法把之前取数据的 sampler 过滤掉了,不输出到 html 测试报告,打开输出的 jtl 看一下你就懂了


所以两份测试报告我也做了一些手脚,但这个不是明智的方法,只不过是没有办法中的办法,就是去改上文的两个 xsl
统计的


查看数据的

其实这些也是我之后要优化的地方,只是目前太急要出个方案罢了


说了那么多,还没说到 jenkins,至于怎么使用,可以看我之前写的文章:https://testerhome.com/topics/5099,大同小异,就是这样用就好

5、结束语

目前我所说的设计耗时不到两天,因为时间比较紧,就只能想出目前这个方案了,大家可以也留意到其实有很多地方是可以优化的,不过目前时间实在有点紧,所以目前只能在接口自动化测试的过程中不断地去优化框架,优化设计,毕竟目前对 jmeter 的使用也不是非常熟悉,才用了 2 个月,也希望大家多给我建议,让我可以用更好地方法去实践接口自动化测试,我只是个工作不到一年的新人,很多东西想不全是会有的,这里有很多大牛,都很值得我去学习,最后还是说那句,工具是死的,思想是活的,利用工具把自己的思想实例化为框架投入到实际应用中,这才是根本的道理,1000 个人对 jmeter 可能有 1000 种用法,反正结合自己的思想和实际,总可以找到工具的价值,好,欢迎大家卖力地吐槽我,让我能好好反思一下设计上的问题,继续优化

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
最佳回复

楼主 问一下 我用 3.3 版本的 jmeter 用你的 bean shell 语句执行的时候报错,提示:ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import java.awt.List; import java.io

.FileInputStream; import java.io

.FileNotFo . . . '' : Typed variable declaration : Method Invocation Workbook.getWorkbook,楼主知道是什么问题吗,感谢

共收到 104 条回复 时间 点赞
恒温 将本帖设为了精华贴 06月25日 01:37

有些代码的图 可以贴代码吗?

#2 楼 @lihuazhang 因为可以说明一下对应使用的 Sampler,我补一下就好了,谢谢提点

—— 来自 TesterHome 官方 安卓客户端

感觉不太适合业务场景的 case?请求依赖上一个请求的结果呢

使用 markdown 吧,方便点看代码

#4 楼 @pacerron 是的,所以我说了是简单接口的测试,如果是业务场景的话,就用回老方式吧,我现在也在做框架,业务场景可以用来跑性能,这些其实我都有考虑到的

—— 来自 TesterHome 官方 安卓客户端

#5 楼 @jphtmt 好的,我先学习一下怎么用吧,谢谢提点

—— 来自 TesterHome 官方 安卓客户端

#4 楼 @pacerron 简单接口更贴近单元测试,业务场景测试的话贴近功能集成,最好还是两种形式都做起来,更好地覆盖测试

—— 来自 TesterHome 官方 安卓客户端

#8 楼 @terrychow 感觉都这样了,还不如自己写一套测试单接口的 来的自由

#9 楼 @pacerron 是的,我感觉自己写也是会好一些,但写了还要自己维护,而且只有两天时间,写的话不仅是脚本,还有测试报告数据关联等东西要考虑,既然都做接口测试了,为何不把性能测试也留个切入点,如果能用两天把 unittest 和 multi_mechanize 或 locust 结合起来做接口性能测试框架的话,那也是可以的呀,但考虑的东西就没那么简单了,有时候工具能用就直接用了,没必要去搞那么多耗成本的,工具弄出来还不是自己用的,要结合自己项目实际和 team 的实际考虑,有现成的,还是先用着吧

你的断言这么简单?

#11 楼 @pacerron 测试用例那里可以控制的,写复杂一点可以的

—— 来自 TesterHome 官方 安卓客户端

@terrychow jmeter-results-detail-report_21.xsl 和 jmeter.results.shanhe.me.xsl 在 build.xml 中调用才可生成 html 报告
格式如:



那么如你所说生成两份报告,如果直接添加则对应提示错误:
[xslt] [Fatal Error] jmeter.results.shanhe.me.xsl:121:26: 元素类型 "xsl:if"
必须后跟属性规范 ">" 或 "/>"。无法生成
不知你这里如何实现两份 html 的生成,还有页面的跳转:

Designed for use with JMeter and Ant.变更为第二份详细的怎么判断跳转你生成的报告?

#13 楼 @geyesheng 两份报告是这么输出的,跳转的话一般固定好输出的 html 名称就好了,在 jmeter-results-detail-report_21.xsl,里面改,这里是参考了 RF 的 report 和 log 的跳转逻辑,虽然不完全,但已经足够使用
跳转也很简单,jenkins 要用的时候把两份都上传了就好

@terrychow 👍 非常感谢!不知能否将 build.xml 及配置的 xml 内容提供参考下

#15 楼 @geyesheng build.xml 我是直接拿 jmeter extras 文件夹中那个模拟做的,几乎一样,改一下路径和定义一下参数就好了,配置那个可以看 bin 底下的 user.properties,参考着做就行了

统计报告中过滤掉不需要的请求,有点不明白,你是修改的哪里,能否指点一二

想问下,这样子测试接口测试的方式,可以有办法去处理一些 workflow 的 case 吗? 比如说,一些不同单一 http request case 的组合 case,如何用 excel 去组织管理这样的 case?

#4 楼 @pacerron 想问下,你说的那种依赖上一个请求的结果的业务场景的 case,应该如何管理 case 然后实现自动化呢?

#19 楼 @jennyli90 特殊场景写特殊脚本,数据驱动可以减少重复的脚本数,但有些还是必须的,这个可以通过做用例组合,我现在也设计了,其实就是几个用例组合成一个用例组进行设计,像添加了一个表单之后删除一个表单。把两个用例组合起来用,脚本取特定的值做传递就行了,用例就以组为单位

#17 楼 @information 过滤的请求关键字是 sampler,我目前用到的只是 httpsamlper,所有在修改测试报告中红色框起来的地方就指明了是统计 httpsampler 的,然后第二份报告就判读如果请求名称是那个获取数据的,就不显示

@terrychow 感谢,按照你的方法已经解决

@terrychow 顾名思义就是业务组合测试或者叫场景测试,单一线程组里多个 http 的 request 请求,相互关联用正则取值上一个接口内容,但是有一个问题,就是 sample 统计实际的接口是存在误差的。能否加 Q 细聊一下?

@terrychow 或者你组织个群加进去共同讨论也可!

在第二份报告中我要过滤掉某些不需要的,<xsl:if test="@lb!= 这个地方我想用正则去过滤,比如 aa 开头的,我试了一下没有效果,楼主能否帮忙看下

#25 楼 @information 刚刚测试正则表达式是可以的,注意字符串等格式,有对应的结束符吧< /xsl:if >

#23 楼 @geyesheng 所以我就没有统计 sample 的,或者可以自己定制一些关键字来过滤,jmeter 毕竟是开源的,只要知道哪部分是干什么的就可以二开了

@terrychow 我的写法 提示错误

@terrychow 原来正则写错了,谢谢

@terrychow 2853903588 烦请添加下,谢谢!😀 👍

@terrychow 你设计的时候使用了前置处理器的方式获取数据行数,获取的数据是如何使用的,能否说明一下

#31 楼 @geyesheng 好的,有空加吧

—— 来自 TesterHome 官方 安卓客户端

#32 楼 @information 代码上面有写,写入到了变量 ${row}中,作为循环控制器的循环次数

#19 楼 @jennyli90 自动化的不难,用 jmeter 的正则表达式取结果,变为变量

vars 是要引用什么 jar 包吗

#36 楼 @information jmeter 自带

—— 来自 TesterHome 官方 安卓客户端

你的 java 请求里面还有一个获取测试数据的对应行,在 String str=vars.get("rownum");中引用的,请问一下,这个是如何处理的啊

发现一个奇葩的问题,使用正则或者 json path 无法提取中文

#39 楼 @information 转码,或先设定为 utf-8,int row = Integer.parseInt(str); 取得的 str 本来是多少行的意思,转回为整型,用来循环遍历

区曼 [该话题已被删除] 中提及了此贴 07月05日 22:48

@terrychow 群主,方便把整个 jmx 发我参考一下吗?

#42 楼 @allanwendy 我在文章中已经展示出来啦,还是试试自己编写起来吧,不难的

#44 楼 @terrychow 很多你的都没有展示出来哈,我是想拿过来参考一下下

学习了学习了。。。之前用 Jenkins+soapui,后来用 jenkins+ant+testng+httpclient 完成的

#46 楼 @leeforleslie 我是为了简化代码工作量,本来也想用 python 写框架做,后面还是算了,能用的工具不用白不用

int i;
int k=0;
String [] datalist=new String[20];
String content;
String filename=vars.get("test_data");
String str=vars.get("rownum");
int row = Integer.parseInt(str);
InputStream openfile = new FileInputStream(filename);

Workbook wb = Workbook.getWorkbook(openfile);
Sheet FirstSheet = wb.getSheet(0);
for(i=1;i<9;i++){ //9 是因为我表格就是 9 列的
if (i!=5&&i!=6){ //表格中白色的两行不取
Cell oCell= FirstSheet.getCell(i,row);
content=oCell.getContents();
datalist[k]=content;
k++;
}
}
vars.put("load",datalist[0]); //标识
vars.put("testcase",datalist[1]); //用例名称
vars.put("inter",datalist[2]); //接口
vars.put("method",datalist[3]); //请求方法
vars.put("request",datalist[4]); //请求数据
vars.put("response",datalist[5]); ///断言校验
return content;

这段代码执行报错
Response code: 500
Response message: org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import java.awt.List; import java.io.FileInputStream; import java.io.FileNotFoun . . . '' : Typed variable declaration : Method Invocation Integer.parseInt

你好,按照你所描述的方法,我能把整个到用 ant 产生报告一个 html 都能搞定,最后想问下报告 html 最后你们是怎么处理展示的?我们组持续集成用的是 bamboo,然后没有找到有插件可以用来显示,如果是用 ant 发邮件的话,带 javascript 的 html 似乎无法在邮件中显示。。想问下有没有什么推荐的处理方式?

#49 楼 @jennyli90 集成到 Jenkins 中,通过插件发布就行了。

#49 楼 @jennyli90 用 jenkins 是比较好的,有成熟的 html 测试报告的插件和 jmeter 测试报告的插件,不过如果不满足的话,只能自己拿到 jtl 的数据自己做一份,我对 robotframework+jenkins 这种方式的时候就是自己做了测试报告

只有评论才能收藏?

@terrychow lz 我使用 HTML Report,点开是 404 Performance Trend 打开是空白的,有遇到过吗?

#50 楼 @allanwendy 我用了 jenkins report 插件之后又遇到一个问题,没法让 javascript 和 css 正确的执行。。 你知道怎么解决吗?

点开楼上的链接看看,专门说 jenkins 中测试报告看不到的处理的,RF 也是,在系统设置执行脚本命令那里跑一下就好

—— 来自 TesterHome 官方 安卓客户端

#56 楼 @terrychow 不好使啊,还是不行

#54 楼 @jennyli90 我现在也是这样,页面样式都乱了,跑了一下楼下哥们的连接,感觉还是不行

#58 楼 @allanwendy @jennyli90 ,再不行就 shift+F5 刷新一下测试报告页面,都不行的话重新 build 一次看看

#54 楼 @jennyli90 插件支持的 Jenkins 版本的问题,你看看

#60 楼 @allanwendy ok,多谢,搞定了,之前不知道咋回事,多谢多谢

#54 楼 @jennyli90 按照楼上的就行了,跑一下脚本,我的正常了

结果报告怎么发出去呢 用 ant 的发邮件功能还是 jenkins 的发送邮件的插件呢

#63 楼 @huiyiditou 用 ant 和 jenkins 发送邮件都只能发附件或一些简单的信息,但具体的数据还是要下载附件或者去到 jenkins 上面查看,后来我自己做了一份测试报告,直接以 html 格式作为邮件正文发送,可以用 python 爬虫爬取 jenkins 上的报告,或者自己解析 jtl 拿到具体数据来做测试报告,我目前使用第一种方法

jmeter-results-shanhe-me.xsl 求分享这个文件~~谢谢楼主大大

收藏了

#4 楼 @pacerron 可以用 Jmeter 的关联去解决

区曼 Ant+JMeter+WebDriverAgent 游记 中提及了此贴 12月22日 14:08

@terrychow ,获取测试数据对应行,怎么写的。

正好我也有需求要做 Jmeter+ant+Jenkins 的自动化接口测试。
不同的是我的用例信息保存在数据库里,数据来源不同,搞了一天。

楼主最主要的细节没写:获取测试数据对应行。
我的做法是:获取 count 循环数量的同时,获取数据的 ID 主键集合,用逗号分隔保存在一个变量里。
获取测试数据对应行时,同时保存及设置用户变量 index,index 从 0 开始计数。
index 是 ID 主键集合的索引,由于已经根据逗号分隔过了,很容易取到。
再根据得到的 ID 主键来获取数据行,完成用户参数的初始化。

再说一下,其实报告的模板我没修改得像楼主这么麻烦,我就是把 beanshell samper 的名称改成了空格,自动就过滤掉了。

还有 if 逻辑控件,注意是 == 号。

有时间我也出一个 JDBC 的接口测试实践。

其实我已经有更好的方案了,这个早已弃用😂

terrychow 回复

能出一个帖子 share 一下 idea 吗

@terrychow 可以贴一下 获取测试数据对应行 的代码吗?O(∩_∩) O 谢谢

@information 可以贴一下 获取测试数据对应行 的代码吗?O(∩_∩) O 谢谢

@zyanycall 可以 share 一下你的 ideal 吗

测试大牛哥!能把 jmx 脚本分享一下吗?最近再学习跪求了

terrychow 回复

大哥跪求 jmx 脚本

朱欢 回复

你好,报错解决了吗?

W 回复

我今天有空的话放网跑给吧

terrychow 回复

感谢感谢

W 回复

链接:http://pan.baidu.com/s/1i5423zB 密码:0zkz jmx 要配合好 execl 和 jtl 的测试报告,剩下的就自己看看吧

terrychow 回复

收到了 测试大牛哥 学习了 感谢🙏

terrychow 历历在目的 2 年 测试生活 中提及了此贴 06月13日 12:04

赞!!! 我也做了个类似的东东,底层技术都比较简单的。 框架也自带了数据驱动 + 函数封装关键字驱动 (用模块控制器模拟函数的功能)。 传送门:《脑洞大开:JMeter_xunit 接口自动化框架》https://testerhome.com/topics/8761

@terrychow 你在另外 1 个帖子里录制的 gif 图片是用什么工具录制的?

https://testerhome.com/topics/9110

terrychow Jmeter BeanShell 中怎么获取 excel 中的参数 中提及了此贴 09月16日 16:15

看帖子,7 月份就没人回复了啊

@terrychow 你的测试 Excel 表格 ,方便发我一份不? 我参考一下你的用例设计

今晚发一下

胖虎 回复

LICEcap

链接: https://pan.baidu.com/s/1nvR3YDr 密码: h9mg,上去取一下吧

terrychow 回复

多谢多谢哈

楼主 问一下 我用 3.3 版本的 jmeter 用你的 bean shell 语句执行的时候报错,提示:ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import java.awt.List; import java.io

.FileInputStream; import java.io

.FileNotFo . . . '' : Typed variable declaration : Method Invocation Workbook.getWorkbook,楼主知道是什么问题吗,感谢

朱欢 回复

哈喽 问一下 你的问题解决了吗?我也遇到跟你一样的问题😟

您好,请问您的报告现在优化成什么样的了,想把测试结果以 excel 表的格式展示用例名、方法、执行结果、comments 这种形式,应该怎么优化呢

追梦 回复

已弃用 jmeter 做接口测试😅 ,不过可以看 jtl 这个原数据,是个 xml,读 xml 写进入 excel 就好

操作不方便,最近社区已经有很多厉害的小伙伴做了一些接口自动化测试平台,比如 httprunner,用这些更好

terrychow 回复

我还以为你弃用 Jmeter 是业务不对头呢……对接口测试,现阶段的 Jmeter 比 httprunner 好多了。你还来了一句操作不方便……别误导别人了好不好。说些肯定能遇到的:httprunner 面对循环重复请求要怎么做?断言的正则表达式怎么做?出了问题怎么 debug?怎么搞定时器?不是 http(s) 协议怎么办?遇到需要校验数据库/缓存变动,只需要一个简单的 SQL,并不是 http 请求怎么弄?怎么实时看到访问结果,如果有 1000 个请求前 2 个就失败了而不需要执行后面的 998 个以免脏数据 httprunner 要怎么做?
这些问题你要打开 IDE,自己造轮子了?
我都不用说 locust 的测试性能有硬伤,协程 + 脚本语言性能的硬伤,上面这些你都搞不定,要二次开发。
别简单一句这些更好,你到底做没做过接口测试,我都怀疑。
如果是你业务不符合,就说业务的问题,别扯工具能力。

zyanycall 回复

然后呢,你来教教我怎么做吧,谢谢哈😁
我的一切观点都是主观的,觉得有用拿去,错了,没关系,和我说说也挺好的,我也思考一下,但这个需要自己判别哈,这点判别能力一个正常的成年人都还是会有滴
如果我真能误导人,那我挺佩服自己的😁

terrychow 回复

你直接用 Jmeter 就都有这些功能了。

102楼 已删除

想问下楼主, 你说的更好的方法是什么? 能分享一下吗?感谢!

我也做了一套和楼主差不多的 ,目前就是对数据复用进行回归测试没办法,还有就是业务场景,多接口依赖关系也没好办法

楼主修改后的测试报告模板可以发一下吗?

@terrychow 楼主完整的工程 jmx 和报告可以参考下么 非常感谢

测试大神,可以把整个工程给我学习一下么,刚入门的菜鸟,很慌,万分感谢

W 回复

你好,可以给楼主 (terrychow ) 的《 对 Jenkins+ANT+Jmeter 接口测试的实践》的工程,我学习一下

楼主,测试报告的 jar 包和 build.xml 的配置可以分享一下吗

109楼 已删除

大佬,请问我的 vars.get() 怎么赋值给定义的参数,日志打出来是 null

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