共计 22396 个字符,预计需要花费 56 分钟才能阅读完成。
一、什么是接口测试?
接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。
接口测试适用于为其他系统提供服务的底层框架系统和中心服务系统,主要测试这些系统对外部提供的接口,验证其正确性和稳定性。接口测试同样适用于一个上层系统中的服务层接口,越往上层,其测试的难度越大。
接口测试实施在多系统多平台的构架下,有着极为高效的成本收益比,接口测试天生为高复杂性的平台带来高效的缺陷监测和质量监督能力。平台越复杂,系统越庞大,接口测试的效果越明显。
基于接口测试的重要性,以及它比较容易自动化的特性,通过持续集成的接口监控能够及时的发现项目中存在的问题,这对持续运营的项目来说,非常重要。
二、接口测试的流程
三、编写接口测试脚本
如上图是添加了一个简单的接口及组成的部件,有需要可以加入逻辑控制器,后置正则处理器,以及其他的监听器。
对于用例的管理,不同模块的用例可以加入逻辑控制器,对组合的接口需要用到后置正则,对于需要连接数据库的需要下载 MySQL JDBC driver(http://dev.mysql.com/downloads/connector/j/5.1.html), 拷贝这个文件到 JMeter 安装路径下的“lib” 文件夹,建立“JDBC Connection Configuation”
四、生成测试报告
采用 ant 的方式,首先下载 ant 的安装包,解压配置环境变量。
表示配置 ant 成功
○ 配置 build.xml 文件,也可以使用 C:\apache-jmeter-2.12\extras 目录下的 build.xml 默认文件。
<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。
在 C:\apache-jmeter-2.12\resultLog\html 目录下可以看到生成的 html 格式的报告
五、配置持续集成
在 jenkins 安装插件 HTML Publisher plugin,Performance plugin。
新建 job 配置如下:
保存配置,构建 job,查看 Console Output 如下:
可以查看 html 格式的测试报告和性能曲线,测试报告和本地生成的一致,性能曲线如下:
还可以配置定时执行时间,每次 build,发送邮件。
六、优化测试报告
○ 修改 jmeter.properties 文件,打开一些输出内容开关
指定测试报告的输出模板,具体参考 http://www.linuxidc.com/Linux/2017-01/139822.htm
build.xml:
<!–
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:
<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) > 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 生成测试报告:
展示了比默认的测试报告更多的接口信息。
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-01/139821.htm