【性能】Jmeter+ant+Jenkins自动化接口测试(自定义html报告+构建后发邮件)

一、配置jmeter、Ant、jenkins环境

1.安装包准备

Jmeter:Apache JMeter - Apache JMeter™

JDK:jdk1.8.0_91

Ant:Apache Ant - Binary Distributions

Jenkins:https://jenkins.io/

2.安装并配置JDK

安装时,一直点下一步就可以,也可以选择自己想安装的目录进行安装。

2.1 配置环境变量

JAVA_HOME: 值为JDK安装目录
CLASSPATH: 值为  .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;
PATH:值为 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
2.2 验证是否配置好JDK
打开cmd,输入java -version

 

 3.安装并配置jmeter

 解压安装包即可

 3.1 配置环境变量(不配置也可以)
JMETER_HOME: 值为安装jmeter的根目录
CLASSPATH: 值为    %JMETER_HOME\lib\ext\ApacheJMeter_core.jar;%JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-2.0.jar
PATH:值为 %JMETER_HOME%\bin
 
4.安装并配置ant
 解压安装包即可
4.1 配置环境变量
ANT_HOME:值为安装ant的绝对路径
CLASSPATH:值为 %ANT_HOME%\lib;
PATH:值为 %ANT_HOME%\bin;
4.2 验证是否配置好ant
打开cmd,输入ant -version

 

 5.安装并配置jenkins

5.1.安装好以后,会出现配置jenkins的url,设置端口(我设置的是9876.可以直接用默认的8080)。创建用户(账号、密码)、点击开始,按提示走就可以
5.2.验证jenkins安装完毕;打开任意一个浏览器,输入localhost:9876(就是一开始的默认jenkins端口号 )
 

 二、Ant配置Jmeter:用ant构建命令来调动执行jmeter接口测试,并生成测试报告

1.配置库文件
1.1 将jmeter extras目录下的ant-jmeter-1.1.1.jar文件拷贝到ant安装目录下的lib文件夹中
1.2 jmete\extras目录下存放报告模板jmeter-results-detail-report_21.xsl,jmeter-results-report_21.xsl等
2.新增ant的编译文件build.xml

 https://www.cnblogs.com/kaideng/p/15909362.html

3.配置jmeter.propertise文档

 找到jmeter.properties文档,在jmeter/bin目录下,打开该文档并编辑,修改jmeter报告输出格式为xml:
改jmeter.save.saveservice.output_format=csv 为jmeter.save.saveservice.output_format=xml,并去掉前面的注释符号#

 

 4.新增文件夹,用于ant执行

内部创建三类文件夹:(result、scrpit、html)

result = 存放执行后的jmx文件结果
html = 存放将jmx执行结果进行转换为html格式文件
scrpit = 存放jmx脚本
5.新建jmeter脚本,并把跑通的脚本放在scrpit 文件夹内
6.将build.xml脚本文件当在刚创建的文件夹目录下

 

7.验证能否跑通
打开cmd,cd到我们项目的文件夹中
然后输入ant run (run为build.xml中的target name)
 三、Jenkins构建任务
1.进入jenkins,配置ant

 

 

 

 

选择ANT安装

 

 

 

 2.安装插件

2.1 生成报告插件

 

 

2.2 ant插件

 

 

 

3.配置项目
3.1 新建一个项目

 

 3.2 配置

注意:ant构建项目,默认执行的是Jenkins中workspace下的脚本,如果workspace下没有脚本则构建会不错的,我的做法是将脚本和build.xml文件都放置workspace目录下了。

 

 

 

将ant版本设置为ant安装中设定的ant名称

 

 配置报告:点击增加构建后操作步骤  并点击Public HTML reports 

 

 保存后可进行构建

 

 构建完成后,可在控制台查看输出

 

 可在jekins下查看报告:

 

 

 

 

 四、自定义html报告

 1.报告主要是引用/extras目录下的报告模板:jmeter-results-detail-report_21.xsl

2.报告自定义

问题1:Date report时间没有正确显示;MinTime、MaxTime显示NaN的问题;

