Should I use xUnitPublisher or xUnitBuilder after

2020-08-17 17:46发布

问题:

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

回答1:

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



回答2:

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:



回答3:

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.