Как я могу написать шаблон Jenkins email-ext для отображения результатов тестирования, таких как стандартный тестовый отчет

Я настроил стандартный шаблон желе для отображения текущих результатов теста в таблице, однако я действительно хочу иметь возможность отображать различия, как видно на странице результатов теста Дженкинса.

например:

JUnit Tests: 0 failures (±0) , 1 skipped (+1)

Package               Duration   Fail  (diff)  Skip  (diff)  Total  (diff)
foo.bar.baz              89 ms      0      0     1       +1     5       +2

4 ответов


написать Groovy шаблон для электронной почты Ext плагин вместо шаблона желе. В шаблоне Groovy у вас будет доступ к построить объект для сборки. Затем вы можете позвонить getTestResultAction на нем получить AbstractTestResultAction для сборки, которую вы можете запросить для всего, что вам нужно.

вот ссылка Jenkins основной модуль API. Образец шаблона Groovy для плагина электронной почты Ext можно найти в $JENKINS_HOME/plugins/email-ext/WEB-INF/classes/hudson/plugins/emailext/templates/groovy-html.template. Более подробную информацию об использовании шаблона/скрипта Groovy можно найти в электронная почта Ext plugin documentation.


Если вы боретесь о том, как получить доступ к нему через внутренний API (трудно знать, и он всегда существует ограничение), есть еще один более гибкий способ сделать это.

использование маркера файла вместо шаблона groovy

  1. использование скрипта для доступа к данным тестирования через Jenkins API, для вашего случая, это как http://jenkins.сервер/работа/yourjob/lastCompletedBuild/testReport/api / xml и создайте свой собственный html-файл как email.html под рабочее место
  2. на Default Content форма в конфигурации email-ext, используя маркер файла для отправки электронной почты напрямую ${FILE, path="email.html"}

в шаге 1 выше вы также можете использовать более гибкий способ для своего собственного шаблона, я использую скрипт python и простой шаблон строки.

это работает идеально для меня.


чтобы расширить этот ответ: Написать Groovy шаблон для электронной почты Ext плагин вместо шаблона желе. В редактируемом содержимом уведомления по электронной почте

  • Установите тип контента в "HTML" или "HTML и обычный текст"
  • и включить groovy скрипт, как это:

    ${SCRIPT, template= " test.groovy"}

  • поместите groovy скрипт в email-шаблоны домой, например /var/lib/jenkins / email-шаблоны. увидеть ниже тест.отличный.

В приведенном ниже примере каждый тест повторяется, получая каждый из этих объектов: "' junitResult.getChildren()"'. Если нужной итерации не только тогда тесты junitResult.можно использовать getFailedTests (). Посмотрите на Гудзон.задачи.тесты JUnit.TestResult по API: http://hudson-ci.org/javadoc/hudson/tasks/junit/PackageResult.html Также см. http://hudson-ci.org/javadoc/hudson/model/Build.html

Collection<ClassResult> getChildren()
List<CaseResult>    getFailedTests()

пример / шаблон из email-ext-plugin можно посмотреть здесь: https://github.com/jenkinsci/email-ext-plugin/blob/master/src/main/resources/hudson/plugins/emailext/templates/groovy-html.template

в этом примере показан итоговый результат теста и таблица результатов для каждого набора тестов и отдельного теста. тест.groovy:

<html>
<body>
<%

    import hudson.model.*

    def build = Thread.currentThread().executable
    def buildNumber = build.number
    def buildNumHash = build.getDisplayName()

    def testCount = "0"
    def testPassed = "0"
    def testFailed = "0"
    def testSkipped = "0"
    def buildDuration = "0"
    if(build.testResultAction) {
        def testResult = build.testResultAction
        testCount = String.format("%d",(testResult.totalCount))
        testPassed = String.format("%d",(testResult.result.passCount))
        testFailed = String.format("%d",(testResult.result.failCount))
        testSkipped = String.format("%d",(testResult.result.skipCount))
        testDuration = String.format("%.2f",(testResult.result.duration ))
    }

    def workspace = build.getEnvVars()["WORKSPACE"]
    def buildName = build.getEnvVars()["JOB_NAME"]
    def BUILD_STATUS = build.getEnvVars()["BUILD_STATUS"]
    def BUILD_URL = build.getEnvVars()["BUILD_URL"]

    def testResult = hudson.tasks.junit.TestResult

    def testResult2 = build.getAction(hudson.tasks.junit.TestResultAction.class)

%>

start test.groovy <br><br>
<b>TEST RESULT:</b> $testCount total, <b>$testPassed pass</b>, <b>$testFailed fail</b>, $testSkipped skip.<br>
Workspace : $workspace<br>
Project Name : $buildName $buildNumHash<br><br>

<!-- GENERAL INFO -->

