Как я могу написать шаблон электронной почты Jenkins для отображения результатов теста, таких как стандартный отчет об испытаниях
Я изменил шаблон стандартного молочка, чтобы отобразить текущие результаты теста в таблице, однако я действительно хочу иметь возможность отображать различия, как показано на странице результатов теста Jenkins.
Например:
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
Ответы
Ответ 1
Напишите шаблон Groovy для плагина Email Ext вместо шаблона Jelly. В шаблоне Groovy у вас будет доступ к объекту Build для вашей сборки. Затем вы можете вызвать getTestResultAction, чтобы получить AbstractTestResultAction для сборки, которую вы можете затем запрос на все, что вам нужно.
Вот ссылка на API основного модуля Jenkins. Пример шаблона Groovy для плагина Ext Email можно найти в $JENKINS_HOME/plugins/email-ext/WEB-INF/classes/hudson/plugins/emailext/templates/groovy-html.template
. Более подробную информацию о Groovy шаблоне /script можно найти в Email Ext плагин документации.
Ответ 2
Если вы боретесь с тем, как получить доступ к нему через внутренний API (трудно знать и он существует ограничение всегда), есть еще один более гибкий способ сделать это.
Использование токена FILE вместо groovy template
- используя script для доступа к вашим данным тестирования через Jenkins API, для вашего случая это похоже на http://jenkins.server/job/yourjob/lastCompletedBuild/testReport/api/xml и создать собственный html файл, например
email.html
в рабочей области
- В форме
Default Content
в конфигурации электронной почты-ext, используя токен FILE, чтобы отправить электронное письмо непосредственно ${FILE, path="email.html"}
В шаге 1 выше вы также можете использовать более гибкий способ для своего собственного шаблона, я использую python script и простой шаблон строки.
Он отлично работает для меня.
Ответ 3
Чтобы расширить этот ответ:
Напишите шаблон Groovy для плагина Email Ext вместо шаблона Jelly.
В редактируемом уведомлении по электронной почте
- установить тип содержимого в "HTML" или "Оба HTML и обычный текст"
-
и включите Groovy script следующим образом:
${SCRIPT, template = "test.groovy" }
-
поместите Groovy script в шаблоны электронной почты домой, например.
/Вар/Lib/Jenkins/электронная почта-шаблоны. см. ниже test.groovy.
В приведенном ниже примере каждый тест повторяется путем получения каждого из этих объектов: '' 'junitResult.getChildren()' ''. Если кто-то захочет итерации только неудавшихся тестов, тогда можно использовать junitResult.getFailedTests(). См. API hudson.tasks.junit.TestResult: 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
В этом примере показан итоговый результат теста и таблица результатов для каждого набора тестов и индивидуального теста. test.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
Ответ 4
Мое решение в желе, основываясь на стандарте static-analysys.jelly script
<!-- 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>
Ответ 5
Сделано с помощью Allure и JUnit
https://gist.github.com/unickq/9042b433f544d704a4d4403ce083e4dc
![enter image description here]()