I am automating a dot net core build
Given the following snippet in my Jenkins file, I generate an XML file for every test project I have. In the following step I would like to process these XML files.
Jenkins gives two options. I am confused which option to use. Do I use "process" or "publish". Both give the same options regarding thresholds, both appear to do the same. They both mark the build FAILED, they both provide Jenkins with a test report. Is this legacy? Or are they completely different steps, with their own purpose?
BTW, is this FAILURE check and throwing an error the only way to stop Jenkins from continuing the build? It seems a bit strange when a build is marked FAILED to just continue the rest of the steps. If I wanted to continue I could also set stopProcessingIfError to false, or am I missing the point?
stage('Test') {
def testScript = ""
def testProjects = findFiles(glob: 'test/**/project.json')
if (!fileExists('reports/xml')) {
if (!fileExists('reports')) {
sh "mkdir reports"
}
sh "mkdir reports/xml"
}
for(prj in testProjects) {
println "Test project located, running tests: " + prj.path
def matcher = prj.path =~ 'test\\/(.+)\\/project.json'
testScript += "dotnet test --no-build '${prj.path}' -xml 'reports/xml/${matcher[0][1]}.Results.xml' || true\n"
}
sh testScript
step([
$class: 'XUnitBuilder',
thresholdMode: 1,
thresholds: [[$class: 'FailedThreshold', failureThreshold: '1']],
tools: [[
$class: 'XUnitDotNetTestType',
deleteOutputFiles: true,
failIfNotNew: true,
pattern: 'reports/xml/*.Results.xml',
skipNoTestFiles: false,
stopProcessingIfError: true
]]
])
if (currentBuild.result.equals("FAILURE")) {
throw "Test results did not pass thresholds"
}
}
After a look at the source code, they seem to be identical in functionality, except XUnitPublisher
has one extra method, the purpose of which I do not understand(!), and the class declares more interfaces in the implements
list.
The crucial difference seems to be that XUnitPublisher
class extends the hudson.tasks.Recorder
class, while XUnitBuilder
extends the hudson.tasks.Builder
.
I believe the user-facing difference is that a failure in a builder marks the Jenkins job as "failed", while failure in a publisher marks the job as "unstable". (source: https://wiki.jenkins.io/display/JENKINS/Terminology)
Given all this, I'd recommend going with xUnitPublisher. I set up my build command to return 0 if compilation passed but some tests failed. This way, Jenkins gives me a FAILED status for broken compilation and UNSTABLE status for working compilation but failing tests. I like it this way.
Commit history does not explain why there is this ridiculous duplication of code. I'd understand if one was implemented in terms of the other, as is usually done when deprecating... Probably because each has to have a different superclass.
XUnitBuilder.java, XUnitPublisher.java
I managed to do so using this simple groovy \ pipline + running unittests
So the final pipeline is:
node {
stage 'Checkout'
checkout scm
stage 'Build'
bat "\"C:/Program Files/dotnet/dotnet.exe\" restore \"${workspace}/MyProg.sln\""
bat "\"C:/Program Files/dotnet/dotnet.exe\" build \"${workspace}/MyProg.sln\""
stage 'UnitTests'
bat returnStatus: true, script: "\"C:/Program Files/dotnet/dotnet.exe\" test \"${workspace}/MyProg.sln\" --logger \"trx;LogFileName=unit_tests.xml\" --no-build"
step([$class: 'MSTestPublisher', testResultsFile:"**/unit_tests.xml", failOnError: true, keepLongStdio: true])
}
I have uploaded some examples that I made to my GitHub for everyone to use and contribute, feel free to take a look:
https://github.com/avrum/JenkinsFileFor.NETCore
Those pipline jenkinsfile will add this pipline template to your build:
From log:
WARNING: XUnitBuilder step is deprecated since 2.x, it has been replaced by XUnitPublisher. This builer will be remove in version 3.x
So the answer is: use XUnitPublisher, as described on answer 1 above.