<TABLE>
  <TR><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>Build URL</TD><TD><A href="${rooturl}${build.url}">${rooturl}${build.url}</A></TD></TR>
  <TR><TD>Project:</TD><TD>${project.name}</TD></TR>
  <TR><TD>Date of build:</TD><TD>${it.timestampString}</TD></TR>
  <TR><TD>Build duration:</TD><TD>${build.durationString}</TD></TR>
  <TR><TD>Test duration:</TD><TD>${testDuration}</TD></TR>
</TABLE>
<BR/>

<!-- JUnit TEMPLATE  hudson.tasks.junit.TestResult   -->

<% def junitResultList = it.JUnitTestResult
try {
 def cucumberTestResultAction = it.getAction("org.jenkinsci.plugins.cucumber.jsontestsupport.CucumberTestResultAction")
 junitResultList.add(cucumberTestResultAction.getResult())
} catch(e) {
        //cucumberTestResultAction not exist in this build
}
// API: http://hudson-ci.org/javadoc/hudson/tasks/junit/PackageResult.html
%>

<!-- JUnit TEMPLATE: all tests PASS FAIL SKIP >
<% 
if (junitResultList.size() > 0) { %>
 <TABLE width="100%">
 <TR><TD class="bg1" colspan="2"><B>${junitResultList.first().displayName}</B></TD></TR>
 <% junitResultList.each{
  junitResult -> %>
     <% junitResult.getChildren().each { packageResult -> %>
        <TR><TD class="bg2" colspan="2"> <B>TEST SUITE: ${packageResult.getName()} Failed: ${packageResult.getFailCount()} test(s), Passed: ${packageResult.getPassCount()} test(s)</B>, Skipped: ${packageResult.getSkipCount()} test(s), Total: ${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()} test(s)</TD></TR>
        <% packageResult.getChildren().each{ suite -> 
               suite.getChildren().each{ test ->
           def colour = "lightgreen"
           def highlight1=""
           def highlight2=""
           RESULT = test.getStatus() // FAILED or PASSED or SKIPPED
           if (RESULT == hudson.tasks.junit.CaseResult.Status.FAILED || RESULT == hudson.tasks.junit.CaseResult.Status.REGRESSION) {
               colour = "#ffcccc" 
               highlight1="<B>"
               highlight2="</B>"
           }
           if (RESULT == hudson.tasks.junit.CaseResult.Status.SKIPPED) { colour = "#ffffb3" }
         %>
          <TR bgcolor="${colour}"><TD class="test" colspan="2">${highlight1}<li>${RESULT}: ${test.getFullName()} </li>${highlight2}</TD></TR>
        <% } }
      }
 } %>
 </TABLE>
 <BR/>
<%
} %>

end of test.groovy

</body>
</html>

например выход (текст только нет цвета/форматирование)

start test.groovy 

TEST RESULT: 18 total, 18 pass, 0 fail, 0 skip. 
Workspace : /var/lib/jenkins/jobs/jobname-1/workspace 
Project Name : jobname-1 #20

BUILD SUCCESS 

Build URL   http://jenkinsurl:port/job/jobname-1/20/
Project:    jobname-1 
Date of build:  Mon, 23 Jan 2017 09:29:00 +0000 
Build duration: 10 min 
Test duration:  267.12

Test Results 
TEST SUITE: suitename1 Failed: 0 test(s), Passed: 3 test(s), Skipped: 0 test(s), Total: 3 test(s) 
 * PASSED: suitename1.testclass.testname1
 * PASSED: suitename1.testclass.testname2
 * PASSED: suitename1.testclass.testname3
TEST SUITE: suitename2 Failed: 2 test(s), Passed: 1 test(s), Skipped: 0 test(s), Total: 3 test(s) 
 * PASSED: suitename2.testclass.testname1
 * FAILED: suitename2.testclass.testname2
 * REGRESSION: suitename2.testclass.testname3

end of test.groovy

мое решение в желе на основе статического анализа по умолчанию.сценарий кисель

  <!-- 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>JUnit Tests</h1>
      </a>
      <table class="border">
        <tr>
          <th class="border">Package</th>
          <th class="border">Failed</th>
          <th class="border">Failed (diff)</th>
          <th class="border">Passed</th>
          <th class="border">Passed (diff)</th>
          <th class="border">Skipped</th>
          <th class="border">Skipped (diff)</th>
          <th class="border">Total</th>
          <th class="border">Total (diff)</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_failed">${packageResult.getFailCount()-packageResult.previousResult.getFailCount()}</td>
              <td class="border test_passed">${packageResult.getPassCount()}</td>
              <td class="border test_passed">${packageResult.getPassCount()-packageResult.previousResult.getPassCount()}</td>
              <td class="border test_skipped">${packageResult.getSkipCount()}</td>
              <td class="border test_skipped">${packageResult.getSkipCount()-packageResult.previousResult.getSkipCount()}</td>
              <td class="border">
                <b>${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()}
                </b>
              </td>
              <td class="border">
                <b>${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()-packageResult.previousResult.getPassCount()-packageResult.previousResult.getFailCount()-packageResult.previousResult.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>