首先了解下生成测试报告的过程,我们看到的测试报告是由.jtl格式转换为.html,html报告的样式由extras目录下xsl文件决定。优化测试报告需要分为两部分内容,首先我们要优化输出的测试内容,其次我们才能优化报告的样式。

1.在jmeter.properties文件添加以下内容,保证执行脚本后结果保存到.jtl文件里面。

jmeter.save.saveservice.data_type=true
jmeter.save.saveservice.label=true
jmeter.save.saveservice.response_code=true
jmeter.save.saveservice.response_data=true
jmeter.save.saveservice.response_data.on_error=false
jmeter.save.saveservice.response_message=true
jmeter.save.saveservice.successful=true
jmeter.save.saveservice.thread_name=true
jmeter.save.saveservice.time=true
jmeter.save.saveservice.subresults=true
jmeter.save.saveservice.assertions=true
jmeter.save.saveservice.latency=true
jmeter.save.saveservice.connect_time=true
jmeter.save.saveservice.samplerData=true
jmeter.save.saveservice.responseHeaders=true
jmeter.save.saveservice.requestHeaders=true
jmeter.save.saveservice.encoding=false
jmeter.save.saveservice.bytes=true
jmeter.save.saveservice.url=true
jmeter.save.saveservice.filename=true
jmeter.save.saveservice.hostname=true
jmeter.save.saveservice.thread_counts=true
jmeter.save.saveservice.sample_count=true
jmeter.save.saveservice.idle_time=true

2.Jmeter测试报告扩展的样式很多,我这里下载一份比较通用jmeter.results.shanhe.me.xsl样式;

3.变更下我们的build.xml,转换时引用最新的样式;

4.使用ant构建测试报告,但是构建出来的报告信息很充足,但是无法格式化json 数据,这样展示很low,而且无法直观的观察到了返回的数据;

5.修改下xls样式文件,让展示的json数据格式化,我这边想到的办法是通过js对数据进行格式化,在xls样式文件中添加下面代码,从新生成测试报告。


