Как получить доступ к подсчетам тестов Junit в проекте конвейера Jenkins
Я только что начал с Дженкинса
мой проект фристайла использовал, чтобы сообщить результаты тестов JUnit в Slack, как это
MyJenkinsFreestyle - #79 Unstable after 4 min 59 sec (Open)
Test Status:
Passed: 2482, Failed: 13, Skipped: 62
Теперь я переместил то же самое в проект конвейера, и все хорошо, за исключением того, что уведомления Slack не имеют статуса теста
done MyPipelineProject #68 UNSTABLE
Я понимаю, что мне нужно создать сообщение для отправки в Slack, и я сделал это выше.
единственная проблема заключается в том, как я могу прочитать состояние теста-пройденный счетчик, не сосчитать и т. д. Это называется "тестовое резюме" в Jenkins slack-plugin фиксация, и вот скриншот
Итак, как мне получить доступ к Junit tests count/details в проекте конвейера Дженкинса ? - чтобы они сообщались в уведомлениях.
обновление: В проекте Freestyle само уведомление Slack имеет "резюме теста", и нет возможности выбрать (или нет) для резюме теста.
в проекте трубопровода, моя команда "junit" для "публикации результатов теста JUnit" перед отправкой уведомления Slack.
Итак, в коде эти строки выглядят так (это последние строки последнего этапа):
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>)";
3 ответов
С презентации из Cloudbees я обнаружил, что это должно быть возможно с помощью объекта "build". Он имеет код, как
def testResult = build.testResultAction
def total = testResult.totalCount
но currentBuild не предоставляет доступ к testResultAction.
поэтому продолжал искать и нашел этот пост "реагировать на неудачные тесты в сценарий нефтепровода". Там Роберт Санделл дал "pro tip"
Pro tip, требует некоторых " пользовательских белый список":
AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class) if (testResultAction != null) { echo "Tests: ${testResultAction.failCount} / ${testResultAction.failureDiffString} failures of ${testResultAction.totalCount}.\n\n" }
это сработало как шарм-просто мне пришлось снять флажок" Groovy sandbox". Теперь у меня есть эти в журнале сборки
Tests: 11 / ±0 failures of 2624
теперь я буду использовать это, чтобы подготовить строку для уведомления в slack с результатами теста.
обновление:
наконец, функция, которую я использовал для получения вывода, выглядит следующим образом (Обратите внимание, что "failure diff" после неудачных тестов очень полезен)
Test Status:
Passed: 2628, Failed: 6 / ±0, Skipped: 0
- это следующий:
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
}
обновление 2018-04-19
Примечание выше требует ручного "белого списка" используемых методов. Вот как вы можете белый список всех методов за один раз
вручную обновите белый список...
Выход Дженкинс
создать /обновить % USERPROFILE%.Дженкинс \ scriptApproval.xml со следующим содержимым
<?xml version='1.0' encoding='UTF-8'?>
<scriptApproval plugin="script-security@1.23">
<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>
- Перезапустить Jenkins
- и затем убедитесь, что "в утверждение сценария " имеет вышеуказанные записи утверждены
- Примечание: это то, что важно. Поэтому, если файл scriptApproval уже есть, вам обычно нужно будет обеспечить содержимое тега.
чтобы расширить ответ @vikramsjn, вот что я использую, чтобы получить резюме теста в моем 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
}
затем я использую этот метод для создания экземпляра my testSummary
переменной:
def testSummary = getTestSummary()
это вернет что-то похожее на:
"Test results:
Passed: 123, Failed: 0, Skipped: 0"
прежде всего, спасибо за ответы выше. Они сэкономили мне много времени, я использовал предложенное решение в своем конвейере. Однако я не использовал "белый список", и он работает нормально. Я использую общие библиотеки для конвейера Дженкинса, и вот часть этой общей библиотеки с конвейером и использованием методов для получения подсчетов:
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: 'example@email.com',
subject: "Tests are finished: ${currentBuild.fullDisplayName}",
body: "Tests are finished ${env.BUILD_URL}\n Test Report: ${emailTestReport} "
}
}
}
}
}
}
p.s. Если я создаю emailTestRepot как локальную переменную внутри скрипта "раздел", я получаю следующее исключение:
an exception which occurred:
in field locals
in field parent
in field caller
in field e
in field program
in field threads
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@11cd92de
Caused: java.io.NotSerializableException: hudson.tasks.junit.TestResultAction
...
Я много боролся с попытками исправить это Java.Ио.NotSerializableException. Как я понял мне нужно использовать "белые списки", чтобы предотвратить NotSerializableException. Но я действительно не хотел этого делать, и когда я переместил "def emailTestReport" из конвейера, он работал просто отлично.