Jmeter(4)、命令行和ant的集成
1·性能更好:命令行比GUI模式消耗的资源更少。
2·更方便的和其他工具的集成。
·Jmeter的命令行模式的准备工作:Jmeter的bin目录配置在系统的环境变量path中。
·Jmeter命令行模式的参数详解:
普通参数
·-? 是列出Jmeter的命令参数的列表和简要说明。
·-h 显示的是Jmeter自带的命令行的帮助信息。
·-n 表示以non GUI模式,即命令行模式运行Jmeter。该参数不会独立使用,会结合其它参数一起使用。
·-t 是用来指定要执行的jmeter的脚本。jmeter的脚本格式为*.jmx。
·-l l是指log,是用来指定存储运行的测试结果的结果文件。建议后缀是*.jtl.
示例:jmeter -n -t badboy_phpwind_fatie.jmx -l results\1.jtl
表示以命令行模式运行当前目录下的脚本badboy_phpwind_fatie.jmx,并且将结果存入当前目录下的results\1.jtl。
PS:在命令行模式运行脚本,脚本(GUI模式下)本身所添加的监听器组件都是无效,最终写入测试结果文件的信息,是由jmeter的配置文件jmeter.properties决定。搜索“Results file”
·命令行模式下,两次日志文件名称相同的话,采用的是追加而不是覆盖方式。
传参的参数
·-D 允许我们在命令行模式传入System properties。即允许我们传入Jmeter的属性变量。该变量在jemter.properties中设置;如果要使用-D,前提条件是脚本中做出了相应的处理。在脚本中,通过__P或者__Property函数来预接收属性变量。参数格式为:
-D属性名=属性值,如果有多个参数要传递,则使用多个-D参数。示例:
jmeter -n -t badboy_phpwind_fatie.jmx -l results\4.jtl -Dthread.num=8
表示以命令行模式运行当前目录下的脚本badboy_phpwind_fatie.jmx,并且将结果存入当前目录下的results\4.jtl,并且传入属性变量thread.num=8
分布式运行的参数
·-r 远程全部启动方式,即远程全部启动控制机上的jmeter.properties中所配置的负载机。
·-R 远程全部启动方式,但是不会去读取jmeter.properties中所配置的负载机。而是直接在-R之后指定。
格式为:
-R ip1:port1,ip2:port2... ip1和ip2就表示负载机的IP地址。
·-G 和-D的作用类似,但是定义的是Global Properties,是做分布式负载的时候使用。
因为分布式负载时,使用-D传递的值,是无法影响到负载机的。
·-X 表示远程全部退出。是结合-r或者-R使用的,表示在测试完毕之后,直接关闭远程的jmeter-server。
报告生成的参数
·-e 表示直接生成html格式的报告。
·-o 表示指定生成的报告所存储的路径。
PS: -e参数都是需要结合-o参数使用的。
示例:jmeter -n -t badboy_phpwind_fatie.jmx -l results\7.jtl -Dthread.num=7 -e -o results\html\h1
表示以命令行模式运行当前目录下的脚本badboy_phpwind_fatie.jmx,并且将结果存入当前目录下的results\4.jtl,并且传入属性变量thread.num=7。最后生成html报告,存入指定目录results\html\h1中。
·-g 表示通过已经存在的jtl结果文件来生成html报告。结合-o命令使用。
示例:jmeter -g results\4.jtl -o results\html\h3
表示根据已经存在的结果文件results\4.jtl生成html报告,并且存入results\html\h3目录下。
PS:-e和-g参数,要求结果文件的数据输出保存格式是csv格式。在Jmeter.properties搜索results file设置格式
-o参数指定的目录,必须是空目录。
Ant+Jmeter的集成:
·Ant的下载和安装:ant的下载地址:https://ant.apache.org/bindownload.cgi
下载下来解压之后,将bin所在的目录(包含)配置到系统环境变量path中即可。
ant+jmeter的相关文件
·Jmeter和ant集成有关的文件都是存放在jmeter的extras目录之下。
·ant-jmeter-1.1.1.jar:是给ant使用的,从而可以使得ant去运行和jmeter有关的任务。
·build.xml:是官方给出的默认的ant的编译执行文件。
·jmeter-results-detail-report_21.xsl/jmeter-results-report_21.xsl:是jmeter给出的默认的报告生成的模板文件。
使用方式:直接在build.xml所在路径下执行ant命令,如果设置了jmeter变量,执行命令 ant -D变量=值
build.xml的配置(在jmeterScript路径下):
<?xml version="1.0" encoding="utf-8" ?> <project name="ant-jemter" default="all" > <tstamp> <format property="time" pattern="yyyyMMddHHmmss" /> </tstamp> <!-- 需要改成自己本地的 Jmeter 目录--> <property name="jmeter.home" value="E:\apache-jmeter-5.2.1\apache-jmeter-5.2.1" /> <!-- 指定需要执行的脚本的存放目录--> <property name="script.home" value="E:\apache-jmeter-5.2.1\jmeterScript" /> <!-- jmeter生成jtl格式的结果报告的路径--> <property name="jmeter.result.jtl.dir" value="E:\apache-jmeter-5.2.1\report\jtl" /> <!-- jmeter生成html格式的结果报告的路径--> <property name="jmeter.result.html.dir" value="E:\apache-jmeter-5.2.1\report\html" /> <!-- jmeter生成html格式的结果报告的前缀--> <property name="ReportName" value="jmeter测试报告" /> <!-- jmeter生成的结果文件的名称 --> <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}${time}.jtl" /> <!-- jmeter生成的html结果文件的名称 --> <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${time}.html" /> <target name="all"> <antcall target="run" /> <antcall target="report" /> </target> <!---指定ant-jmeter-1.1.1.jar 的位置--> <path id="jmeter.classpath"> <fileset dir="${jmeter.home}\extras"> <include name="ant-jmeter*.jar"/> </fileset> </path> <target name="run"> <taskdef name="jmeter" classpathref="jmeter.classpath" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/> <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}" > <!-- 声明要运行的脚本。“*.jmx”包含此目录下的所有jmeter脚本,可以在执行ant命令时,通过-D属性来传入file的值:ant -Dfile=fileName.jmx--> <testplans dir="${script.home}" includes="${file}" /> <!-- 加入jmeter的参数,这样可以根据需要生成jmeter的CSV报告,需要设置 jmeter.save.saveservice.output_format的value=csv <jmeterarg value="-e" /> <jmeterarg value="-o${jmeter.result.html.dir}/${time}" /> --> <!-- 声明ant执行jmeter时,传入jmeter的属性值,可以自定义。--> <property name="jmeter.save.saveservice.output_format" value="xml"/> <!-- 线程数,可以在执行ant命令时,通过-D属性来传入tn值 --> <property name="thread.num" value="${tn}" /> </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="${script.home}/jmeter-results-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>
Jmeter自定义报告模板(在jmeterScript路径下)
Jmeter默认的报告模板,和ant集成时生成的html报告是不包含tps和90%这样的数据。如果需要,则可以通过自定义报告的方式来实现。
Jmeter所提供的Jmeter+ant的方式,生成报告采用的是xlst的语法。
·自定义模板的实现:
·第一行:修改编码,使得支持中文。
·根据自身的需求,决定需要添加那些统计列。
首先要从理论层面弄清楚统计列是如何统计得到的。
TPS(每秒事务数)=总的事务数/总的场景执行时间
总的场景执行时间=最后一个请求的开始时间+最后一个请求的响应时间-第一个请求的开始时间
·先根据分析去设计和获取所需要的值:
<!--QPS/TPS --> <!-- 场景开始时间 --> <xsl:variable name="allstartTime"> <xsl:call-template name="sTime"> <xsl:with-param name="nodes" select="/testResults/*/@ts" /> </xsl:call-template> </xsl:variable> <!-- 最后一个请求的开始时间 --> <xsl:variable name="allendTime"> <xsl:call-template name="eTime"> <xsl:with-param name="nodes" select="/testResults/*/@ts" /> </xsl:call-template> </xsl:variable> <!-- 最后一个请求的响应时间 --> <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)" />
模板:参考最小值和最大值的数据处理模板,我们可以得到下列两个模板:
<!-- 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>
90%、95%line数据的获取
·首先要理解90%line的含义:是指将所有的响应时间从小到大排列,获取90%比例的位置的值
<!-- 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>
模板定义
<!-- 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>
·自定义模板的处理思路:
·明确需求:
·分析需求:获取需求对象的明确的计算公式。
·处理模板:
·加变量、引入处理对象,调用处理模板。
·加处理模板
·调用变量。