web-dev-qa-db-ger.com

Zugriff auf die Junit-Testanzahl im Jenkins Pipeline-Projekt

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 testsummaryimage

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>)";
16
vikramsjn

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>
  • Starten Sie Jenkins neu
  • vergewissern Sie sich dann, dass für die "In-Skript-Genehmigung" die obigen Einträge genehmigt wurden
  • HINWEIS: Es ist das, was wichtig ist. Wenn also die scriptApproval-Datei bereits vorhanden ist, müssen Sie im Allgemeinen den Inhalt des Tags sicherstellen.
26
vikramsjn

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

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.

1