性能测试工具 [Jmeter+Ant+Jenkins 集成自动化实践]

麦兜珊 · 2019年11月14日 · 最后由 李佳凯 回复于 2022年06月01日 · 3877 次阅读

一、实现原理

使用 ant 任务批量跑指定目录下的 Jmeter 脚本,在 jmeter.properties 配置输出更详细的测试信息 (请求入参、image 请求出参、请求 URL、指定结果 jtl 文件格式为 xml),然后根据指定的 xsl 样式文件由 jtl 结果文件转换为 html 报告。

二、依赖环境

1.Jmeter+Jdk

本教程中使用的是 apache-jmeter-5.2.zip,亲们可以根据自行选择适合自己的版本安装并配置好环境变量,详细过程不再赘述,网上有很多教程。

2.Ant

  • Ant 下载地址:https://ant.apache.org/bindownload.cgi
  • 成功检查:在任何目录下执行 ant 均正常,提示 Buildfile: build.xml does not exist!
  • 使用命令:ant -f build 文件名称.xml

本教程中使用的是 apache-ant-1.10.7-bin.tar.gz,亲们可以根据自行选择适合自己的版本安装并配置好环境变量,详细过程不再赘述,网上有很多教程。

3.Jenkins

本教程中使用的是公司统一部署的 Jenkins,故不再赘述安装过程。

三、各部分集成过程

1.Jmeter+Ant 集成

  • 1)两个工具连接:把 jmeter 安装目录/extras 中的 ant-jmeter-1.1.1.jar 复制到 ant 安装目录/apache-ant-1.10.5\lib 中
  • 2)修改 jmeter 生成 jtl 文件格式:编辑 jmeter 安装目录/bin/jmeter.properties 文件,将以下设置内容粘贴进去,设置生成的 jtl 文件格式是 xml,并且打印出详细的请求 url、请求入参、请求出参等信息

特别注意其中的 xsl 样式文件,jmeter 安装目录/extras 下有 jmeter 自带的两个.xsl 样式,ant 就是根据这个样式完成的从 jtl 文件到 html 文件的转换,可以使用 jmeter 自带的也可使用自定义的,网上使用比较多的就是 jmeter.results.shanhe.me.xsl,得到的测试结果更新更加的详细,推荐使用这个。没找到粘贴文件的地方,大家网上百度这个样式吧,很容易找到。

#设置jemter的jtl结果文件中打印以下内容,使测试结果更详细
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
#设置jmeter生成的jtl文件是xml格式的
jmeter.save.saveservice.output_format=xml
  • 3)编辑 build.xml 文件:以下内容是 ant 构建任务依赖的 build.xml 文件内容,只需要修改其中的 jmeter 安装目录,生成报告的目录,以及 jmeter 脚本存放目录即可。执行过程为:首先执行指定的 jmeter 的.jmx 脚本,生成 xml 格式的 jtl 文件,然后根据

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="ant-jmeter-test" default="run" basedir=".">
    <tstamp>
        <format property="time" pattern="yyyyMMddhhmm" />
    </tstamp>
    <!-- 需要改成自己本地的 Jmeter 目录-->  
    <property name="jmeter.home" value="/Users/tal/css/ProgramFiles/apache-jmeter-5.1.1" />
    <!-- jmeter生成jtl格式的结果报告的路径--> 
    <property name="jmeter.result.jtl.dir" value="./jtl" />
    <!-- jmeter生成html格式的结果报告的路径-->
    <property name="jmeter.result.html.dir" value="./html" />
    <!-- 生成的报告的前缀-->  
    <property name="ReportName" value="TestReport" />
    <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" />
    
    <!-- ant构建顺序控制,先执行test任务中的指定的jmeter脚本,生成jtl文件,然后执行report任务,根据jtl文件生成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="./addPerson-V1.0.1" 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}"
              <!-- jmeter安装目录/extras下有jmeter自带的两个.xsl样式ant就是根据这个样式完成的从jtl文件到html文件的转换可以使用jmeter自带的也可使用自定义的网上使用比较多的就是jmeter.results.shanhe.me.xsl得到的测试结果更新更加的详细推荐使用这个 --> 
              style="${jmeter.home}/extras/jmeter.results.shanhe.me.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>
    

2.Jmeter+Ant+Jenkins 集成

创建一个风格自由的 job 任务,下面是 job 的配置步骤

  • 1)配置 git:将 jmeter 脚本放置在 git 仓库中,每次构建 job 的时候自动从 git 仓库中拉取最新的脚本执行
  • 2)调用 ant 命令执行 build.xml:我这里使用的是 shell 命令执行,也可以使用 invoke ant 执行均可
  • 3)调用 publish html reports 插件显示生成的 html 报告:配置生成的 html 报告的路径,每次构建完毕可以展示出 html 报告
  • 4)最后生成的报告:

四、踩坑记录

1.jenkins

1)脚本及目录中禁止出现中文字符,否则在 Jenkins 中访问会出错找不到
2)执行 Execute shell 中可能会出现 jmeter 命令 not found,各种命令 not found
解决方案:重新 export 一下环境变量

2.jemter

1)生成的 jtl 文件中 response data 显示:Non-TEXT response data, cannot record: ()
原因分析:通过查看 jmeter 源码发现:如果接口的返回 response header 中没有 content_type 字段,则会导致源码判断中条件不满足,触发此错误
接口没有返回 content_type:

接口返回 content_type:

Jmeter 源码

//包含在https://github.com/apache/jmeter/blob/master/src/core/src/main/java/org/apache/jmeter/save/converters/SampleResultConverter.java类中
public static final String TEXT = "text"; // $NON-NLS-1$
protected void saveResponseData(HierarchicalStreamWriter writer, MarshallingContext context, SampleResult res,
            SampleSaveConfiguration save) {
        if (save.saveResponseData(res)) {
            writer.startNode(TAG_RESPONSE_DATA);
            writer.addAttribute(ATT_CLASS, JAVA_LANG_STRING);
            try {
                if (SampleResult.TEXT.equals(res.getDataType())){
                    writer.setValue(new String(res.getResponseData(), res.getDataEncodingWithDefault()));
                } else {
                    writer.setValue("Non-TEXT response data, cannot record: (" + res.getDataType() + ")");
                }
                // Otherwise don't save anything - no point
            } catch (UnsupportedEncodingException e) {
                writer.setValue("Unsupported encoding in response data, cannot record: " + e);
            }
            writer.endNode();
        }
        if (save.saveFileName()){
            writer.startNode(TAG_RESPONSE_FILE);
            writer.addAttribute(ATT_CLASS, JAVA_LANG_STRING);
            writer.setValue(res.getResultFileName());
            writer.endNode();
        }
    }

解决方案
1)修改 jmeter 源码把 if 判断去掉
2)简单粗暴的方式:是把出错的 response data 通过 beanshell 的方式写入到一个专门的文件中,作为补救措施

共收到 4 条回复 时间 点赞

Jenkins 拼写错了。😓

t-bug 回复

多谢提醒,改一下,哈哈哈

老实说 这一套比市面上那些形形色色的自动化平台可好用一百倍了

这边遇到过一个问题是 ant+jmeter 返回 response_data 的时候如果 response_data 里有特殊字符保存 xml 就失败,大家有遇到吗

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