本文讲解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>支持多人同时发邮件!!<br /><br /></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 > 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 > 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、查看测试报告