1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

testsPublishResults: add option to fail the build on test errors (#472)

* add option to fail the build on test errors

* fix typo

* add test cases

* adjust docs

* set build result

* add hasTestFailure utils method

* use utils method

* use dedicated type

* adapt tests

* handle missing test actions

* Update testsPublishResults.md

* Update JenkinsUtils.groovy

* Update JenkinsUtils.groovy

* Update JenkinsUtils.groovy

* remove comments

* adapt test case

* Update TestsPublishResultsTest.groovy
This commit is contained in:
Christopher Fenner 2019-02-08 12:30:59 +01:00 committed by GitHub
parent 3f12015364
commit d657f0dc28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 8 deletions

View File

@ -33,6 +33,7 @@ Available parameters:
| parameter | mandatory | default | possible values |
| ----------|-----------|---------|-----------------|
| script | yes | | |
| `failOnError` | no | `false` | `true`, `false` |
| junit | no | `false` | true, false |
| jacoco | no | `false` | true, false |
| cobertura | no | `false` | true, false |
@ -43,6 +44,7 @@ Available parameters:
with the `this` parameter, as in `script: this`.
This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md)
for retrieving, for example, configuration parameters.
* `failOnError` - If `failOnError` it set to `true` the step will fail the build if JUnit detected any failing tests.
* `junit` - Publishes test results files in JUnit format with the [JUnit Plugin](https://plugins.jenkins.io/junit).
* `jacoco` - Publishes code coverage with the [JaCoCo plugin](https://plugins.jenkins.io/jacoco) .
* `cobertura` - Publishes code coverage with the [Cobertura plugin](https://plugins.jenkins.io/cobertura).

View File

@ -317,6 +317,7 @@ steps:
toJson: false
toHtml: false
testsPublishResults:
failOnError: false
junit:
pattern: '**/TEST-*.xml'
updateResults: false

View File

@ -3,6 +3,7 @@ package com.sap.piper
import com.cloudbees.groovy.cps.NonCPS
import jenkins.model.Jenkins
import org.jenkinsci.plugins.workflow.steps.MissingContextVariableException
import hudson.tasks.junit.TestResultAction
@API
@NonCPS
@ -10,6 +11,14 @@ static def isPluginActive(pluginId) {
return Jenkins.instance.pluginManager.plugins.find { p -> p.isActive() && p.getShortName() == pluginId }
}
static boolean hasTestFailures(build){
//build: https://javadoc.jenkins.io/plugin/workflow-support/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.html
//getRawBuild: https://javadoc.jenkins.io/plugin/workflow-job/org/jenkinsci/plugins/workflow/job/WorkflowRun.html
//getAction: http://www.hudson-ci.org/javadoc/hudson/tasks/junit/TestResultAction.html
def action = build?.getRawBuild()?.getAction(TestResultAction.class)
return action && action.getFailCount() != 0
}
def nodeAvailable() {
try {
sh "echo 'Node is available!'"

View File

@ -3,6 +3,7 @@ import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.rules.ExpectedException
import util.BasePiperTest
import util.JenkinsReadYamlRule
@ -16,12 +17,14 @@ class TestsPublishResultsTest extends BasePiperTest {
Map publisherStepOptions
List archiveStepPatterns
private ExpectedException thrown = ExpectedException.none()
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
@Rule
public RuleChain ruleChain = Rules
.getCommonRules(this)
.around(new JenkinsReadYamlRule(this))
.around(thrown)
.around(stepRule)
@Before
@ -126,4 +129,40 @@ class TestsPublishResultsTest extends BasePiperTest {
assertTrue('Cobertura options are not empty', publisherStepOptions.cobertura == null)
assertTrue('JMeter options are not empty', publisherStepOptions.jmeter == null)
}
@Test
void testBuildResultStatus() throws Exception {
stepRule.step.testsPublishResults(script: nullScript)
assertJobStatusSuccess()
}
@Test
void testBuildWithTestFailuresAndWithoutFailOnError() throws Exception {
nullScript.currentBuild.getRawBuild = {
return [getAction: { type ->
return [getFailCount: {
return 6
}]
}]
}
stepRule.step.testsPublishResults(script: nullScript)
assertJobStatusSuccess()
}
@Test
void testBuildWithTestFailuresAndWithFailOnError() throws Exception {
nullScript.currentBuild.getRawBuild = {
return [getAction: { type ->
return [getFailCount: {
return 6
}]
}]
}
thrown.expect(hudson.AbortException)
thrown.expectMessage('[testsPublishResults] Some tests failed!')
stepRule.step.testsPublishResults(script: nullScript, failOnError: true)
}
}

View File

@ -3,6 +3,7 @@ import static com.sap.piper.Prerequisites.checkScript
import com.cloudbees.groovy.cps.NonCPS
import com.sap.piper.ConfigurationHelper
import com.sap.piper.JenkinsUtils
import com.sap.piper.MapUtils
import com.sap.piper.Utils
import groovy.transform.Field
@ -13,7 +14,9 @@ import groovy.transform.Field
@Field def STEP_NAME = getClass().getName()
@Field Set GENERAL_CONFIG_KEYS = TOOLS
@Field Set STEP_CONFIG_KEYS = TOOLS
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
'failOnError'
])
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
/**
@ -24,10 +27,7 @@ import groovy.transform.Field
*/
void call(Map parameters = [:]) {
handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) {
def script = checkScript(this, parameters)
if (script == null)
script = this
def script = checkScript(this, parameters) ?: this
prepare(parameters)
@ -46,13 +46,15 @@ void call(Map parameters = [:]) {
stepParam1: parameters?.script == null
], configuration)
// UNIT TESTS
publishJUnitReport(configuration.get('junit'))
// CODE COVERAGE
publishJacocoReport(configuration.get('jacoco'))
publishCoberturaReport(configuration.get('cobertura'))
// PERFORMANCE
publishJMeterReport(configuration.get('jmeter'))
if (configuration.failOnError && JenkinsUtils.hasTestFailures(script.currentBuild)) {
script.currentBuild.result = 'FAILURE'
error "[${STEP_NAME}] Some tests failed!"
}
}
}