Jmeter+ant+Jenkins 接口自动化框架完整版

一、背景

 上一篇讲了Jmeter 接口自动化-脚本数据分离实例,我们知道怎么利用Jmeter去编写接口自动化脚本,但是接口自动化测试单有脚本是不够的,我们还需要批量跑指定接口,生成接口运行报告,定位报错接口,接口定时任务,邮件通知等功能。
批量跑指定接口:我们可以利用ant批量跑指定目录下的Jmeter脚本
生成接口运行报告:使用Jmeter(extras目录下)自带的jmeter-results-detail-report_21.xsl样式文件
定位报错接口:使用扩展的jmeter-results-shanhe-me.xsl(可自行下载,我git地址也放了)样式文件,输出的信息比自带的jmeter-results-detail-report_21.xsl
接口定时任务:使用Jenkins的build periodically完成
邮件通知:使用Jenkins的Extended E-mail Notification插件

顺序从Jmeter-》Jmeter+ant-》Jmeter+ant+Jenkins穿插原理,逐渐过渡,二中讲的是基础(可跳过),三讲的是实践,遇到的问题以及扩展。

二、Jmeter+ant+Jenkins接口自动化框架搭建

1 Jmeter

1、E:\sample下有sample.jmx的脚本文件
2、追加E:\apache-jmeter-2.13\bin到path环境变量后
环境变量配置成功验证-》dos中输入jmeter,windows会直接打开jmeter
3、Dos命令:
cd /d e: 
cd sample
jmeter -n -t sample.jmx -l log.jtl

-n 这是指定JMeter在非用户界面模式运行
-t 包含测试计划的JMX文件的名字
-l 记录取样结果的JTL文件的名字

 

这里要讲两句,我们做接口自动化还好,要是用Jmeter做负载测试时,建议写好性能脚本后,用NON GUI模式进行负载测试,即非图形化界面,也就是建议使用命令行运行!因为图形化界面会消耗资源,导致负载测试结果不精确,特别是用图形化界面时还把查看结果树给打开,查看结果树输出的结果很多,所以,写完负载测试脚本后尽量把查看结果树等调试插件给禁掉
我们启动Jmeter3.0以上版本,也有建议不要使用图形化界面进行负载测试的提示:
翻译:不要使用GUI模式进行负载测试,只用于测试创建和测试调试!

 

2 Jmeter+ant

1、下载ant后在window中设置ant环境变量:
ANT_HOME 新建:E:\Program Files\apache-ant-1.7.1
path 追加:%ANT_HOME%\bin
环境变量配置成功验证-》dos中输入ant,提示:Buildfile: build.xml does not exist!

 

2、将JMeter所在目录下extras子目录里的ant-JMeter-1.1.1.jar复制到Ant所在目录lib子目录之下,这样Ant运行时才能找到"org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"这个类,从而成功触发JMeter脚本

3、jmeter默认保存的是.csv格式的文件,所以我们先要设置一下bin/jmeter.properties文件内容,保存
jmeter.save.saveservice.output_format=xml
4、主要逻辑思路:
E:\jmeter\build下有build_smoke_report.xml文件
运行E:\jmeter\script_smoke下面的.jmx脚本,生成.jtl文件放入 E:\jmeter\report_smoke文件中
然后ant再利用指定的.xsl文件(build_smoke_report.xml定义)去解析.jtl文件,生成对应的html文件放入E:\jmeter\report_smoke中。
简写就是:跑完结果后,.xsl文件把.jtl文件转化成直观的html报告。

PS:XSL是什么
XSL是可扩展样式表语言(eXtensible Stylesheet Language)的外语缩写,是一种用于以可读格式呈现 XML(标准通用标记语言的子集)数据的语言。
易懂一点的说法:XSL可描述如何来显示 XML 文档,XSL 之于XML,就像CSS之于HTML。

