Nx: Display test results and code coverage on TFS/DevOps(VSTS)

Created on 20 Oct 2018  Â·  12Comments  Â·  Source: nrwl/nx

I have setup my workspace to generate test results using jest-junit but every app or lib overrides the previously generated junit.xml file, so it actually ends up with the lastly executed tests.

Is there any way how to merge the junit.xml results and not to override?

Anyway, my question is actually more related to if anyone has successfully integrated JEST test results/codecoverage into TFS/DevOps(VSTS) CI pipeline?

testing tools question / discussion

Most helpful comment

We also encountered the issue of the junit.xml file getting replaced for each test suite. We found out Azure DevOps can handle multiple xml-files, so our solution was to change the root jest.config.js to include the following reporters:

reporters: ['default', ['jest-junit', { outputDirectory: './junit', outputName: new Date().getTime() + '.xml' }]]

This way it will create a new xml file inside a junit folder for every test suite with the name of the current timestamp the suite ran. Then you can add the junit folder to Azure DevOps.

Our solution of only running JUnit in CI environment was to add an environment variable to our command:

JUNIT=true ng test --ci --code-coverage

And then add a conditional to our Jest config:

reporters: process.env.JUNIT
    ? ['default', ['jest-junit', { outputDirectory: './junit', outputName: new Date().getTime() + '.xml' }]]
    : ['default'],

Hope this helps someone and hoping for a better solution out of the box from the Nx team in the future.

All 12 comments

I managed to get test results being displayed in TFS by manually updating jest.config.js of each app/lib. Would it be possible to add an option to generate reporters section in jest.config.js?

    reporters: [
        'default',
        [
            'jest-junit',
            {
                output: 'test/<libs/apps>-<folder>-<name>-junit.xml',
                usePathForSuiteName: 'true',
            },
        ],
    ],

I am having the same problem. I got to batch jest-junit index.js and override it with the following

processor = (report, reporterOptions = {}) => {
  // If jest-junit is used as a reporter allow for reporter options
  // to be used. Env and package.json will override.
  const options = getOptions.options(reporterOptions);

  const jsonResults = buildJsonResults(report, fs.realpathSync(process.cwd()), options);

  // Ensure output path exists
  mkdirp.sync(path.dirname(options.output));

  if (fs.existsSync(options.output.replace('xml', 'json'))) {
    var contents = JSON.parse(fs.readFileSync(options.output.replace('xml', 'json'), 'utf8'));
    const currentAttr = jsonResults.testsuites[0]._attr;
    contents.testsuites[0]._attr.tests += currentAttr.tests;
    contents.testsuites[0]._attr.failures += currentAttr.failures;
    contents.testsuites[0]._attr.time += currentAttr.time;
    jsonResults.testsuites.shift();
    jsonResults.testsuites = contents.testsuites.concat(jsonResults.testsuites);
  }
  // Write data to file
  fs.writeFileSync(options.output, xml(jsonResults, {
    indent: '  '
  }));
  fs.writeFileSync(options.output.replace('xml', 'json'), JSON.stringify(jsonResults));

  // Jest 18 compatibility
  return report;
};

But now I am facing a new issue for collecting coverage for sonar. It expects one lcov.info file per repo, but NX is creating one per app/lib. Now I am wondering if a jest.config per app/lib was a good design or not?

@mohyeid Yep, I did the same with this https://github.com/Leonidas-from-XIV/node-xml2js
So, I have a build task which actually merge all the cobertura files into one. It's more like a hack then a solution. I just wonder what is the recommendation from NRWL team. I don't believe they didn't face this issue as CC results is pretty common task.

We also encountered the issue of the junit.xml file getting replaced for each test suite. We found out Azure DevOps can handle multiple xml-files, so our solution was to change the root jest.config.js to include the following reporters:

reporters: ['default', ['jest-junit', { outputDirectory: './junit', outputName: new Date().getTime() + '.xml' }]]

This way it will create a new xml file inside a junit folder for every test suite with the name of the current timestamp the suite ran. Then you can add the junit folder to Azure DevOps.

Our solution of only running JUnit in CI environment was to add an environment variable to our command:

JUNIT=true ng test --ci --code-coverage

And then add a conditional to our Jest config:

reporters: process.env.JUNIT
    ? ['default', ['jest-junit', { outputDirectory: './junit', outputName: new Date().getTime() + '.xml' }]]
    : ['default'],

Hope this helps someone and hoping for a better solution out of the box from the Nx team in the future.

Any news on this?
@flugger 's option is a viable one to have devops merge all the files, but it seems a bit strange that we'd have to _hack_ it together rather than having something out of the box?

@jaysoo could you comment on this?

@flugger
Our solution is to add the following line into each jest config per project.
reporters: ["default", ["jest-junit", {outputDirectory: './coverage/apps/app1'}]]

@vsavkin @FrozenPandaz @bcabanes
Maybe this is a possible solution for nx?

@vsavkin is this feature request on the backlog somewhere?

@flugger @EvtK - We resolved it by adding jest-config dependency and following piece of code in jest-config.json

reporters: [["jest-unit", {
    "outputDirectory": '<rootDir>',
    "outputName": "test-report.xml"
}]]

this will generate test-report.xml in respective directories which you can converge in azure devops task like below

- task: PublishTestResults@2
    inputs:
      testResultsFormat: 'JUnit'
      testResultsFiles: '**/test-report.xml'
      testRunTitle: 'Jest Unit Tests'
      mergeTestResults: true
      failTaskOnFailedTests: true

It looks like there isn't any work needed from Nx's to support multiple junit reports.

@adinath 's solution should work for everyone since <rootDir> will be the root of each app/lib, which means the reports will no override each other.

@adinath thanks for sharing your solution.

In the end the solution is the same: you need to distinguish in generating the reports and then later merge them yourself. It would be nice if this was an out of the box functionality within NX. But.. the current solutions are sufficient.

I was able to get unique files per libs/apps using this jest config.

reporters: [
    'default',
    [
      'jest-junit',
      {
        suiteName: 'jest tests',
        outputDirectory: 'build/test-results',
        uniqueOutputName: 'true',
        classNameTemplate: '{classname}-{title}',
        titleTemplate: '{classname}-{title}',
        ancestorSeparator: ' › ',
        usePathForSuiteName: 'true',
      },
    ],
  ],

Getting files with uuid numbers:
junit-d44f8e60-ff33-11ea-a312-85dbd838ca1a.xml

Was this page helpful?
0 / 5 - 0 ratings

Related issues

markphip picture markphip  Â·  3Comments

SWGeekPD picture SWGeekPD  Â·  3Comments

MichaelWarneke picture MichaelWarneke  Â·  3Comments

ZempTime picture ZempTime  Â·  3Comments

kmkatsma picture kmkatsma  Â·  3Comments