SpringMVC+MockMvc+dbUnit+cobertura构建测试框架(下)

简介: 本文基于SpringMVC搭建测试框架

image.png

配置coberture插件.png


image.png

邮件发送.png


邮件发送我用的是jelly模板,使用的时候只需要填写模板文件名称(.jelly后缀不需要),模板文件放在jenkins服务器上,具体模板代码见附件一,见下图


image.png

邮件模板位置.png


image.png

配置trigger.png


7.邮件发送最终效果


邮件主要内容:构建状态、覆盖率整体情况、包覆盖率情况、UT趋势、变更集等等


image.png


邮件效果.png


附件一:jelly邮件模板


<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define">
  <html>
    <head>
      <title>${project.name}</title>
      <style>
        body table, td, th, p, h1, h2 {
        margin:0;
        font:normal normal
        100% Georgia, Serif;
        background-color: #ffffff;
        }
        h1, h2 {
        border-bottom:dotted 1px #999999;
        padding:5px;
        margin-top:10px;
        margin-bottom:10px;
        color: #000000;
        font: normal bold 130%
        Georgia,Serif;
        background-color:#f0f0f0;
        }
        tr.gray {
        background-color:#f0f0f0;
        }
        h2 {
        padding:5px;
        margin-top:5px;
        margin-bottom:5px;
        font: italic bold 110% Georgia,Serif;
        }
        .bg2 {
        color:black;
        background-color:#E0E0E0;
        font-size:110%
        }
        th {
        font-weight: bold;
        }
        tr, td, th {
        padding:2px;
        }
        td.test_passed {
        color:blue;
        }
        td.test_failed {
        color:red;
        }
        td.center {
          text-align: center;
        }
        td.test_skipped {
        color:grey;
        }
        .console {
        font: normal normal 90% Courier New,
        monotype;
        padding:0px;
        margin:0px;
        }
        div.content, div.header {
        background: #ffffff;
        border: dotted
        1px #666;
        margin: 2px;
        content:
        2px;
        padding: 2px;
        }
        table.border, th.border, td.border {
        border:
        1px solid black;
        border-collapse:collapse;
        }
      </style>
    </head>
    <body>
      <div class="header">
        <j:set var="spc" value="&amp;nbsp;&amp;nbsp;" />
        <!-- GENERAL INFO -->
        <table>
          <tr class="gray">
            <td align="right">
              <j:choose>
                <j:when test="${build.result=='SUCCESS'}">
                  <img src="${rooturl}static/e59dfe28/images/32x32/blue.gif" />
                </j:when>
                <j:when test="${build.result=='FAILURE'}">
                  <img src="${rooturl}static/e59dfe28/images/32x32/red.gif" />
                </j:when>
                <j:otherwise>
                  <img
                    src="${rooturl}static/e59dfe28/images/32x32/yellow.gif" />
                </j:otherwise>
              </j:choose>
            </td>
            <td valign="center">
              <b style="font-size: 200%;">BUILD ${build.result}</b>
            </td>
          </tr>
          <tr>
            <td>构建地址</td>
            <td>
              <a href="${rooturl}${build.url}">${rooturl}${build.url}</a>
            </td>
          </tr>
          <tr>
            <td>项  目:</td>
            <td>${project.name}</td>
          </tr>
          <tr>
            <td>构建日期:</td>
            <td>${it.timestampString}</td>
          </tr>
          <tr>
            <td>构建时长:</td>
            <td>${build.durationString}</td>
          </tr>
          <tr>
            <td>Build cause:</td>
            <td>
              <j:forEach var="cause" items="${build.causes}">${cause.shortDescription}
              </j:forEach>
            </td>
          </tr>
          <tr>
            <td>Build description:</td>
            <td>${build.description}</td>
          </tr>
          <tr>
            <td>Built on:</td>
            <td>
              <j:choose>
                <j:when test="${build.builtOnStr!=''}">${build.builtOnStr}</j:when>
                <j:otherwise>master</j:otherwise>
              </j:choose>
            </td>
          </tr>
        </table>
      </div>
      <!-- COBERTURA TEMPLATE -->
      <j:set var="coberturaAction" value="${it.coberturaAction}" />
      <j:if test="${coberturaAction!=null}">
        <div class="content">
          <j:set var="coberturaResult" value="${coberturaAction.result}" />
          <j:if test="${coberturaResult!=null}">
            <a href="${rooturl}${build.url}/cobertura">
              <h1>Cobertura报告</h1>
            </a>
            <h2>趋势</h2>
            <img src="http://*.*.*.*:****/${build.url}../cobertura/graph" width="600" height="200px" />
            <h2>项目覆盖率汇总</h2>
            <table class="border">
              <tr>
                <th class="border">Name</th>
                <j:forEach var="metric" items="${coberturaResult.metrics}">
                  <th class="border">${metric.name}</th>
                </j:forEach>
              </tr>
              <tr>
                <td class="border">${coberturaResult.name}</td>
                <j:forEach var="metric" items="${coberturaResult.metrics}">
                  <!--
                  <td class="border"
                    data="${coberturaResult.getCoverage(metric).percentageFloat}">${coberturaResult.getCoverage(metric).percentage}%
                    (${coberturaResult.getCoverage(metric)})
                  </td>
                  -->
                  <td class="border">
                      <div style="background-color:#ff9090;width:100px;height:20px;">
                        <div style="background-color:#80ff80;width: ${coberturaResult.getCoverage(metric).percentage}px;height:20px;">
                            <span style="text-align:center;position:absolute;width:100px;" vertical-align="middle">
                                ${coberturaResult.getCoverage(metric).percentage}%(${coberturaResult.getCoverage(metric)})
                            </span>
                        </div>
                      </div>
                  </td>
                </j:forEach>
              </tr>
            </table>
            <j:if test="${coberturaResult.sourceCodeLevel}">
              <h2>Source</h2>
              <j:choose>
                <j:when test="${coberturaResult.sourceFileAvailable}">
                  <div style="overflow-x:scroll;">
                    <table class="source">
                      <thead>
                        <tr>
                          <th colspan="3">${coberturaResult.relativeSourcePath}
                          </th>
                        </tr>
                      </thead>
                      ${coberturaResult.sourceFileContent}
                    </table>
                  </div>
                </j:when>
                <j:otherwise>
                  <p>
                    <i>Source code is unavailable</i>
                  </p>
                </j:otherwise>
              </j:choose>
            </j:if>
            <j:forEach var="element" items="${coberturaResult.childElements}">
              <j:set var="childMetrics"
                value="${coberturaResult.getChildMetrics(element)}" />
              <h2>Coverage Breakdown by ${element.displayName}</h2>
              <table class="border">
                <tr>
                  <th class="border">Name</th>
                  <j:forEach var="metric" items="${childMetrics}">
                    <th class="border">${metric.name}</th>
                  </j:forEach>
                </tr>
                <j:forEach var="c" items="${coberturaResult.children}">
                  <j:set var="child" value="${coberturaResult.getChild(c)}" />
                  <tr>
                    <td class="border">
                      ${child.xmlTransform(child.name)}
                    </td>
                    <j:forEach var="metric" items="${childMetrics}">
                      <j:set var="childResult" value="${child.getCoverage(metric)}" />
                      <j:choose>
                        <j:when test="${childResult!=null}">
                          <!--
                          <td class="border" data="${childResult.percentageFloat}">${childResult.percentage}%
                            (${childResult})
                          </td>
                          -->
                          <td class="border" data="${childResult.percentageFloat}">
                              <div style="background-color:#ff9090;width:100px;height:20px;">
                                <div style="background-color:#80ff80;width: ${childResult.percentage}px;height:20px;">
                                    <span style="text-align:center;position:absolute;width:100px;">
                                        ${childResult.percentage}%(${childResult})
                                    </span>
                                </div>
                              </div>
                          </td>
                        </j:when>
                        <j:otherwise>
                          <td class="border" data="101">N/A</td>
                        </j:otherwise>
                      </j:choose>
                    </j:forEach>
                  </tr>
                </j:forEach>
              </table>
            </j:forEach>
          </j:if>
          <br />
        </div>
      </j:if>
      <!-- 覆盖率趋势统计 -->
      <!--
      <j:set var="coberturaAction" value="${it.coberturaAction}" />
      <j:if test="${coberturaAction!=null}">
        <div class="content">
          <j:set var="coberturaResult" value="${coberturaAction.result}" />
          <j:if test="${coberturaResult!=null}">
            <a href="${rooturl}${build.url}/cobertura">
              <h1>覆盖率趋势</h1>
            </a>
            <j:forEach var="metric" items="${coberturaResult.metrics}">
                <table style="padding: 0 10px; width:480px;">
                    <tbody>
                    <tr>
                        <th align="left">${metric.name}</th>
                        <td align="right"
                            data="${coberturaResult.getCoverage(metric).percentageFloat}">${coberturaResult.getCoverage(metric).percentage}%
                            (${coberturaResult.getCoverage(metric)})
                        </td>
                    </tr>
                    </tbody>
                </table>
                <table style="height: 3px; padding: 0 10px; width:480px;">
                    <tbody>
                    <tr>
                        <td width="${coberturaResult.getCoverage(metric).percentage}%" height="20" style="background-color:#bfb;">
                        </td>
                        <td style="background-color:#fdd;">
                        </td>
                    </tr>
                    </tbody>
                </table>
            </j:forEach>
          </j:if>
          <br />
        </div>
      </j:if>
      -->
      <!-- HEALTH TEMPLATE -->
      <div class="content">
        <j:set var="healthIconSize" value="16x16" />
        <j:set var="healthReports" value="${project.buildHealthReports}" />
        <j:if test="${healthReports!=null}">
          <h1>健康报告</h1>
          <table>
            <tr>
              <th>W</th>
              <th>描述</th>
              <th>分数</th>
            </tr>
            <j:forEach var="healthReport" items="${healthReports}">
              <tr>
                <td>
                  <img
                    src="${rooturl}${healthReport.getIconUrl(healthIconSize)}" />
                </td>
                <td>${healthReport.description}</td>
                <td>${healthReport.score}</td>
              </tr>
            </j:forEach>
          </table>
          <br />
        </j:if>
      </div>
      <!-- CHANGE SET -->
      <div class="content">
        <j:set var="changeSet" value="${build.changeSet}" />
        <j:if test="${changeSet!=null}">
          <j:set var="hadChanges" value="false" />
          <a href="${rooturl}${build.url}/changes">
            <h1>变更集</h1>
          </a>
          <j:forEach var="cs" items="${changeSet.logs}"
            varStatus="loop">
            <j:set var="hadChanges" value="true" />
            <h2>${cs.msgAnnotated}</h2>
            <p>
              by
              <em>${cs.author}</em>
            </p>
            <table>
              <j:forEach var="p" items="${cs.affectedFiles}">
                <tr>
                  <td width="10%">${spc}${p.editType.name}</td>
                  <td>
                    <tt>${p.path}</tt>
                  </td>
                </tr>
              </j:forEach>
            </table>
          </j:forEach>
          <j:if test="${!hadChanges}">
            <p>无</p>
          </j:if>
          <br />
        </j:if>
      </div>
      <!-- ARTIFACTS -->
      <j:set var="artifacts" value="${build.artifacts}" />
      <j:if test="${artifacts!=null and artifacts.size()&gt;0}">
        <div class="content">
          <h1>Build Artifacts</h1>
          <ul>
            <j:forEach var="f" items="${artifacts}">
              <li>
                <a href="${rooturl}${build.url}artifact/${f}">${f}</a>
              </li>
            </j:forEach>
          </ul>
        </div>
      </j:if>
      <!-- MAVEN ARTIFACTS -->
      <j:set var="mbuilds" value="${build.moduleBuilds}" />
      <j:if test="${mbuilds!=null}">
        <div class="content">
          <h1>Build Artifacts</h1>
          <j:forEach var="m" items="${mbuilds}">
            <h2>${m.key.displayName}</h2>
            <j:forEach var="mvnbld" items="${m.value}">
              <j:set var="artifacts" value="${mvnbld.artifacts}" />
              <j:if test="${artifacts!=null and artifacts.size()&gt;0}">
                <ul>
                  <j:forEach var="f" items="${artifacts}">
                    <li>
                      <a href="${rooturl}${mvnbld.url}artifact/${f}">${f}</a>
                    </li>
                  </j:forEach>
                </ul>
              </j:if>
            </j:forEach>
          </j:forEach>
          <br />
        </div>
      </j:if>
      <!-- JUnit TEMPLATE -->
      <j:set var="junitResultList" value="${it.JUnitTestResult}" />
      <j:if test="${junitResultList.isEmpty()!=true}">
        <div class="content">
          <a href="${rooturl}${build.url}/testReport">
            <h1>单元测试</h1>
          </a>
          <table class="border">
            <tr>
              <th class="border">包路径</th>
              <th class="border">失败</th>
              <th class="border">通过</th>
              <th class="border">跳过</th>
              <th class="border">总计</th>
            </tr>
            <j:forEach var="junitResult" items="${it.JUnitTestResult}">
              <j:forEach var="packageResult" items="${junitResult.getChildren()}">
                <tr>
                  <td class="border">
                    <tt>${packageResult.getName()}</tt>
                  </td>
                  <td class="border test_failed">${packageResult.getFailCount()}</td>
                  <td class="border test_passed">${packageResult.getPassCount()}</td>
                  <td class="border test_skipped">${packageResult.getSkipCount()}</td>
                  <td class="border">
                    <b>${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()}
                    </b>
                  </td>
                </tr>
                <j:forEach var="failed_test"
                  items="${packageResult.getFailedTests()}">
                  <tr>
                    <td class="test_failed" colspan="5">
                      <tt>${failed_test.getFullName()}</tt>
                    </td>
                  </tr>
                </j:forEach>
              </j:forEach>
            </j:forEach>
          </table>
          <br />
        </div>
      </j:if>
      <!-- Static Analysis -->
      <j:set var="actions" value="${it.staticAnalysisActions}" />
      <j:if test="${!actions.isEmpty()}">
        <div class="content">
          <h1>Static Analysis Results</h1>
          <table>
            <tr>
              <th></th>
              <th>Name</th>
              <th>Result</th>
              <th>Total</th>
              <th>High</th>
              <th>Normal</th>
              <th>Low</th>
            </tr>
            <j:forEach var="action" items="${actions}">
              <tr>
                <td>
                  <img src="${rooturl}${action.smallImageName}" />
                </td>
                <td>
                  <a href="${rooturl}${build.url}/${action.urlName}">${action.displayName}</a> 
                </td>
                <td class="center">
                  <j:choose>
                    <j:when test="${action.result.pluginResult=='SUCCESS'}">
                      <img src="${rooturl}static/e59dfe28/images/16x16/blue.gif" />
                    </j:when>
                    <j:when test="${action.result.pluginResult=='FAILURE'}">
                      <img src="${rooturl}static/e59dfe28/images/16x16/red.gif" />
                    </j:when>
                    <j:otherwise>
                      <img src="${rooturl}static/e59dfe28/images/16x16/yellow.gif" />
                    </j:otherwise>
                  </j:choose>
                </td>
                <td class="center">${action.result.numberOfAnnotations} </td>
                <td class="center">${action.result.getNumberOfAnnotations('HIGH')} </td>
                <td class="center">${action.result.getNumberOfAnnotations('NORMAL')} </td>
                <td class="center">${action.result.getNumberOfAnnotations('LOW')} </td>
              </tr>
            </j:forEach>
          </table>
        </div>
      </j:if>
    </body>
  </html>