build_smoke_report.xml文件中的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project name="ant-jmeter-test" default="run" basedir=".">
      <tstamp>
        <format property="time" pattern="_yyyy_MMdd_HHmmss" />
    </tstamp>
    <!-- 需要改成自己本地的 Jmeter 目录-->  
    <property name="jmeter.home" value="E:\apache-jmeter-2.13" />
    <property name="report.title" value="接口测试"/>
    <!-- jmeter生成jtl格式的结果报告的路径--> 
    <property name="jmeter.result.jtl.dir" value="E:\jmeter\report_smoke" />
    <!-- jmeter生成html格式的结果报告的路径-->
    <property name="jmeter.result.html.dir" value="E:\jmeter\report_smoke" />
    <property name="detail" value="_detail" />
    <!-- 生成的报告的前缀-->  
    <property name="ReportName" value="SmokeReport" />
    <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}${time}.jtl" />
    <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${time}.html" />

    <target name="run">
        <antcall target="test" />
        <antcall target="report" />
    </target>

    <target name="test">
        <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" />
        <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">
            <!-- 声明要运行的脚本"*.jmx"指包含此目录下的所有jmeter脚本-->
            <testplans dir="E:\jmeter\script_smoke" includes="*.jmx" />

            <property name="jmeter.save.saveservice.output_format" value="xml"/>
        </jmeter>
    </target>

    <path id="xslt.classpath">
        <fileset dir="${jmeter.home}/lib" includes="xalan*.jar"/>
        <fileset dir="${jmeter.home}/lib" includes="serializer*.jar"/>
    </path>


    <target name="report">
        <tstamp> <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm" /></tstamp>
        <xslt 
              classpathref="xslt.classpath"
              force="true"
              in="${jmeter.result.jtlName}"
              out="${jmeter.result.htmlName}"
              style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">
              <param name="dateReport" expression="${report.datestamp}"/>
       </xslt>
                <!-- 因为上面生成报告的时候,不会将相关的图片也一起拷贝至目标目录,所以,需要手动拷贝 --> 
        <copy todir="${jmeter.result.html.dir}">
            <fileset dir="${jmeter.home}/extras">
                <include name="collapse.png" />
                <include name="expand.png" />
            </fileset>
        </copy>
    </target>

</project>

Dos切换到E:\jmeter\build目录下运行:ant –f build_smoke_report.xml
提示:BUILD SUCCESSFUL代表build_smoke_report.xml文件运行成功
E:\jmeter\script_smoke目录下会生成.jtl和.html文件

 

3 Jmeter+ant+Jenkins

1、 命令行切换到jenkins.war的根目录,输入 java -jar jenkins.war
2、 浏览器输入地址http://localhost:8080显示界面,安装成功

 

3、新建一个构建自由风格的软件项目并配置

 

4、设置定时任务,这里是设置每周一到周五的8点30分运行次JOB。
定时构建语法:

  • * * * * *(五颗星,中间用空格隔开)

第一颗*表示分钟,取值0~59
第二颗*表示小时,取值0~23
第三颗*表示一个月的第几天,取值1~31
第四颗*表示第几月,取值1~12
第五颗*表示一周中的第几天,取值0~7,其中0和7代表的都是周日

 

4、构建->增加构建步骤->Invoke Ant->高级(需要去Jenkins的系统配置->Global Tool Configuration配置ant的地址),Build File中输入E:\jmeter\build\build_smoke_report.xml,保存

 

5、立即构建,运行成功,查看console output控制台输入的日志
出现BUILD SUCCESSFUL表示编译成功,跟dos运行ant –f build_smoke_report.xml效果一样

 

三、扩展的分割线

1·执行多个目录的jmx脚本


<jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">
    <!-- 声明要运行的脚本"*.jmx"指包含此目录下的所有jmeter脚本-->
    <testplans dir="E:\jmeter\script_smoke" includes="*.jmx" />

    <property name="jmeter.save.saveservice.output_format" value="xml"/>
</jmeter>

改成


<jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">
    <!-- 声明要运行的脚本"*.jmx"指包含此目录下的所有jmeter脚本-->
    <testplans dir="E:\jmeter\script_smoke" includes="*.jmx" />
    <testplans dir="E:\jmeter\script_smoke_two" includes="*.jmx" />

    <property name="jmeter.save.saveservice.output_format" value="xml"/>
</jmeter>

2.生成多个html报告

我这里是生成两个,一个简单的汇总报告,一个详细的报告(用于定位接口报错)
build_smoke_report.xml文件只利用jmeter-results-detail-report_21.xsl生成了一个html报告,想利用jmeter-results-shanhe-me.xsl生成第二个
添加属性值


<property name="detail" value="_detail" />
<property name="jmeter.result.jtlNamedetail" value="${jmeter.result.jtl.dir}/${ReportName}${time}.jtl" />
<property name="jmeter.result.htmlNamedetail" value="${jmeter.result.html.dir}/${ReportName}${time}${detail}.html" />

并且将


<target name="report">
    <tstamp> <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm" /></tstamp>
   <xslt 
          classpathref="xslt.classpath"
          force="true"
          in="${jmeter.result.jtlNamedetail}"
          out="${jmeter.result.htmlNamedetail}"
          style="${jmeter.home}/extras/jmeter-results-shanhe-me.xsl">
          <param name="dateReport" expression="${report.datestamp}"/>
   </xslt>

改为