var formatJson = function(json, options) {
    var reg = null,
    formatted = '',
    pad = 0,
    PADDING = '    ';
    options = options || {};
    options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true: false;
    options.spaceAfterColon = (options.spaceAfterColon === false) ? false: true;
    if (typeof json !== 'string') {
        json = JSON.stringify(json);
    } else {
        json = JSON.parse(json);
        json = JSON.stringify(json);
    }
    reg = /([\{\}])/g;
    json = json.replace(reg, '\r\n$1\r\n');
    reg = /([\[\]])/g;
    json = json.replace(reg, '\r\n$1\r\n');
    reg = /(\,)/g;
    json = json.replace(reg, '$1\r\n');
    reg = /(\r\n\r\n)/g;
    json = json.replace(reg, '\r\n');
    reg = /\r\n\,/g;
    json = json.replace(reg, ',');
    if (!options.newlineAfterColonIfBeforeBraceOrBracket) {
        reg = /\:\r\n\{/g;
        json = json.replace(reg, ':{');
        reg = /\:\r\n\[/g;
        json = json.replace(reg, ':[');
    }
    if (options.spaceAfterColon) {
        reg = /\:/g;
        json = json.replace(reg, ':');
    } (json.split('\r\n')).forEach(function(node, index) {
        var i = 0,
        indent = 0,
        padding = '';

        if (node.match(/\{$/) || node.match(/\[$/)) {
            indent = 1;
        } else if (node.match(/\}/) || node.match(/\]/)) {
            if (pad !== 0) {
                pad -= 1;
            }
        } else {
            indent = 0;
        }

        for (i = 0; i < pad; i++) {
            padding += PADDING;
        }

        formatted += padding + node + '\r\n';
        pad += indent;
    });
    return formatted;
};

最终的结果比较满意,这样一份便于观察的测试报告就生成了。

通过https://github.com/liuqiangcl/Jmeter 可以下载最新的Html的样式,重点可以格式化报告的json数据

build.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project name="ant-jmeter-test" default="all" basedir=".">
    <!--为生成的jtl和html文件加时间戳-->
    <tstamp>
        <format property="time" pattern="yyyyMMddHHmm" />
    </tstamp>
    <!--jmeter安装路径-->
    <property name="jmeter.home" value="D:\jmeter\apache-jmeter-3.2"/>
     <!--生成jtl文件结果存放路径-->
    <property name="jmeter.result.jtl.dir" value="${jmeter.home}/report/jtl"/>
    <!--生成html文件结果存放路径-->
    <property name="jmeter.result.html.dir" value="${jmeter.home}/report/html"/>
    <!--生成的结果报告的前缀-->
    <property name="ReportName" value="TestReport" />
    <!--jlt和html文件名称-->
    <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}${time}.jtl" />
    <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${time}.html" />
    <target name="all">
        <antcall target="test" />
        <antcall target="report" />
    </target>
    <target name="test">
        <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" />
        <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">
            <!--项目测试脚本jmx文件所在路径-->
            <testplans dir="${jmeter.home}/workspace" 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">
        <!--使用jmeter自己的转化文件:将jtl转化为xsl文件,改为自己的xsl文件所在路径-->
        <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-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.results.shanhe.me.xsl文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="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-space elements="*"/>
    <xsl:template match="/testResults">
        <html lang="en">
        <head>
            <meta name="Author" content="shanhe.me"/>
            <title>JMeter Test Results</title>
            <style type="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>
            <script type="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);
                    };
                })();
                var formatJson = function (json, options) {
                    var reg = null,
                            formatted = '',
                            pad = 0,
                            PADDING = '    ';
                    options = options || {};
                    options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false;
                    options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true;
                    if (typeof json !== 'string') {
                        json = JSON.stringify(json);
                    } else {
                        json = JSON.parse(json);
                        json = JSON.stringify(json);
                    }
                    reg = /([\{\}])/g;
                    json = json.replace(reg, '\r\n$1\r\n');
                    reg = /([\[\]])/g;
                    json = json.replace(reg, '\r\n$1\r\n');
                    reg = /(\,)/g;
                    json = json.replace(reg, '$1\r\n');
                    reg = /(\r\n\r\n)/g;
                    json = json.replace(reg, '\r\n');
                    reg = /\r\n\,/g;
                    json = json.replace(reg, ',');
                    if (!options.newlineAfterColonIfBeforeBraceOrBracket) {
                        reg = /\:\r\n\{/g;
                        json = json.replace(reg, ':{');
                        reg = /\:\r\n\[/g;
                        json = json.replace(reg, ':[');
                    }
                    if (options.spaceAfterColon) {
                        reg = /\:/g;
                        json = json.replace(reg, ':');
                    }
                    (json.split('\r\n')).forEach(function (node, index) {
                                var i = 0,
                                        indent = 0,
                                        padding = '';

                                if (node.match(/\{$/) || node.match(/\[$/)) {
                                    indent = 1;
                                } else if (node.match(/\}/) || node.match(/\]/)) {
                                    if (pad !== 0) {
                                        pad -= 1;
                                    }
                                } else {
                                    indent = 0;
                                }

                                for (i = 0; i < pad; i++) {
                                    padding += PADDING;
                                }

                                formatted += padding + node + '\r\n';
                                pad += indent;
                            }
                    );
                    return formatted;
                };

                window.onload = function() {
                    var objectDom =  document.getElementsByClassName("responsedata")[0];
                    var jsonObject = JSON.parse(objectDom.outerText);
                    var resultJson = formatJson(jsonObject);
                    objectDom.parentNode.innerHTML = '<pre class="data">' +resultJson + '<pre/>';
                    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>
            <div id="left-panel">
                <ol id="result-list">
                    <xsl:for-each select="*">
                        <!-- group with the previous sibling -->
                        <xsl:if test="position() = 1 or @tn != preceding-sibling::*[1]/@tn">
                            <li class="navigation">Thread: <xsl:value-of select="@tn"/></li>
                        </xsl:if>
                        <li onclick="return onclick_li(this);">
                            <div>
                                <xsl:attribute name="class">
                                    <xsl:choose>
                                        <xsl:when test="@s = 'true'">success</xsl:when>
                                        <xsl:otherwise>failure</xsl:otherwise>
                                    </xsl:choose>
                                </xsl:attribute>
                                <xsl:value-of select="@lb"/>
                            </div><div class="detail">
                                <div class="group">Sampler</div>
                                <div class="zebra">
                                    <table>
                                        <tr><td class="data key">Thread Name</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@tn"/></td></tr>
                                        <tr><td class="data key">Timestamp</td><td class="data delimiter">:</td><td class="data"><span class="patch_timestamp"><xsl:value-of select="@ts"/></span></td></tr>
                                        <tr><td class="data key">Time</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@t"/> ms</td></tr>
                                        <tr><td class="data key">Latency</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@lt"/> ms</td></tr>
                                        <tr><td class="data key">Bytes</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@by"/></td></tr>
                                        <tr><td class="data key">Sample Count</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@sc"/></td></tr>
                                        <tr><td class="data key">Error Count</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@ec"/></td></tr>
                                        <tr><td class="data key">Response Code</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@rc"/></td></tr>
                                        <tr><td class="data key">Response Message</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@rm"/></td></tr>
                                    </table>
                                </div>
                                <div class="trail"></div>
                                <xsl:if test="count(assertionResult) &gt; 0">
                                    <div class="group">Assertion</div>
                                    <div class="zebra">
                                        <table>
                                            <xsl:for-each select="assertionResult">
                                                <tbody>
                                                    <xsl:attribute name="class">
                                                        <xsl:choose>
                                                            <xsl:when test="failure = 'true'">failure</xsl:when>
                                                            <xsl:when test="error = 'true'">failure</xsl:when>
                                                        </xsl:choose>
                                                    </xsl:attribute>
                                                    <tr><td class="data assertion" colspan="3"><xsl:value-of select="name"/></td></tr>
                                                    <tr><td class="data key">Failure</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="failure"/></td></tr>
                                                    <tr><td class="data key">Error</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="error"/></td></tr>
                                                    <tr><td class="data key">Failure Message</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="failureMessage"/></td></tr>
                                                </tbody>
                                            </xsl:for-each>
                                        </table>
                                    </div>
                                    <div class="trail"></div>
                                </xsl:if>
                                <div class="group">Request</div>
                                <div class="zebra">
                                    <table>
                                        <tr><td class="data key">Method/Url</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="method"/><xsl:text> </xsl:text><xsl:value-of select="java.net.URL"/></pre></td></tr>
                                        <tr><td class="data key">Query String</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="queryString"/></pre></td></tr>
                                        <tr><td class="data key">Cookies</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="cookies"/></pre></td></tr>
                                        <tr><td class="data key">Request Headers</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="requestHeader"/></pre></td></tr>
                                    </table>
                                </div>
                                <div class="trail"></div>
                                <div class="group">Response</div>
                                <div class="zebra">
                                    <table>
                                        <tr><td class="data key">Response Headers</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="responseHeader"/></pre></td></tr>
                                        <tr><td class="data key">Response Data</td><td class="data delimiter">:</td><td class="data"><pre class="responsedata"><xsl:value-of select="responseData"/></pre></td></tr>
                                        <tr><td class="data key">Response File</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="responseFile"/></pre></td></tr>
                                    </table>
                                </div>
                                <div class="trail"></div>
                            </div>
                        </li>
                    </xsl:for-each>
                </ol>
            </div>
            <div id="right-panel"></div>
        </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

Jmeter 自动化测试报告扩展的更多相关文章

  1. Jmeter 自动化测试报告扩展(转 Todo 需要修正)

    首先了解下生成测试报告的过程,我们看到的测试报告是由.jtl格式转换为.html,html报告的样式由extras目录下xsl文件决定.优化测试报告需要分为两部分内容,首先我们要优化输出的测试内容,其 ...

  2. Jmeter性能测试报告扩展

    自动收集采集结果:运行完毕后,自动出结果:

  3. jmeter生成html格式接口自动化测试报告

    jmeter生成html格式接口自动化测试报告 jmeter自带执行结果查看的插件,但是需要在jmeter工具中才能查看,如果要向领导提交测试结果,不够方便直观. 笔者刚做了这方面的尝试,总结出来分享 ...

  4. Allure自动化测试报告之修改allure测试报告名称

    1.从github获取allure代码 https://github.com/allure-framework/allure2 2.安装gradle,用于打包jar brew install grad ...

  5. HTMLTESTRunner自动化测试报告增加截图功能

    我们都知道HTMLTESTRunner自动化测试报告,是Unittest单元测试框架报告,那么在做ui测试的时候就有点不适用了. 我们需要出错截图功能. 以下是我改的,增加了截图功能,先展示界面,再展 ...

  6. jenkins+ant+jmeter自动化性能测试平台

    jenkins+ant+jmeter自动化性能测试平台 Jmeter是性能测试的工具,java编写.开源,小巧方便,可以图形界面运行也可以在命令行下运行.网上已经有人使用ant来运行,http://w ...

  7. 【Jmeter自学】Jmeter性能测试报告(八)

    http://www.cnblogs.com/YatHo/p/6092599.htmlhttp://blog.csdn.net/xiaojianpitt/article/details/4821554 ...

  8. jmeter --自动化badboy脚本开发技术

    jmeter --自动化badboy脚本开发技术 一般人用badboy都是使用它的录制功能,其它badboy还是一款自动化的工具,它可以实现检查点.参数化.迭代.并发.报告.断点等功能.本文就这些功能 ...

  9. Python+Selenium----使用HTMLTestRunner.py生成自动化测试报告2(使用PyCharm )

    1.说明 在我前一篇文件(Python+Selenium----使用HTMLTestRunner.py生成自动化测试报告1(使用IDLE ))中简单的写明了,如何生产测试报告,但是使用IDLE很麻烦, ...

随机推荐

  1. python - 爬虫入门练习 爬取链家网二手房信息

    import requests from bs4 import BeautifulSoup import sqlite3 conn = sqlite3.connect("test.db&qu ...

  2. Python学习笔记-转义字符

    Python转义字符同C语言的转义字符

  3. Go语言中的struct tag

    有时在Go的结构体定义时会看到这样的形式: type User struct { UserId int `json:"user_id" bson:"b_user_id&q ...

  4. python模块之sniffio

    嗅探python用了哪个异步库 from sniffio import current_async_library import trio import asyncio async def print ...

  5. C++中for_each的应用

    C++中for_each的应用   for each语法是方便的,也是很自然的,这也是为什么很多语言都有这样的语法,就我所知,包括java(jdk5.0以上),python,php,asp.net等语 ...

  6. CF449C:Jzzhu and Apples

    题意简述 给出正整数n,你要把1-n之间的正整数分成尽可能多组,使得每一组两个数的最大公约数大于1;输出能分成最多组的个数,并按任意顺序输出每组的两个数. 很妙的一道题. 首先我们考虑去处理每个质数的 ...

  7. frei0r-1.6.1 for win32 133 DLLs

    ffmpeg中frei0r滤镜基本使用方法 ffplay -vf frei0r=filter_name=filter_params:filter_params:... 在Windows系统ffmpeg ...

  8. NO-CARRIER

    自己动手写了创建虚拟接口,删除虚拟接口程序,频繁调用创建删除时,有时将接口up起来时会报错: Name not unique on network 利用ip link命令来查看接口(及其对应的索引) ...

  9. js 常用的工具函数

    1 类型判断 isString (o) { //是否字符串 return Object.prototype.toString.call(o).slice(8, -1) === 'String' } i ...

  10. 使用tomcat发布含有shtml文件的web程序

    平常都是使用html或jsp,当导入含有shtml的一个web项目时,向平常一样使用Jetty运行,访问到shtml文件时,直接在浏览器上显示出了源码. 查询,使用tomcat发布,修改tomcat的 ...