阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

JMeter接口测试实践

421次阅读
没有评论

共计 22396 个字符,预计需要花费 56 分钟才能阅读完成。

一、什么是接口测试?

接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。
接口测试适用于为其他系统提供服务的底层框架系统和中心服务系统,主要测试这些系统对外部提供的接口,验证其正确性和稳定性。接口测试同样适用于一个上层系统中的服务层接口,越往上层,其测试的难度越大。
接口测试实施在多系统多平台的构架下,有着极为高效的成本收益比,接口测试天生为高复杂性的平台带来高效的缺陷监测和质量监督能力。平台越复杂,系统越庞大,接口测试的效果越明显。
基于接口测试的重要性,以及它比较容易自动化的特性,通过持续集成的接口监控能够及时的发现项目中存在的问题,这对持续运营的项目来说,非常重要。

二、接口测试的流程

JMeter 接口测试实践

三、编写接口测试脚本

JMeter 接口测试实践

如上图是添加了一个简单的接口及组成的部件,有需要可以加入逻辑控制器,后置正则处理器,以及其他的监听器。

对于用例的管理,不同模块的用例可以加入逻辑控制器,对组合的接口需要用到后置正则,对于需要连接数据库的需要下载 MySQL JDBC driver(http://dev.mysql.com/downloads/connector/j/5.1.html), 拷贝这个文件到 JMeter 安装路径下的“lib” 文件夹,建立“JDBC Connection Configuation”

四、生成测试报告

采用 ant 的方式,首先下载 ant 的安装包,解压配置环境变量。

JMeter 接口测试实践

表示配置 ant 成功

○ 配置 build.xml 文件,也可以使用 C:\apache-jmeter-2.12\extras 目录下的 build.xml 默认文件。

<?xml version=”1.0″ encoding=”UTF-8″?>

<projectname=”ant-jmeter-test” default=”all” basedir=”.”>
    <tstamp>
        <formatproperty=”time” pattern=”yyyyMMddhhmm” />
    </tstamp>
    <!– 需要改成自己本地的 Jmeter 目录 –>
    <propertyname=”jmeter.home” value=”C:\apache-jmeter-2.12″ />
    <!– jmeter 生成 jtl 格式的结果报告的路径 –>
    <propertyname=”jmeter.result.jtl.dir” value=”C:\apache-jmeter-2.12\resultLog\jtl” />
    <!– jmeter 生成 html 格式的结果报告的路径 –>
    <propertyname=”jmeter.result.html.dir” value=”C:\apache-jmeter-2.12\resultLog\html” />
    <!– 生成的报告的前缀 –>
    <propertyname=”ReportName” value=”TestReport” />
    <propertyname=”jmeter.result.jtlName” value=”${jmeter.result.jtl.dir}/${ReportName}${time}.jtl” />
    <propertyname=”jmeter.result.htmlName” value=”${jmeter.result.html.dir}/${ReportName}${time}.html” />

    <targetname=”all”>
        <antcalltarget=”test” />
        <antcalltarget=”report” />
    </target>
   
    <targetname=”test”>
        <taskdefname=”jmeter” classname=”org.programmerplanet.ant.taskdefs.jmeter.JMeterTask” />
        <jmeterjmeterhome=”${jmeter.home}” resultlog=”${jmeter.result.jtlName}”>
            <!– 声明要运行的脚本。”*.jmx” 指包含此目录下的所有 jmeter 脚本 –>
            <testplansdir=”C:\apache-jmeter-2.12\testcase” includes=”*.jmx” />
            <propertyname=”jmeter.save.saveservice.output_format” value=”xml”/>
        </jmeter>
    </target>

    <targetname=”report”>
        <xsltin=”${jmeter.result.jtlName}”
              out
=”${jmeter.result.htmlName}”
              style
=”${jmeter.home}/extras/jmeter-results-shanhe-me.xsl” />

        <!– 因为上面生成报告的时候,不会将相关的图片也一起拷贝至目标目录,所以,需要手动拷贝 –>
        <copytodir=”${jmeter.result.html.dir}”>
            <filesetdir=”${jmeter.home}/extras”>
                <includename=”collapse.png” />
                <includename=”expand.png” />
            </fileset>
        </copy>
    </target>
</project>

○ 设置脚本执行目录,将 build.xml 放在 jmeter 的根目录,新件文件夹:resultlog,testcase。在 resultlog 下面新建文件夹 html,jtl。

○ Jmeter 的 lib 包里把 xalan-2.7.2.jar 和 serializer-2.7.2.jar copy 到 Ant 的 lib 包里,C:\apache-jmeter-2.12\extras 目录下的 ant-jmeter-1.1.1.jar copy 到 Ant 的 lib 包里。

○ 在 jmeter 根目录下执行 ant。

JMeter 接口测试实践

在 C:\apache-jmeter-2.12\resultLog\html 目录下可以看到生成的 html 格式的报告

JMeter 接口测试实践

 

五、配置持续集成

在 jenkins 安装插件 HTML Publisher plugin,Performance plugin。

新建 job 配置如下:

JMeter 接口测试实践

保存配置,构建 job,查看 Console Output 如下:

JMeter 接口测试实践

JMeter 接口测试实践

可以查看 html 格式的测试报告和性能曲线,测试报告和本地生成的一致,性能曲线如下:

JMeter 接口测试实践

还可以配置定时执行时间,每次 build,发送邮件。

JMeter 接口测试实践

六、优化测试报告

○ 修改 jmeter.properties 文件,打开一些输出内容开关

JMeter 接口测试实践

指定测试报告的输出模板,具体参考 http://www.linuxidc.com/Linux/2017-01/139822.htm

build.xml:

<?xml 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.
–>
<projectname=”ant-jmeter” default=”all”>
    <description>

        Sample build file for use with ant-jmeter.jar
        See http://www.programmerplanet.org/pages/projects/jmeter-ant-task.php

    To run a test and create the output report:
        ant -Dtest=script

    To run a test only:
        ant -Dtest=script run

    To run report on existing test output
        ant -Dtest=script report

    The “script” parameter is the name of the script without the .jmx suffix.

    Additional options:
        -Dshow-data=y – include response data in Failure Details
        -Dtestpath=xyz – path to test file(s) (default user.dir).
                        N.B. Ant interprets relative paths against the build file
        -Djmeter.home=.. – path to JMeter home directory (defaults to parent of this build file)
        -Dreport.title=”My Report” – title for html report (default is ‘Load Test Results’)

        Deprecated:
        -Dformat=2.0 – use version 2.0 JTL files rather than 2.1

   </description>
   
    <!– <property name=”testpath” value=”${user.dir}”/>–>
    <propertyname=”testpath” value=”C:\apache-jmeter-2.12\testcase” />
    <propertyname=”jmeter.home” value=”${basedir}/..”/>
    <propertyname=”report.title” value=”Load Test Results”/>
   
    <!– Name of test (without .jmx)–>
    <propertyname=”test” value=”Test”/>
   
    <!– Should report include response data for failures?–>
    <propertyname=”show-data” value=”n”/>

    <propertyname=”format” value=”2.1″/>
   
    <conditionproperty=”style_version” value=””>
        <equalsarg1=”${format}” arg2=”2.0″/>
    </condition>

    <conditionproperty=”style_version” value=”_21″>
        <equalsarg1=”${format}” arg2=”2.1″/>
    </condition>

    <conditionproperty=”funcMode”>
        <equalsarg1=”${show-data}” arg2=”y”/>
    </condition>
   
    <conditionproperty=”funcMode” value=”false”>
      <not>
        <equalsarg1=”${show-data}” arg2=”y”/>
      </not>
    </condition>

    <!– Allow jar to be picked up locally–>
    <pathid=”jmeter.classpath”>
        <filesetdir=”${basedir}”>
          <includename=”ant-jmeter*.jar”/>
        </fileset>
    </path>

    <taskdef
       
name=”jmeter”
        classpathref
=”jmeter.classpath”
        classname
=”org.programmerplanet.ant.taskdefs.jmeter.JMeterTask”/>
   
    <targetname=”all” depends=”run,report”/>

    <targetname=”run”>
        <echo>funcMode = ${funcMode}</echo>
        <deletefile=”${testpath}/${test}.html”/>
        <jmeter
           
jmeterhome=”${jmeter.home}”
            testplan
=”${testpath}/*.jmx”
            resultlog
=”${testpath}/${test}.jtl”>
        <!–
            <jvmarg value=”-Xincgc”/>
            <jvmarg value=”-Xmx128m”/>
            <jvmarg value=”-Dproperty=value”/>
            <jmeterarg value=”-qextra.properties”/>
       
–>
            <!– Force suitable defaults–>
            <propertyname=”jmeter.save.saveservice.response_data” value=”true”/>
            <propertyname=”jmeter.save.saveservice.samplerData” value=”true”/>
            <propertyname=”jmeter.save.saveservice.responseHeaders” value=”true”/>
            <propertyname=”jmeter.save.saveservice.requestHeaders” value=”true”/>
            <propertyname=”jmeter.save.saveservice.encoding” value=”true”/>
            <propertyname=”jmeter.save.saveservice.url” value=”true”/>
            <propertyname=”jmeter.save.saveservice.filename” value=”true”/>
            <propertyname=”jmeter.save.saveservice.hostname” value=”true”/>
            <propertyname=”jmeter.save.saveservice.thread_counts” value=”true”/>
            <propertyname=”jmeter.save.saveservice.sample_count” value=”true”/>
            <propertyname=”jmeter.save.saveservice.idle_time” value=”true”/>
            <propertyname=”jmeter.save.saveservice.output_format” value=”xml”/>
            <propertyname=”jmeter.save.saveservice.assertion_results” value=”all”/>
            <propertyname=”jmeter.save.saveservice.bytes” value=”true”/>
            <propertyname=”file_format.testlog” value=”${format}”/>
            <propertyname=”jmeter.save.saveservice.response_data.on_error” value=”${funcMode}”/>
        </jmeter>
    </target>

    <propertyname=”lib.dir” value=”${jmeter.home}/lib”/>

    <!– Use xalan copy from JMeter lib directory to ensure consistent processing with Java 1.4+–>
    <pathid=”xslt.classpath”>
        <filesetdir=”${lib.dir}” includes=”xalan*.jar”/>
        <filesetdir=”${lib.dir}” includes=”serializer*.jar”/>
    </path>

    <targetname=”report” depends=”xslt-report,copy-images”>
        <echo>Report generated at ${report.datestamp}</echo>
    </target>

    <targetname=”xslt-report” depends=”_message_xalan”>
        <tstamp><formatproperty=”report.datestamp” pattern=”yyyy/MM/dd HH:mm”/></tstamp>
        <xslt
           
classpathref=”xslt.classpath”
            force
=”true”
            in
=”${testpath}/${test}.jtl”
            out
=”${testpath}/${test}.html”
            style
=”C:\apache-jmeter-2.12\extras\jmeter-results-shanhe-me.xsl”>
            <paramname=”showData” expression=”${show-data}”/>
            <paramname=”titleReport” expression=”${report.title}”/>
            <paramname=”dateReport” expression=”${report.datestamp}”/>
        </xslt>
    </target>

    <!– Copy report images if needed–>
    <targetname=”copy-images” depends=”verify-images” unless=”samepath”>
        <copyfile=”${basedir}/expand.png” tofile=”${testpath}/expand.png”/>
        <copyfile=”${basedir}/collapse.png” tofile=”${testpath}/collapse.png”/>
    </target>

    <targetname=”verify-images”>
        <conditionproperty=”samepath”>
                <equalsarg1=”${testpath}” arg2=”${basedir}” />
        </condition>
    </target>

    <!– Check that the xalan libraries are present–>
    <conditionproperty=”xalan.present”>
          <and>
              <!– No need to check all jars; just check a few–>
            <availableclasspathref=”xslt.classpath” classname=”org.apache.xalan.processor.TransformerFactoryImpl”/>
            <availableclasspathref=”xslt.classpath” classname=”org.apache.xml.serializer.ExtendedContentHandler”/>
          </and>
    </condition>

    <targetname=”_message_xalan” unless=”xalan.present”>
          <echo>Cannot find all xalan and/or serialiser jars</echo>
        <echo>The XSLT formatting may not work correctly.</echo>
        <echo>Check you have xalan and serializer jars in ${lib.dir}</echo>
    </target>

</project>

jmeter-result-shanhe-me.xsl:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheetxmlns:xsl=”http://www.w3.org/1999/XSL/Transform” version=”1.0″>
    <xsl:outputmethod=”html” indent=”no” encoding=”UTF-8″ doctype-public=”-//W3C//DTD HTML 4.01 Transitional//EN” doctype-system=”http://www.w3.org/TR/html4/loose.dtd”/>
    <xsl:strip-spaceelements=”*”/>
    <xsl:templatematch=”/testResults”>
        <htmllang=”en”>
        <head>
            <metaname=”Author” content=”shanhe.me”/>
            <title>JMeter Test Results</title>
            <styletype=”text/css”><![CDATA[
           
                * {margin: 0; padding: 0}
                html, body {width: 100%; height: 100%; background: #b4b4b4; font-size: 12px}
                table {border: none; border-collapse: collapse; table-layout: fixed}
                td {vertical-align: baseline; font-size: 12px}
                #left-panel {position: absolute; left: 0; top: 0; bottom: 0; width: 300px; overflow: auto; background: #dee4ea}
                #left-panel li.navigation {font-weight: bold; cursor: default; color: #9da8b2; line-height: 18px; background-position: 12px 5px; background-repeat: no-repeat; padding: 0 0 0 25px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAICAYAAAArzdW1AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDEBQqGbO7BEcAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAKRJREFUGNN1zM0KgkAYheF3RvtXSsGyWhRNaILS7bdt11W0KgJvoPwZp0UlBPUtz3nOJw7Hk7necv5dOA2Qaazo2vZP0LEt9olCVtqQROufKNmuqBuBNAYW4QzXGX6B0bDPcjGnMQYJ8Cg12U59oSzaUJQa4IUAXMclDHwAAn/MxPMw765FZd2QRgopBWmsKCrdfhXnS/4ZYElBXdyxewN008Y8AephLAkqz613AAAAAElFTkSuQmCC) }
                #left-panel li.success {color: #565b60}
                #left-panel li.failure {color: red}
                #left-panel li {list-style: none; color: black; cursor: pointer}
                #left-panel li.selected {background-repeat: repeat-x; color: white; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAUCAYAAABMDlehAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDEBQxLTs5O2gAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAEdJREFUCNc1y7ERgEAMA0GNUhIyGqM2uqKgtyWZhE9v53A/7/A6D7BkMDNgy2AroB2wHTCZv5UMOgFLG1bvd7XBckBlwCXjA5wMOF5iOX/MAAAAAElFTkSuQmCC) }
                #left-panel div {line-height: 20px; background-position: 25px 3px; background-repeat: no-repeat; padding: 0 0 0 45px}
                #left-panel div.success {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAOCAYAAADwikbvAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDEBULEEc6wzcAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAiNJREFUKM99kktIVGEYhp/jzJl08lI6logp2Y2EFkbtaqlFROsWrlq4ioJWQRs37VoUVItWkYEVRGSBlhleCpywDEWxTEuxcURTZ6YzxzP/5WshCOHUt36f93kXnyMi5Lsnb4clI4s4fhkXzp5w8mWcfHBvfEpUxVdCUUU6lUPNHuD86cYtBQX5GhPrM7hRg7GaSDRg2vuUd90WuOPVsOyqy6FFo2yOQHlU1S9z9dZT+S/8I7GCLlkAN4eyAf56mnT6Fy1HLnGuuYa++MS/4e74qMRqfXLaJ9BpfnsrLC0m2BYuoqwUbj/+274JD43OEqmexwvW8NUKXnaZtVSS1pNtAAyOvyC6v48HnUNb4Z7PH8UtTlIQWA5tb2RhYY7kz3l2FleytJYg/qWb8t2KZ/0PN+1hgI6uEUr2jpHKpGlquExVaS0VbjUZL7WxaqIXK6ADQ0n9GNfv9XCttWnD/O57t0TKFklnF3g5fJ/seoaa2D4O1x0F4PlgO9oIftbgFgYMfLgjACGqj0vlsddoUnj+Kt/mxunq72RP+UGqYjWMTA7R+b6dUCSEGEF5hoJQip6BaFs4HJtCyRrKs6wHCovDip/kys0WWpovMpOYBCtoT2N9B5uzWG0Zid8gnFrVFEQDtBaUrxEgXBimaEeER2/uIiK4roPOaMRYjBKsFly3fOO3G06dETGCWIsYjckprMphtEKMAQtgsMYi1mJMQHJ6xvkDKQoyphCzkl0AAAAASUVORK5CYII=) }
                #left-panel div.failure {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAOCAYAAADwikbvAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDEBUJOEC5CU8AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAeVJREFUKM+NkDtok2EUhp8vl9ZLo/EyKI6KFgqCKC4OClrBWUQEcRRx1cGpk3WyInWrgoMZKkW8thYaEYQ0i7WC2ngrNDTERHJvkv/L/3//dxwc7F8jeOAsh/c973OOEhG61aPnaen7maXYt4MLZ4+pbppQt+F06jNH3QWOb8pxUs+SmJzjv83hxY8SVy3wNdtVneiHqe54IhLoB4/TUkyMyOrKj5yXoVtPZK02kLyYK7OnlqFWzgcCGtUC/YUJ3n5a/jd28tU7ORTN0myUA6Jms8bpWIa798elqzn1fokjThrpVBC3ETzNbYAuca59j/Hp+b/N869Tsk8tgVMCXQk+RlfQuk1/tMLMwzsSMCcm5zjhvoR2AdpF0GuwO4aqttS05ZSbZHhsBoAIwI83Cdkd/460XDAOG02d24MxvlR8dsUUh3f2UHaEtgdbWCHz4oZwcVCp66PP5FLhKjEc8DXaCMsNy8DYn/SnZ+L0hhWOb/F8yLs9fDtwk8j+VpqwrlC34PrgGEu2bhlYhZ1b8dncq3AMeBaUr/k6NUyk4ChKzu+N2hc6Bqody+WDG8g2fLatD7F3axjPgmvAtYJvIbouhhIRrl0ZktnkBGIt1gqeMXQ8D2MMiCIUCqFEsFhEQMSykCuqX0MzLAUJTzRsAAAAAElFTkSuQmCC) }
                #left-panel div.detail {display: none}
                #right-panel {position: absolute; right: 0; top: 0; bottom: 0; left: 301px; overflow: auto; background: white}
                #right-panel .group {font-size: 12px; font-weight: bold; line-height: 16px; padding: 0 0 0 18px; counter-reset: assertion; background-repeat: repeat-x; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAQCAYAAADXnxW3AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDEBUkDq8pxjkAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAADdJREFUCNdVxrERwDAMAzGK0v47eS6Z927SpMFBAAbkvSvnRk5+7K5cVfLMyN39bWakJAjA5xw9R94jN3tVhVEAAAAASUVORK5CYII=) }
                #right-panel .zebra {background-repeat: repeat; padding: 0 0 0 18px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAmCAYAAAAFvPEHAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDEBYWFlNztEcAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAABdJREFUCNdjYKAtePv5338mBgYGBpoQAGy1BAJlb/y6AAAAAElFTkSuQmCC) }
                #right-panel .data {line-height: 19px; white-space: nowrap}
                #right-panel pre.data {white-space: pre}
                #right-panel tbody.failure {color: red}
                #right-panel td.key {min-width: 108px}
                #right-panel td.delimiter {min-width: 18px}
                #right-panel td.assertion:before {counter-increment: assertion; content: counter(assertion) “. ” }
                #right-panel td.assertion {color: black}
                #right-panel .trail {border-top: 1px solid #b4b4b4}
               
           
]]></style>
            <scripttype=”text/javascript”><![CDATA[
           
                var onclick_li = (function() {
                    var last_selected = null;
                    return function(li) {
                        if(last_selected == li)
                            return;
                        if(last_selected)
                            last_selected.className = “”;
                        last_selected = li;
                        last_selected.className = “selected”;
                        document.getElementById(“right-panel”).innerHTML = last_selected.firstChild.nextSibling.innerHTML;
                        return false;
                    };
                })();
               
                var patch_timestamp = function() {
                    var spans = document.getElementsByTagName(“span”);
                    var len = spans.length;
                    for(var i = 0; i < len; ++i) {
                        var span = spans[i];
                        if(“patch_timestamp” == span.className)
                            span.innerHTML = new Date(parseInt( span.innerHTML) );
                    }
                };
               
                var patch_navigation_class = (function() {
               
                    var set_class = function(el, flag) {
                        if(el) {
                            el.className += flag ? ” success” : ” failure”;
                        }
                    };
               
                    var traverse = function(el, group_el, flag) {
                        while(1) {
                            if(el) {
                                if(el.className == ‘navigation’) {
                                    set_class(group_el, flag);
                                    group_el = el;
                                    flag = true;
                                } else {
                                    var o = el.firstChild;
                                    o = o ? o.className : null;
                                    flag = flag ? (o == ‘success’) : false;
                                }
                                el = el.nextSibling;
                            } else {
                                set_class(group_el, flag);
                                break;
                            }
                        }
                    };
                   
                    return function() {
                        var o = document.getElementById(“result-list”);
                        o = o ? o.firstChild : null;
                        if(o)
                            traverse(o, null, true);
                    };
                })();
       
                window.onload = function() {
                    patch_timestamp();
                    patch_navigation_class();
                    var o = document.getElementById(“result-list”);
                    o = o ? o.firstChild : null;
                    o = o ? o.nextSibling : null;
                    if(o)
                        onclick_li(o);
                };
       
           
]]></script>
        </head>
        <body>
            <divid=”left-panel”>
                <olid=”result-list”>
                    <xsl:for-eachselect=”*”>
                        <!– group with the previous sibling–>
                        <xsl:iftest=”position() = 1 or @tn != preceding-sibling::*[1]/@tn”>
                            <liclass=”navigation”>Thread: <xsl:value-ofselect=”@tn”/></li>
                        </xsl:if>
                        <lionclick=”return onclick_li(this);”>
                            <div>
                                <xsl:attributename=”class”>
                                    <xsl:choose>
                                        <xsl:whentest=”@s = ‘true'”>success</xsl:when>
                                        <xsl:otherwise>failure</xsl:otherwise>
                                    </xsl:choose>
                                </xsl:attribute>
                                <xsl:value-ofselect=”@lb”/>
                            </div><divclass=”detail”>
                                <divclass=”group”>Sampler</div>
                                <divclass=”zebra”>
                                    <table>
                                        <tr><tdclass=”data key”>Thread Name</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@tn”/></td></tr>
                                        <tr><tdclass=”data key”>Timestamp</td><tdclass=”data delimiter”>:</td><tdclass=”data”><spanclass=”patch_timestamp”><xsl:value-ofselect=”@ts”/></span></td></tr>
                                        <tr><tdclass=”data key”>Time</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@t”/> ms</td></tr>
                                        <tr><tdclass=”data key”>Latency</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@lt”/> ms</td></tr>
                                        <tr><tdclass=”data key”>Bytes</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@by”/></td></tr>
                                        <tr><tdclass=”data key”>Sample Count</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@sc”/></td></tr>
                                        <tr><tdclass=”data key”>Error Count</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@ec”/></td></tr>
                                        <tr><tdclass=”data key”>Response Code</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@rc”/></td></tr>
                                        <tr><tdclass=”data key”>Response Message</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”@rm”/></td></tr>
                                    </table>
                                </div>
                                <divclass=”trail”></div>
                                <xsl:iftest=”count(assertionResult) &gt; 0″>
                                    <divclass=”group”>Assertion</div>
                                    <divclass=”zebra”>
                                        <table>
                                            <xsl:for-eachselect=”assertionResult”>
                                                <tbody>
                                                    <xsl:attributename=”class”>
                                                        <xsl:choose>
                                                            <xsl:whentest=”failure = ‘true'”>failure</xsl:when>
                                                            <xsl:whentest=”error = ‘true'”>failure</xsl:when>
                                                        </xsl:choose>
                                                    </xsl:attribute>
                                                    <tr><tdclass=”data assertion” colspan=”3″><xsl:value-ofselect=”name”/></td></tr>
                                                    <tr><tdclass=”data key”>Failure</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”failure”/></td></tr>
                                                    <tr><tdclass=”data key”>Error</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”error”/></td></tr>
                                                    <tr><tdclass=”data key”>Failure Message</td><tdclass=”data delimiter”>:</td><tdclass=”data”><xsl:value-ofselect=”failureMessage”/></td></tr>
                                                </tbody>
                                            </xsl:for-each>
                                        </table>
                                    </div>
                                    <divclass=”trail”></div>
                                </xsl:if>
                                <divclass=”group”>Request</div>
                                <divclass=”zebra”>
                                    <table>
                                        <tr><tdclass=”data key”>Method/Url</td><tdclass=”data delimiter”>:</td><tdclass=”data”><preclass=”data”><xsl:value-ofselect=”method”/><xsl:text> </xsl:text><xsl:value-ofselect=”java.net.URL”/></pre></td></tr>
                                        <tr><tdclass=”data key”>Query String</td><tdclass=”data delimiter”>:</td><tdclass=”data”><preclass=”data”><xsl:value-ofselect=”queryString”/></pre></td></tr>
                                        <tr><tdclass=”data key”>Cookies</td><tdclass=”data delimiter”>:</td><tdclass=”data”><preclass=”data”><xsl:value-ofselect=”cookies”/></pre></td></tr>
                                        <tr><tdclass=”data key”>Request Headers</td><tdclass=”data delimiter”>:</td><tdclass=”data”><preclass=”data”><xsl:value-ofselect=”requestHeader”/></pre></td></tr>
                                    </table>
                                </div>
                                <divclass=”trail”></div>
                                <divclass=”group”>Response</div>
                                <divclass=”zebra”>
                                    <table>
                                        <tr><tdclass=”data key”>Response Headers</td><tdclass=”data delimiter”>:</td><tdclass=”data”><preclass=”data”><xsl:value-ofselect=”responseHeader”/></pre></td></tr>
                                        <tr><tdclass=”data key”>Response Data</td><tdclass=”data delimiter”>:</td><tdclass=”data”><preclass=”data”><xsl:value-ofselect=”responseData”/></pre></td></tr>
                                        <tr><tdclass=”data key”>Response File</td><tdclass=”data delimiter”>:</td><tdclass=”data”><preclass=”data”><xsl:value-ofselect=”responseFile”/></pre></td></tr>
                                    </table>
                                </div>
                                <divclass=”trail”></div>
                            </div>
                        </li>
                    </xsl:for-each>
                </ol>
            </div>
            <divid=”right-panel”></div>
        </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

 

在当前目录执行 ant 生成测试报告:

JMeter 接口测试实践

展示了比默认的测试报告更多的接口信息。

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-01/139821.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计22396字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19350
评论数
4
阅读量
7962955
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
星哥带你玩飞牛NAS-7:手把手教你免费内网穿透-Cloudflare tunnel

星哥带你玩飞牛NAS-7:手把手教你免费内网穿透-Cloudflare tunnel

星哥带你玩飞牛 NAS-7:手把手教你免费内网穿透 -Cloudflare tunnel 前言 大家好,我是星...
【1024程序员】我劝你赶紧去免费领一个AWS、华为云等的主机

【1024程序员】我劝你赶紧去免费领一个AWS、华为云等的主机

【1024 程序员】我劝你赶紧去免费领一个 AWS、华为云等的主机 每年 10 月 24 日,程序员们都会迎来...
星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛 NAS-1:安装飞牛 NAS 前言 在家庭和小型工作室场景中,NAS(Network Atta...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...
每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站 - 手机博物馆 -CHAZ 3D Experience 一句话介绍:一个用 3D 方式重温...
Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集 在云原生体系中,Prometheus 已成为最主流的监控与报警...
星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛 NAS-11:咪咕视频订阅部署全攻略 前言 在家庭影音系统里,NAS 不仅是存储中心,更是内容...
多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞...