How to test DotNet in Azure DevOps

In this article we will explain how to test dotnet core applications with Azure DevOps. It will attach unit test results as well as code coverage results in to the build pipeline.
In this article we will explain how to test dotnet core applications with Azure DevOps. It will attach unit test results as well as code coverage results in to the build pipeline.

Setting up the dotnet project

In our previous article we have explained How to build DotNet in Azure DevOps. So we will continue where we stopped and you can start with a basic .net web application.

Configure unit test porject

You can have a xUnit project with few unit test on it. When you create a xUnit project, it will automatically add coverlet.collector package. Here we will use that in order to calculate code coverage in Azure DevOps build pipeline

Configure azure pipeline

As mentioned earlier, we will continue where we stopped last time. So that we have the working Azure DevOps pipeline. In addition to what we have, we need to modify the content of the azure-pipelines.yml file to include following steps.
  • Run Unit Tests
  • Publish Code Coverage Results

Let's have a detail look on how we can do those.

Run Unit Tests

We can add DotNetCoreCLI task as a step soon after the previous dotnet build task and configure as following
        
- task: DotNetCoreCLI@2
  displayName: Test dotnet
  inputs:
    command: test
    projects: "**/*Tests/*.csproj"
    arguments: >-
      --configuration $(BuildConfiguration) 
      --no-build
      --collect "XPlat Code Coverage"
      
      

Here we are using wildcard filter for all the projects which end with Tests.cspoj

--no-build will tell the compiler to not to build the project since we already did it in previous step.

--collect "XPlat Code Coverage" will tell dotnet test command to include code coverage for the matching projects using coverlet.collector package.

Publish Code Coverage Results

Now it is time to submit the code coverage result. Lets add DotNetCoreCLI task as a step one more time and configure as following
        
- task: PublishCodeCoverageResults@1
  displayName: Publish code coverage
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: $(Agent.TempDirectory)/**/coverage.cobertura.xml
      
      

$(Agent.TempDirectory) is the directory where coverlet.collector package create the coverage reports.

Final yaml structure

        
trigger:
  - main
  - development
  - backlogs/*

variables:
  BuildConfiguration: "Release"
  DefaultProject: "test-dotnet-in-azure-devops"

steps:
  - task: DeleteFiles@1
    displayName: "Delete old test results"
    inputs:
      SourceFolder: "$(System.DefaultWorkingDirectory)"
      Contents: "**/TestResults/**"

  - task: DotNetCoreCLI@2
    displayName: "Restore dotnet packages"
    inputs:
      command: restore
      projects: "**/*.csproj"

  - task: DotNetCoreCLI@2
    displayName: "Build with $(buildConfiguration) configuration"
    inputs:
      projects: "**/*.csproj"
      arguments: "--configuration $(BuildConfiguration)"

- task: DotNetCoreCLI@2
  displayName: Test dotnet
  inputs:
    command: test
    projects: "**/*Tests/*.csproj"
    arguments: >-
      --configuration $(BuildConfiguration) 
      --no-build
      --collect "XPlat Code Coverage"
- task: PublishCodeCoverageResults@1
  displayName: Publish code coverage
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: $(Agent.TempDirectory)/**/coverage.cobertura.xml

  - task: DotNetCoreCLI@2
    displayName: "Publish"
    inputs:
      command: publish
      arguments: "$(Build.SourcesDirectory)/$(DefaultProject)/$(DefaultProject).csproj -c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory)"
      workingDirectory: "$(DefaultProject)"
      zipAfterPublish: False
      publishWebProjects: False

  - task: PublishBuildArtifacts@1
    displayName: "Publish artifact: drop"
    inputs:
      pathtoPublish: "$(Build.ArtifactStagingDirectory)"
      artifactName: "drop"
      publishLocation: "Container"
      
      

Now we are ready with the pipeline and you will see the unit tests and coverage results as part of the DevOps build.

Hope you enjoy the tutorial and see you soon in another very exiting tutorial