Конвейер сценариев Jenkins не получает результат теста, если модульный тест не пройден - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть основанные на gradle java-проекты с тестами junit, для которых я создаю CI-задания. Мне удалось интегрировать слабину с Дженкинсом, используя плагин Slack Notification.

Jenkins Версия: 2.173
Версия Slack Notification: 2.20

Jenkins CI - это скриптовый конвейер, который имеет следующий код:


stage('Test') {
        def slackHelper = new com.xyz.jenkins.libraries.SlackNotifier(env)
        try {
            sh "./gradlew test"
            junit 'build/test-results/test/*.xml'
        } finally {
            AbstractTestResultAction testResultAction =  currentBuild.rawBuild.getAction(AbstractTestResultAction.class)

            slackHelper.getTestStatuses(currentBuild)
            slackSend(channel: '#ci-cd', attachments: slackHelper.buildUnitTestSlackNotificationMessage())
        }
    }

SlackNotifier - это библиотека, которая имеет следующий код:

/**
 * Calculates test result as a string
 * @param currentBuild : jenkins object, should be passed from jenkins pipeline script
 * @return the final test result as a string
 */
@NonCPS
def getTestStatuses(currentBuild) {
    final AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
    if (testResultAction != null) {
        this.total = testResultAction.totalCount
        this.failed = testResultAction.failCount
        this.skipped = testResultAction.skipCount
        this.passed = total - failed - skipped
    }
}

buildUnitTestSlackNotificationMessage делает это в том же классе:

def buildUnitTestSlackNotificationMessage() {
        final JSONObject unitTestResult = new JSONObject()
        unitTestResult.put("fallback", this.jenkinsEnvironment.JOB_NAME + "with build#" + this.jenkinsEnvironment.BUILD_NUMBER + "finish with unit test result : Passed: " + this.passed + " | Failed: " + this.failed + " | Skipped: " + this.skipped )
        unitTestResult.put("color", this.getUnitTestReportColor())
        unitTestResult.put("pretext", "Message from CI job: " + this.jenkinsEnvironment.JOB_NAME + "#" + this.jenkinsEnvironment.BUILD_NUMBER)
        unitTestResult.put("title", "BuildLog")
        unitTestResult.put("title_link", "<<<JenkinsHost>>>" + this.jenkinsEnvironment.JOB_NAME + "/" + this.jenkinsEnvironment.BUILD_NUMBER  + "/console")
        unitTestResult.put("text", "Passed: " + this.passed +  " | Failed: " + this.failed + " | Skipped: " + this.skipped)
        unitTestResult.put("image_url", this.getLogoURL())
        this.attachments.add(unitTestResult)
        return this.attachments.toString()
    }

Все хорошо, когда все тесты пройдены. Но когда тесты не пройдены, я получаю следующее уведомление:

Message from CI job: <<<JobName>>>#47
BuildLog
Passed: null | Failed: null | Skipped: null

Оказывается, testResultAction равен нулю, если здесь не пройдут какие-либо модульные тесты.

И я не могу до конца разобраться. Пожалуйста, помогите.

1 Ответ

0 голосов
/ 16 апреля 2019

Я получил ответ в Reddit, кредит идет на: / U / Bodumin

А вот основная причина, я цитирую его здесь:

Move the junit step into the finally. What's likely happening is that test returns a non 0 (error) status so it fails it of the try.

Итак, скриптовый конвейер выглядит следующим образом:

stage('Test') {
        def slackHelper = new com.xyz.jenkins.libraries.SlackNotifier(env)
        try {
            sh "./gradlew test"
        } finally {
            junit 'build/test-results/test/*.xml'
            AbstractTestResultAction testResultAction =  currentBuild.rawBuild.getAction(AbstractTestResultAction.class)

            slackHelper.getTestStatuses(currentBuild)
            slackSend(channel: '#ci-cd', attachments: slackHelper.buildUnitTestSlackNotificationMessage())
        }
    }
...