<target name="report">
    <tstamp> <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm" /></tstamp>
    <xslt 
          classpathref="xslt.classpath"
          force="true"
          in="${jmeter.result.jtlName}"
          out="${jmeter.result.htmlName}"
          style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">
          <param name="dateReport" expression="${report.datestamp}"/>
   </xslt>
   <xslt 
          classpathref="xslt.classpath"
          force="true"
          in="${jmeter.result.jtlNamedetail}"
          out="${jmeter.result.htmlNamedetail}"
          style="${jmeter.home}/extras/jmeter-results-shanhe-me.xsl">
          <param name="dateReport" expression="${report.datestamp}"/>
   </xslt>

如果知道XML的一些语法,应该一下就能看明白,我们只是加了一个标签,然后把里面用到的属性值定义好。好吧,不懂XML语法也能看懂,哈哈。

PS:
使用jmeter-results-shanhe-me.xsl的一些前置操作
1、下载style文件:jmeter.results.shanhe.me.xsl
2、把下载的文件放到jmeter的extras目录下。
3、修改jmeter.properties文件如下部分,我这里都修改成true,这样执行完脚本后就会保存这些结果到.jtl文件里面,重启jmeter生效:

jmeter.save.saveservice.data_type=true
jmeter.save.saveservice.label=true
jmeter.save.saveservice.response_code=true
# response_data is not currently supported for CSV output
jmeter.save.saveservice.response_data=true
# Save ResponseData for failed samples
jmeter.save.saveservice.response_data.on_error=false
jmeter.save.saveservice.response_message=true
jmeter.save.saveservice.successful=true
jmeter.save.saveservice.thread_name=true
jmeter.save.saveservice.time=true
jmeter.save.saveservice.subresults=true
jmeter.save.saveservice.assertions=true
jmeter.save.saveservice.latency=true
jmeter.save.saveservice.connect_time=true
jmeter.save.saveservice.samplerData=true
jmeter.save.saveservice.responseHeaders=true
jmeter.save.saveservice.requestHeaders=true
jmeter.save.saveservice.encoding=false
jmeter.save.saveservice.bytes=true
jmeter.save.saveservice.url=true
jmeter.save.saveservice.filename=true
jmeter.save.saveservice.hostname=true
jmeter.save.saveservice.thread_counts=true
jmeter.save.saveservice.sample_count=true
jmeter.save.saveservice.idle_time=true

3.XSL文件的定制

其实XSL语法跟XML挺像的,多看看我们可以进行定制,如定义接口排序,扩展性能指标,那样我们性能测试也能利用这个生成报告,响应时间超过3秒的接口标黄显示,直观显示接口响应的性能状态,主要还是看公司的业务需求。

 


我会把扩展后的XSL也放到git地址,有需要的可以参考。

4.与Jenkins的集成

我们会用到两个插件,可到Jenkins的系统管理-》管理插件-》可选插件中搜索安装

4.1 HTML Publisher plugin

安装好HTML Publisher plugin之后,会在新建或者编辑项目时,在【增加构建后操作步骤】出现【Publish HTML reports】的选项

 

这样我们就可以在Jenkins中进行接口自动化测试报告的查看

4.2 Performance plugin

安装好Performance plugin之后,会在新建或者编辑项目时,在【增加构建后操作步骤】出现【Publish Performance test result report】的选项

 

 

仔细的朋友可以发现,我们使用HTML Publisher plugin用到了html文件,并且目录是指定的,难道每次每次生成的接口测试结果都要被覆盖?不存在的,当一个接口变动时,可通过接口历史响应,判断接口性能变化。使用HTML Publisher plugin用到了jtl文件名字是指定的,难道也要覆盖?也不存在的,这里放一下我的解决方案。

timestamp=`date +%Y%m%d%H%M%S`
pwd
rm -f ./*.html
mkdir  /jmeter/report/$timestamp
cp /jmeter/report/*.jtl /jmeter/report/$timestamp/
cp /jmeter/report/*.html /jmeter/report/$timestamp/

cp /jmeter/report/R*.html ./
rm -f /jmeter/report/latest/*.jtl
rm -f /jmeter/report/latest/*.html
cp /jmeter/report/*.jtl /jmeter/report/latest/
cd /jmeter/report/latest
mv -f *.jtl latest.jtl
rm -f /jmeter/report/*.jtl
mv -f /jmeter/report/*.html /jmeter/report/latest

思路:每次生成的两个html文件和jtl文件都放到类似20170831102019(时间戳)的目录下,保证每次的接口测试结果都能保存。
结果保存了,但是每次的jtl文件名字是不一样的,就算把jtl文件名字改成一致的,目录也是不同的,于是我们新建了一个latest目录,每次执行接口测试都保证latest目录的html和jtl文件是最新的,并且把jtl文件的名字改成latest.jtl,完美达到我们的要求。只要思想不滑坡,办法总比困难多

  • 14
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值