Ich habe gerade mit Jenkins angefangen
Mein Freestyle-Projekt verwendete, um JUnit-Testergebnisse in Slack wie folgt zu melden
MyJenkinsFreestyle - #79 Unstable after 4 min 59 sec (Open)
Test Status:
Passed: 2482, Failed: 13, Skipped: 62
Jetzt habe ich dasselbe in ein Pipeline-Projekt verschoben, und alles ist gut, außer dass Slack-Benachrichtigungen keinen Teststatus haben
done MyPipelineProject #68 UNSTABLE
Ich verstehe, dass ich die Nachricht konstruieren muss, um sie an Slack zu senden, und das habe ich oben gemacht.
Das einzige Problem ist, wie ich den Teststatus ablesen kann - den übergebenen Zählerstand, den fehlgeschlagenen Zählerstand usw. .. Dies wird in Jenkins slack-plugin commit als "Testzusammenfassung" bezeichnet. Hier ist der Screenshot
Wie kann ich auf die Anzahl der Junit-Tests im Jenkins Pipeline-Projekt zugreifen? - so dass diese in Benachrichtigungen gemeldet werden.
UPDATE: Im Freestyle-Projekt verfügt die Slack-Benachrichtigung selbst über die "Testzusammenfassung", und es gibt keine Option für die Testzusammenfassung (oder nicht).
Im Pipeline-Projekt wird vor dem Senden einer Slack-Benachrichtigung mein "junit" -Befehl zum "Veröffentlichen von JUnit-Testergebnissen" ausgeführt.
Im Code sehen diese Zeilen also so aus (dies sind die letzten Zeilen der letzten Stufe):
bat runtests.bat
junit 'junitreport/xml/TEST*.xml'
slackSend channel: '#testschannel', color: 'normal', message: "done ${env.JOB_NAME} ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)";
Aus dieser Präsentation von Cloudbees habe ich festgestellt, dass es per "build" -Objekt möglich sein soll . Es hat Code wie
def testResult = build.testResultAction
def total = testResult.totalCount
CurrentBuild bietet jedoch keinen Zugriff auf testResultAction.
Also suchte weiter und fand diesen Beitrag "auf fehlgeschlagene Tests im Pipeline-Skript reagieren" . Dort hat Robert Sandell "Pro-Tipp" gegeben
Pro-Tipp, erfordert einige "benutzerdefinierte Whitelisting":
AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class) if (testResultAction != null) { echo "Tests: ${testResultAction.failCount} / ${testResultAction.failureDiffString} failures of ${testResultAction.totalCount}.\n\n" }
Das funktionierte wie ein Zauber - nur dass ich das Kontrollkästchen "Groovy Sandbox" abwählen musste. Nun habe ich diese im Build-Protokoll
Tests: 11 / ±0 failures of 2624
Jetzt werde ich dies verwenden, um eine Zeichenfolge vorzubereiten, um die Testergebnisse mitzubringen.
AKTUALISIEREN:
Schließlich ist die Funktion, die ich verwendet habe, um folgende Ausgabe zu erhalten:. (Beachten Sie, dass das "Fehlerdiff" nach fehlgeschlagenen Tests sehr nützlich ist.)
Test Status:
Passed: 2628, Failed: 6 / ±0, Skipped: 0
Ist das Folgende:
import hudson.tasks.test.AbstractTestResultAction
@NonCPS
def testStatuses() {
def testStatus = ""
AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
if (testResultAction != null) {
def total = testResultAction.totalCount
def failed = testResultAction.failCount
def skipped = testResultAction.skipCount
def passed = total - failed - skipped
testStatus = "Test Status:\n Passed: ${passed}, Failed: ${failed} ${testResultAction.failureDiffString}, Skipped: ${skipped}"
if (failed == 0) {
currentBuild.result = 'SUCCESS'
}
}
return testStatus
}
UPDATE 2018-04-19
Beachten Sie das obige manuelle "Whitelisting" der verwendeten Methoden. So können Sie alle Methoden auf einmal in die Whitelist aufnehmen
Aktualisieren Sie die Whitelist manuell ...
Beenden Sie Jenkins
Erstellen/Aktualisieren Sie% USERPROFILE% .jenkins\scriptApproval.xml mit dem folgenden Inhalt
<?xml version='1.0' encoding='UTF-8'?>
<scriptApproval plugin="[email protected]">
<approvedScriptHashes>
</approvedScriptHashes>
<approvedSignatures>
<string>method hudson.model.Actionable getAction Java.lang.Class</string>
<string>method hudson.model.Cause getShortDescription</string>
<string>method hudson.model.Run getCauses</string>
<string>method hudson.tasks.test.AbstractTestResultAction getFailCount</string>
<string>method hudson.tasks.test.AbstractTestResultAction getFailureDiffString</string>
<string>method hudson.tasks.test.AbstractTestResultAction getSkipCount</string>
<string>method hudson.tasks.test.AbstractTestResultAction getTotalCount</string>
<string>method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild</string>
</approvedSignatures>
<aclApprovedSignatures/>
<approvedClasspathEntries/>
<pendingScripts/>
<pendingSignatures/>
<pendingClasspathEntries/>
</scriptApproval>
Um die Antwort von @ vikramsjn zu erweitern, verwende ich die Testzusammenfassung in meiner Jenkinsfile :
import hudson.tasks.test.AbstractTestResultAction
import hudson.model.Actionable
@NonCPS
def getTestSummary = { ->
def testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
def summary = ""
if (testResultAction != null) {
def total = testResultAction.getTotalCount()
def failed = testResultAction.getFailCount()
def skipped = testResultAction.getSkipCount()
summary = "Test results:\n\t"
summary = summary + ("Passed: " + (total - failed - skipped))
summary = summary + (", Failed: " + failed)
summary = summary + (", Skipped: " + skipped)
} else {
summary = "No tests found"
}
return summary
}
Ich verwende dann diese Methode, um meine Variable testSummary
zu instanziieren:
def testSummary = getTestSummary()
Dies wird etwas ähnliches zurückgeben:
"Test results:
Passed: 123, Failed: 0, Skipped: 0"
Zunächst einmal danke ich Ihnen für die obigen Antworten. Sie haben mir viel Zeit gespart, ich habe die vorgeschlagene Lösung in meiner Pipeline verwendet. Ich habe jedoch nicht "Whitelisting" verwendet und es funktioniert gut . Ich verwende gemeinsam genutzte Bibliotheken für Jenkins Pipeline. Hier ist ein Teil dieser gemeinsam genutzten Bibliothek mit Pipeline und Verwendung von Methoden, um die Anzahl zu ermitteln:
import hudson.model.*
import jenkins.model.*
import hudson.tasks.test.AbstractTestResultAction
def call(Closure body) {
...
def emailTestReport = ""
pipeline {
...
stages{
stage('Test'){
...
post {
always {
junit 'tests.xml'
script {
AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
if (testResultAction != null) {
def totalNumberOfTests = testResultAction.totalCount
def failedNumberOfTests = testResultAction.failCount
def failedDiff = testResultAction.failureDiffString
def skippedNumberOfTests = testResultAction.skipCount
def passedNumberOfTests = totalNumberOfTests - failedNumberOfTests - skippedNumberOfTests
emailTestReport = "Tests Report:\n Passed: ${passedNumberOfTests}; Failed: ${failedNumberOfTests} ${failedDiff}; Skipped: ${skippedNumberOfTests} out of ${totalNumberOfTests} "
}
}
mail to: '[email protected]',
subject: "Tests are finished: ${currentBuild.fullDisplayName}",
body: "Tests are finished ${env.BUILD_URL}\n Test Report: ${emailTestReport} "
}
}
}
}
}
}
p.s. Wenn ich emailTestRepot als lokale Variable im Skript "section" erstelle, erhalte ich die nächste Ausnahme:
an exception which occurred:
in field locals
in field parent
in field caller
in field e
in field program
in field threads
in object [email protected]
Caused: Java.io.NotSerializableException: hudson.tasks.junit.TestResultAction
...
Ich hatte viel zu kämpfen mit dem Versuch, diese Java.io.NotSerializableException zu beheben. Nach meinem Verständnis musste ich "Whitelisting" verwenden, um NotSerializableException zu verhindern. Aber ich wollte es wirklich nicht und als ich "def emailTestReport" aus der Pipeline herausgezogen habe, hat es gut funktioniert.