• Jenkins+Ant可持续集成Jmeter脚本


    本文讲解Jenkins如何通过Ant定时自动构建Jmeter脚本。

    前言与准备

    1、apache-ant-1.10.1和apache-jmeter-2.10安装在windows平台上

    2、jenkins安装在linux平台上(可参考我的另外一篇博文Jenkins可持续集成Python自动化脚本

    3、jmeter脚本

    一、Ant和Jmeter配置

    1、修改Jmeter的bin目录下jmeter.properties文件,配置成:jmeter.save.saveservice.output_format=xml

    2、将 jmeter的extras目录中ant-jmeter-1.1.1.jar包拷贝至ant文件目录下的lib中

    3、在jmeter目录下新建文件夹(test下的result文件夹包含html和jtl文件夹)

    4、把jmx脚本放置在test文件夹中

    5、替换apache-jmeter-2.10extras下面的build.xml文件内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="ant-jmeter-test" default="run" basedir=".">
     <taskdef resource="net/sf/antcontrib/antlib.xml" />
     <!-- (1)需要改成自己本地的 Jmeter 目录-->
    <property name="jmeter.home" value="F:apache-jmeter-2.10"/>
    <property name="report.title" value="report"/>
    <!-- (2)jmeter生成jtl格式的结果报告的路径-->
    <property name="jmeter.result.jtl.dir" value="F:apache-jmeter-2.10	est
    esultjtl"/>
    <!-- (3)jmeter生成html格式的结果报告的路径-->
    <property name="jmeter.result.html.dir" value="F:apache-jmeter-2.10	est
    esulthtml"/>
    <!-- 生成的报告的前缀 -->
    <property name="ReportName" value="TestReport"/>
    <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}.jtl"/>
    <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}.html"/>
    
    <target name="run"> 
      <antcall target="test"/>  
      <antcall target="report"/> 
      <!--antcall  target="mail"/-->    
    </target>
    <target name="test"> 
      <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>  
      <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}"> 
      <!-- (4)build.xml的存放的路径-->
        <testplans dir="F:apache-jmeter-2.10	est" 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>
     <path id="lib_classpath">
            <fileset dir="${basedir}/">
                <include name="mail*.jar" />
                <include name="activation*.jar" />
                <include name="commons-email*.jar" />
                <include name="ant-contrib*.jar" />
            </fileset>
     </path>
        <!--target name="mail">
            <for list="hanxm@thunisoft.com" param="tmp" >
                <sequential>
                  <echo>message @{tmp}</echo> 
                    <mail mailhost="smtp.thunisoft.com" mailport="25" ssl="false" subject="ant mail" messagemimetype="text/html" user="zhangjn" password="*******"  tolist="@{tmp}">
                        <from address="zhangjn@thunisoft.com" />
                        <fileset dir="${jmeter.result.html.dir}">
                           <include name="*.html" />
                           <include name="*.png" />
                          </fileset>
                        <message>支持多人同时发邮件!!&lt;br /&gt;&lt;br /&gt;</message>
                    </mail>
                </sequential>
            </for>
        </target-->
    </project>

    6、替换apache-jmeter-2.10extras下面的jmeter-results-detail-report_21文件内容

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
    <!--
       Licensed to the Apache Software Foundation (ASF) under one or more
       contributor license agreements.  See the NOTICE file distributed with
       this work for additional information regarding copyright ownership.
       The ASF licenses this file to You under the Apache License, Version 2.0
       (the "License"); you may not use this file except in compliance with
       the License.  You may obtain a copy of the License at
     
           http://www.apache.org/licenses/LICENSE-2.0
     
       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.
    -->
    
    <!-- 
        Stylesheet for processing 2.1 output format test result files 
        To uses this directly in a browser, add the following to the JTL file as line 2:
        <?xml-stylesheet type="text/xsl" href="../extras/jmeter-results-detail-report_21.xsl"?>
        and you can then view the JTL in a browser
    -->
    
    <xsl:output method="html" indent="yes" encoding="UTF-8" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
    
    <!-- Defined parameters (overrideable) -->
    <xsl:param    name="showData" select="'n'"/>
    <xsl:param    name="titleReport" select="'Load Test Results'"/>
    <xsl:param    name="dateReport" select="'date not defined'"/>
    
    <xsl:template match="testResults">
        <html>
            <head>
                <title><xsl:value-of select="$titleReport" /></title>
                <style type="text/css">
                    body {
                        font:normal 68% verdana,arial,helvetica;
                        color:#000000;
                    }
                    table tr td, table tr th {
                        font-size: 68%;
                    }
                    table.details tr th{
                        color: #ffffff;
                        font-weight: bold;
                        text-align:center;
                        background:#2674a6;
                        white-space: nowrap;
                    }
                    table.details tr td{
                        background:#eeeee0;
                        white-space: nowrap;
                    }
                    h1 {
                        margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
                    }
                    h2 {
                        margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
                    }
                    h3 {
                        margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
                    }
                    .Failure {
                        font-weight:bold; color:red;
                    }
                    
        
                    img
                    {
                      border- 0px;
                    }
                    
                    .expand_link
                    {
                       position=absolute;
                       right: 0px;
                        27px;
                       top: 1px;
                       height: 27px;
                    }
                    
                    .page_details
                    {
                       display: none;
                    }
                                    
                                    .page_details_expanded
                                    {
                                        display: block;
                                        display/* hide this definition from  IE5/6 */: table-row;
                                    }
    
    
                </style>
                <script language="JavaScript"><![CDATA[
                               function expand(details_id)
                   {
                      
                      document.getElementById(details_id).className = "page_details_expanded";
                   }
                   
                   function collapse(details_id)
                   {
                      
                      document.getElementById(details_id).className = "page_details";
                   }
                   
                   function change(details_id)
                   {
                      if(document.getElementById(details_id+"_image").src.match("expand"))
                      {
                         document.getElementById(details_id+"_image").src = "collapse.png";
                         expand(details_id);
                      }
                      else
                      {
                         document.getElementById(details_id+"_image").src = "expand.png";
                         collapse(details_id);
                      } 
                               }
                ]]></script>
            </head>
            <body>
            
                <xsl:call-template name="pageHeader" />
                
                <xsl:call-template name="summary" />
                <hr size="1" width="95%" align="center" />
                
                <xsl:call-template name="pagelist" />
                <hr size="1" width="95%" align="center" />
                
                <xsl:call-template name="detail" />
    
            </body>
        </html>
    </xsl:template>
    
    <xsl:template name="pageHeader">
        <h1><xsl:value-of select="$titleReport" /></h1>
        <table width="100%">
            <tr>
                <td align="left">Date report: <xsl:value-of select="$dateReport" /></td>
                <td align="right">Designed for use with <a href="http://jmeter.apache.org/">JMeter</a> and <a href="http://ant.apache.org">Ant</a>.</td>
            </tr>
        </table>
        <hr size="1" />
    </xsl:template>
    
    <xsl:template name="summary">
        <h2>Summary</h2>
        <table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
            <tr valign="top">
                <th># Samples</th>
                <th>Failures</th>
                <th>Success Rate</th>
                <th>Average Time</th>
                <th>Min Time</th>
                <th>Max Time</th>
            </tr>
            <tr valign="top">
                <xsl:variable name="allCount" select="count(/testResults/*)" />
                <xsl:variable name="allFailureCount" select="count(/testResults/*[attribute::s='false'])" />
                <xsl:variable name="allSuccessCount" select="count(/testResults/*[attribute::s='true'])" />
                <xsl:variable name="allSuccessPercent" select="$allSuccessCount div $allCount" />
                <xsl:variable name="allTotalTime" select="sum(/testResults/*/@t)" />
                <xsl:variable name="allAverageTime" select="$allTotalTime div $allCount" />
                <xsl:variable name="allMinTime">
                    <xsl:call-template name="min">
                        <xsl:with-param name="nodes" select="/testResults/*/@t" />
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable name="allMaxTime">
                    <xsl:call-template name="max">
                        <xsl:with-param name="nodes" select="/testResults/*/@t" />
                    </xsl:call-template>
                </xsl:variable>
                <xsl:attribute name="class">
                    <xsl:choose>
                        <xsl:when test="$allFailureCount &gt; 0">Failure</xsl:when>
                    </xsl:choose>
                </xsl:attribute>
                <td align="center">
                    <xsl:value-of select="$allCount" />
                </td>
                <td align="center">
                    <xsl:value-of select="$allFailureCount" />
                </td>
                <td align="center">
                    <xsl:call-template name="display-percent">
                        <xsl:with-param name="value" select="$allSuccessPercent" />
                    </xsl:call-template>
                </td>
                <td align="center">
                    <xsl:call-template name="display-time">
                        <xsl:with-param name="value" select="$allAverageTime" />
                    </xsl:call-template>
                </td>
                <td align="center">
                    <xsl:call-template name="display-time">
                        <xsl:with-param name="value" select="$allMinTime" />
                    </xsl:call-template>
                </td>
                <td align="center">
                    <xsl:call-template name="display-time">
                        <xsl:with-param name="value" select="$allMaxTime" />
                    </xsl:call-template>
                </td>
            </tr>
        </table>
    </xsl:template>
    
    <xsl:template name="pagelist">
        <h2>Pages</h2>
        <table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
            <tr valign="top">
                <th>URL</th>
                <th># Samples</th>
                <th>Failures</th>
                <th>Success Rate</th>
                <th>Average Time</th>
                <th>Min Time</th>
                <th>Max Time</th>
                <th></th>
            </tr>
            <xsl:for-each select="/testResults/*[not(@lb = preceding::*/@lb)]">
                <xsl:variable name="label" select="@lb" />
                <xsl:variable name="count" select="count(../*[@lb = current()/@lb])" />
                <xsl:variable name="failureCount" select="count(../*[@lb = current()/@lb][attribute::s='false'])" />
                <xsl:variable name="successCount" select="count(../*[@lb = current()/@lb][attribute::s='true'])" />
                <xsl:variable name="successPercent" select="$successCount div $count" />
                <xsl:variable name="totalTime" select="sum(../*[@lb = current()/@lb]/@t)" />
                <xsl:variable name="averageTime" select="$totalTime div $count" />
                <xsl:variable name="minTime">
                    <xsl:call-template name="min">
                        <xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@t" />
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable name="maxTime">
                    <xsl:call-template name="max">
                        <xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@t" />
                    </xsl:call-template>
                </xsl:variable>
                <tr valign="top">
                    <xsl:attribute name="class">
                        <xsl:choose>
                            <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
                        </xsl:choose>
                    </xsl:attribute>
                    <td>
                    <xsl:if test="$failureCount > 0">
                      <a><xsl:attribute name="href">#<xsl:value-of select="$label" /></xsl:attribute>
                      <xsl:value-of select="$label" />
                      </a>
                    </xsl:if>
                    <xsl:if test="0 >= $failureCount">
                      <xsl:value-of select="$label" />
                    </xsl:if>
                    </td>
                    <td align="center">
                        <xsl:value-of select="$count" />
                    </td>
                    <td align="center">
                        <xsl:value-of select="$failureCount" />
                    </td>
                    <td align="right">
                        <xsl:call-template name="display-percent">
                            <xsl:with-param name="value" select="$successPercent" />
                        </xsl:call-template>
                    </td>
                    <td align="right">
                        <xsl:call-template name="display-time">
                            <xsl:with-param name="value" select="$averageTime" />
                        </xsl:call-template>
                    </td>
                    <td align="right">
                        <xsl:call-template name="display-time">
                            <xsl:with-param name="value" select="$minTime" />
                        </xsl:call-template>
                    </td>
                    <td align="right">
                        <xsl:call-template name="display-time">
                            <xsl:with-param name="value" select="$maxTime" />
                        </xsl:call-template>
                    </td>
                    <td align="center">
                       <a href="">
                          <xsl:attribute name="href"><xsl:text/>javascript:change('page_details_<xsl:value-of select="position()" />')</xsl:attribute>
                          <img src="expand.png" alt="expand/collapse"><xsl:attribute name="id"><xsl:text/>page_details_<xsl:value-of select="position()" />_image</xsl:attribute></img>                      
                       </a>
                    </td>
                </tr>
                
                            <tr class="page_details">
                               <xsl:attribute name="id"><xsl:text/>page_details_<xsl:value-of select="position()" /></xsl:attribute>
                               <td colspan="8" bgcolor="#FF0000">
                                  <div align="center">
                         <b>Details for Page "<xsl:value-of select="$label" />"</b>
                         <table bordercolor="#000000" bgcolor="#2674A6" border="0"  cellpadding="1" cellspacing="1" width="95%">
                         <tr>
                            <th>Thread</th>
                            <th>Iteration</th>
                            <th>Time (milliseconds)</th>
                            <th>Bytes</th>
                            <th>Success</th>
                         </tr>
                                          
                         <xsl:for-each select="../*[@lb = $label and @tn != $label]">                                             
                            <tr>
                               <td><xsl:value-of select="@tn" /></td>
                               <td align="center"><xsl:value-of select="position()" /></td>
                               <td align="right"><xsl:value-of select="@t" /></td>
                               <!--  TODO allow for missing bytes field -->
                               <td align="right"><xsl:value-of select="@by" /></td>
                               <td align="center"><xsl:value-of select="@s" /></td>
                            </tr>
                         </xsl:for-each>
                         
                         </table>
                      </div>
                               </td>
                            </tr>
                
            </xsl:for-each>
        </table>
    </xsl:template>
    
    <xsl:template name="detail">
        <xsl:variable name="allFailureCount" select="count(/testResults/*[attribute::s='false'])" />
    
        <xsl:if test="$allFailureCount > 0">
            <h2>Failure Detail</h2>
    
            <xsl:for-each select="/testResults/*[not(@lb = preceding::*/@lb)]">
    
                <xsl:variable name="failureCount" select="count(../*[@lb = current()/@lb][attribute::s='false'])" />
    
                <xsl:if test="$failureCount > 0">
                    <h3><xsl:value-of select="@lb" /><a><xsl:attribute name="name"><xsl:value-of select="@lb" /></xsl:attribute></a></h3>
    
                    <table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
                    <tr valign="top">
                        <th>Response</th>
                        <th>Failure Message</th>
                        <xsl:if test="$showData = 'y'">
                           <th>Response Data</th>
                        </xsl:if>
                    </tr>
                
                    <xsl:for-each select="/testResults/*[@lb = current()/@lb][attribute::s='false']">
                        <tr>
                            <td><xsl:value-of select="@rc | @rs" /> - <xsl:value-of select="@rm" /></td>
                            <td><xsl:value-of select="assertionResult/failureMessage" /></td>
                            <xsl:if test="$showData = 'y'">
                                <td><xsl:value-of select="./binary" /></td>
                            </xsl:if>
                        </tr>
                    </xsl:for-each>
                    
                    </table>
                </xsl:if>
    
            </xsl:for-each>
        </xsl:if>
    </xsl:template>
    
    <xsl:template name="min">
        <xsl:param name="nodes" select="/.." />
        <xsl:choose>
            <xsl:when test="not($nodes)">NaN</xsl:when>
            <xsl:otherwise>
                <xsl:for-each select="$nodes">
                    <xsl:sort data-type="number" />
                    <xsl:if test="position() = 1">
                        <xsl:value-of select="number(.)" />
                    </xsl:if>
                </xsl:for-each>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template name="max">
        <xsl:param name="nodes" select="/.." />
        <xsl:choose>
            <xsl:when test="not($nodes)">NaN</xsl:when>
            <xsl:otherwise>
                <xsl:for-each select="$nodes">
                    <xsl:sort data-type="number" order="descending" />
                    <xsl:if test="position() = 1">
                        <xsl:value-of select="number(.)" />
                    </xsl:if>
                </xsl:for-each>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template name="display-percent">
        <xsl:param name="value" />
        <xsl:value-of select="format-number($value,'0.00%')" />
    </xsl:template>
    
    <xsl:template name="display-time">
        <xsl:param name="value" />
        <xsl:value-of select="format-number($value,'0 ms')" />
    </xsl:template>
        
    </xsl:stylesheet>

    二、Jenkins配置步骤

    1、设置工作空间,填写jmeter的build.xml文件所在目录

    2、构建触发器

    3、设置构建时执行的cmd命令,删除本地目录F:apache-jmeter-2.10 est esultjtl下的jtl文件后每次都会生成最新的文件

    4、设置构建后的操作,生成jenkins测试报告

    5、查看测试报告

  • 相关阅读:
    PyQt5基础应用一
    常用SQL
    常用vim命令
    原生Ajax XMLHttpRequest对象
    跨域两种解决方案CORS以及JSONP
    Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析
    Django缓存机制--rest_framework中节流源码使用的就是django提供的缓存api
    Django2.0 models中的on_delete参数
    【开发工具IDE】Eclipse 安装 Maven 的 m2eclipse 插件
    【Java】CSVUtils
  • 原文地址:https://www.cnblogs.com/szmcn/p/7799808.html
Copyright © 2020-2023  润新知