I could not find a relevant article for combined code coverage reporting of a project with both .NET Core tests and Javascript tests, so having spent far too much time working it out I have documented the steps necessary here to save you the same pain.
My projects are using XUnit to test my .NET Core code and npm with Jest to test my Javascript code.
In your package.json file you will need to include jest and jest-junit as dev dependencies setup the Jest testing to output results in Cobertura format, e.g.
"test": "jest --ci --coverage --reporters=jest-junit --reporters=default --coverageReporters=html --coverageReporters=cobertura",
In the Azure pipeline you will need to be running “test” as a custom npm command after npm has been installed, publish the Javascript tests so they are included in the test tab, create a code coverage report using the 3rd party tool “Report Generator”, and publish the code coverage results in a new tab.
Here is an example of what a simple Azure pipeline yml might look like. Items of special note are the exclusion of Views and Tests when the .NET Core testing is undertaken (I don’t want the 0% coverage of those items contaminating my overall results), and the combining of the Javasctipt cobertura-coverage.xml and .NET Core coverage.cobertura.xml files in the Report Generator step.
steps:
- task: DotNetCoreCLI@2
displayName: Restore
inputs:
command: restore
projects: '$(Parameters.RestoreBuildProjects)'
steps:
- task: Npm@1
displayName: 'npm install'
inputs:
workingDir: TestProject
verbose: false
steps:
- task: Npm@1
displayName: 'npm test'
inputs:
command: custom
workingDir: TestProject
verbose: false
customCommand: test
steps:
- task: PublishTestResults@2
displayName: 'Publish JS Test Results'
inputs:
testResultsFiles: junit.xml
searchFolder: TestProject
mergeTestResults: true
steps:
- task: DotNetCoreCLI@2
displayName: Build
inputs:
projects: '$(Parameters.RestoreBuildProjects)'
arguments: '--configuration $(BuildConfiguration)'
steps:
- task: DotNetCoreCLI@2
displayName: 'Test dotnet'
inputs:
command: test
projects: '$(Parameters.TestProjects)'
arguments: '--configuration $(BuildConfiguration) /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:Exclude=[TestProject.Views]*%2c[TestProject.Tests]*'
steps:
- script: |
dotnet tool install -g dotnet-reportgenerator-globaltool
reportgenerator -reports:$(Build.SourcesDirectory)/**/*[Tt]ests/**/coverage.cobertura.xml;$(Build.SourcesDirectory)/**/coverage/cobertura-coverage.xml -targetDir:$(Build.SourcesDirectory)/CodeCoverage -reporttypes:HtmlInline_AzurePipelines;Cobertura
displayName: 'Create Code Coverage Report'
steps:
- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage'
inputs:
codeCoverageTool: Cobertura
summaryFileLocation: '$(Build.SourcesDirectory)/CodeCoverage/Cobertura.xml'
reportDirectory: '$(Build.SourcesDirectory)/CodeCoverage'
steps:
- task: DotNetCoreCLI@2
displayName: Publish
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)'
steps:
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
Once you have the pipeline running you will end up with a new tab in the results named “Code Coverage”, here is an example test project output:
Underneath the summary are more detailed coverage results that you can drill into to see where you can improve.