</j:jelly>


相关文章
|
14天前
|
人工智能 搜索推荐 数据管理
探索软件测试中的自动化测试框架选择与优化策略
本文深入探讨了在现代软件开发流程中,如何根据项目特性、团队技能和长期维护需求,精准选择合适的自动化测试框架。
64 8
|
20天前
|
人工智能 JavaScript 前端开发
自动化测试框架的演进与实践###
本文深入探讨了自动化测试框架从诞生至今的发展历程,重点分析了当前主流框架的优势与局限性,并结合实际案例,阐述了如何根据项目需求选择合适的自动化测试策略。文章还展望了未来自动化测试领域的技术趋势,为读者提供了宝贵的实践经验和前瞻性思考。 ###
|
9天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
42 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
15天前
|
安全 Ubuntu Linux
Metasploit Pro 4.22.6-2024111901 (Linux, Windows) - 专业渗透测试框架
Metasploit Pro 4.22.6-2024111901 (Linux, Windows) - 专业渗透测试框架
38 9
Metasploit Pro 4.22.6-2024111901 (Linux, Windows) - 专业渗透测试框架
|
19天前
|
Java 测试技术 API
探索软件测试中的自动化测试框架
本文深入探讨了自动化测试在软件开发中的重要性,并详细介绍了几种流行的自动化测试框架。通过比较它们的优缺点和适用场景,旨在为读者提供选择合适自动化测试工具的参考依据。
|
22天前
|
jenkins 测试技术 持续交付
自动化测试框架的搭建与实践
在软件开发领域,自动化测试是提升开发效率、确保软件质量的关键手段。本文将引导读者理解自动化测试的重要性,并介绍如何搭建一个基本的自动化测试框架。通过具体示例和步骤,我们将探索如何有效实施自动化测试策略,以实现软件开发流程的优化。
47 7
|
19天前
|
数据管理 jenkins 测试技术
自动化测试框架的设计与实现
在软件开发周期中,测试是确保产品质量的关键步骤。本文通过介绍自动化测试框架的设计原则、组件构成以及实现方法,旨在指导读者构建高效、可靠的自动化测试系统。文章不仅探讨了自动化测试的必要性和优势,还详细描述了框架搭建的具体步骤,包括工具选择、脚本开发、执行策略及结果分析等。此外,文章还强调了持续集成环境下自动化测试的重要性,并提供了实际案例分析,以帮助读者更好地理解和应用自动化测试框架。
|
20天前
|
监控 测试技术 定位技术
探索软件测试中的自动化测试框架选择与实施###
本文不概述传统意义上的摘要内容,而是直接以一段对话形式引入,旨在激发读者兴趣。想象一下,你是一名勇敢的探险家,面前摆满了各式各样的自动化测试工具地图,每张地图都指向未知的宝藏——高效、精准的软件测试领域。我们将一起踏上这段旅程,探讨如何根据项目特性选择合适的自动化测试框架,并分享实施过程中的关键步骤与避坑指南。 ###
30 4
|
19天前
|
敏捷开发 测试技术 持续交付
自动化测试之美:从零开始搭建你的Python测试框架
在软件开发的马拉松赛道上,自动化测试是那个能让你保持节奏、避免跌宕起伏的神奇小助手。本文将带你走进自动化测试的世界,用Python这把钥匙,解锁高效、可靠的测试框架之门。你将学会如何步步为营,构建属于自己的测试庇护所,让代码质量成为晨跑时清新的空气,而不是雾霾中的忧虑。让我们一起摆脱手动测试的繁琐枷锁,拥抱自动化带来的自由吧!
|
20天前
|
测试技术 持续交付 数据安全/隐私保护
软件测试的艺术与科学:探索自动化测试框架
在软件开发的世界中,测试是确保产品质量的关键环节。本文将深入探讨自动化测试框架的重要性和实现方法,旨在为读者揭示如何通过自动化测试提升软件测试效率和准确性。我们将从测试的基本概念出发,逐步引导读者了解自动化测试框架的设计和实施过程,以及如何选择合适的工具来支持测试活动。文章不仅提供理论知识,还将分享实用的代码示例,帮助读者将理论应用于实践。无论你是测试新手还是经验丰富的开发者,这篇文章都将为你打开一扇通往更高效、更可靠软件测试的大门。
20 1