解决方案:在build.xml文件内找到转换报告的内容,定义时间部分

 

 具体内容如下:

<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>

显示正常:

 

 

问题2:添加TPS。以及在列表里新增90%line、95%line

解决方案:在jmeter-results-detail-report_21.xsl内新增TPS内容(这里仅附上新增的代码,不再详解)

<xsl:template name="summary">
<h2>概述</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>
<th>TPS每秒事务数</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:variable name="allstartTime">
<xsl:call-template name="sTime">
<xsl:with-param name="nodes" select="/testResults/*/@ts" />
</xsl:call-template>
</xsl:variable>
<!-- endtime -->
<xsl:variable name="allendTime">
<xsl:call-template name="eTime">
<xsl:with-param name="nodes" select="/testResults/*/@ts" />
</xsl:call-template>
</xsl:variable>
<!-- lasttime -->
<xsl:variable name="alllastTime">
<xsl:for-each select="/testResults/*">
<xsl:if test="./@ts = $allendTime">
<xsl:value-of select="./@t" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!--QPS/TPS=-->
<xsl:variable name="alltps" select="$allCount * 1000 div ($allendTime + $alllastTime - $allstartTime)" />




<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>

<!-- TPS -->
<td align="right">
<xsl:call-template name="display-tps">
<xsl:with-param name="value" select="$alltps" />
</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>
<!-- 添加PageList 的TPS列,即每一个请求的TPS -->
<th>QPS/TPS</th>
<!-- 90%用户体验数据 列名 -->
<th>90%Line</th>
<th>95%Line</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>

<!--QPS/TPS -->
<!-- startTime -->
<xsl:variable name="startTime">
<xsl:call-template name="sTime">
<xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@ts" />
</xsl:call-template>
</xsl:variable>

<!-- endTime -->
<xsl:variable name="endTime">
<xsl:call-template name="eTime">
<xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@ts" />
</xsl:call-template>
</xsl:variable>

<!-- lastTime -->
<xsl:variable name="lastTime">
<xsl:for-each select="../*[@lb = current()/@lb]">
<xsl:if test="./@ts = $endTime">
<xsl:value-of select="./@t"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>

<!--QPS/TPS=-->
<xsl:variable name="tps" select="$count * 1000 div ($endTime + $lastTime - $startTime)" />

<!-- 90%用户体验数据 值-->
<xsl:variable name="percenttime">
<xsl:call-template name="percent90">
<xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@t" />
</xsl:call-template>
</xsl:variable>

<xsl:variable name="percenttime1">
<xsl:call-template name="percent95">
<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>

<!-- add new TPS -->
<td align="right">
<xsl:call-template name="display-tps">
<xsl:with-param name="value" select="$tps" />
</xsl:call-template>
</td>

<!--将90%line的值写入对应的列-->
<td align="right">
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="$percenttime" />
</xsl:call-template>
</td>

<td align="right">
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="$percenttime1" />
</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>


<!-- startTime template -->
<xsl:template name="sTime">
<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>

<!-- endTime template -->
<xsl:template name="eTime">
<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>

<!-- Add New display-tps -->
<xsl:template name="display-tps">
<xsl:param name="value" />
<xsl:value-of select="format-number($value,'0.00 /sec')" />
</xsl:template>

<!-- 90%line的数据处理模板 -->
<xsl:template name="percent90">
<xsl:param name="nodes" select="/.." />
<xsl:param name="mycount" select="count($nodes)" />
<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() = round($mycount * 0.9)">
<xsl:value-of select="number(.)" />
</xsl:if>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="percent95">
<xsl:param name="nodes" select="/.." />
<xsl:param name="mycount" select="count($nodes)" />
<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() = round($mycount * 0.95)">
<xsl:value-of select="number(.)" />
</xsl:if>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>


</xsl:template>


</xsl:stylesheet>

最终实现效果:

 

 

posted @ 2022-02-21 11:04  灯灯开灯  阅读(733)  评论(0)    收藏  举报