Tomcat+Jenkins+JMeter+Ant实现接口自动化测试(二)

安装Tomcat+Jenkins+JMeter+Ant实现接口自动化测试(一)配置完毕后,会发现两个问题:

1、发送的邮件只能看到成功率,失败的接口看不到响应信息,不好定位接口报错原因

2、无论接口是否报错,构建都是成功的,没办法通过构建结果知道是否接口报错,而且不能做到接口报错时发送邮件

所以,继续写一篇优化以上两个问题的文章

1、报告优化

首先,下载一个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);

                    };

                })();


                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>

            <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="data"><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>

之后,把文件放在/Users/x/Downloads/apache-jmeter-5.2.1/extras下,然后替换build.xml里面的报告模板,如图,我的已经替换完了,完成后报告展示如下,直观了很多,问题解决

图1
图2

2、构建优化

打开项目配置,选择构建里面的执行shell,命令如下,问题解决!接口报错,构建失败!

图3

linux系统和mac可用:

shell命令:

#!/bin/bash

cd /Users/zhangbaoting/Desktop/shenpi_product/resultLog/

pwd

ls

grep '<failure>true</failure>' jtl/${BUILD_NUMBER}.jtl

if [ $? -ne 0 ]; then

echo "NOT exist failure cases" && exit 0

else

echo "Exist failure cases" && exit 1

fi

windows系统用:


命令如下:

G:

cd report

cd resultLog

cd jtl

findstr /i "<failure>true</failure>" %BUILD_NUMBER%.jtl

if NOT %ERRORLEVEl% == 0 (

    echo "无失败用例" && exit 0

)else (

    echo "有失败用例" && exit 1

)

完结,撒花✿✿ヽ(°▽°)ノ✿

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容