# Sonarcloud Code coverage

**URL:** <https://community.sonarsource.com/t/sonarcloud-code-coverage/105344>\
**Category:** SonarQube Cloud\
**Tags:** github-actions, coverage, scanner\
**Created:** [December 1, 2023, 12:22pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344 "2023-12-01T12:22:02Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dantrew](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/dantrew/32/52238_2.png) [@Dantrew](https://community.sonarsource.com/u/Dantrew)\
**Post date:** [December 1, 2023, 12:22pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/1 "2023-12-01T12:22:02Z")

</div>

I starting to pull my hair because I can’t get the coverage to work. I have read documents on sonarcloud, visual studio, forums both here and stack, asked chatgpt etc etc. I can generate a testfile as you will see in my workflow. Here is the workflow

```auto
name: SonarCloud
on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  build:
    name: Build and analyze
    runs-on: windows-latest
    steps:
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'zulu'

      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Cache SonarCloud packages
        uses: actions/cache@v3
        with:
          path: ~\sonar\cache
          key: ${{ runner.os }}-sonar
          restore-keys: ${{ runner.os }}-sonar
    
      - name: Cache SonarCloud scanner
        id: cache-sonar-scanner
        uses: actions/cache@v3
        with:
          path: .\.sonar\scanner
          key: ${{ runner.os }}-sonar-scanner
          restore-keys: ${{ runner.os }}-sonar-scanner
    
      - name: Install SonarCloud scanner
        if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
        shell: powershell
        run: |
          New-Item -Path .\.sonar\scanner -ItemType Directory
          dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
     
      - name: Install dotnet-coverage tool
        run: dotnet tool install --global dotnet-coverage
     
      - name: Build and analyze
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        shell: powershell
        run: |
          .\.sonar\scanner\dotnet-sonarscanner begin /k:"lind-exe_Statify" /o:"lind-exe" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.dotcover.reportsPaths="coverage.xml"
  
          dotnet build --no-incremental
          dotnet test # Run your tests
          
          # Collect coverage using dotnet-coverage in Cobertura and output to coverage.xml
          dotnet-coverage collect "dotnet test" -f cobertura -o "coverage.xml"
          
          # Display content of coverage.xml for debugging
          Get-Content -Path "coverage.xml"
    
          .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"

```

When I build and do the debugg part to se the file I find it

```auto
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

Passed! - Failed: 0, Passed: 12, Skipped: 0, Total: 12, Duration: 57 ms - Statify.Tests.dll (net7.0)
Code coverage results: coverage.xml.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<coverage line-rate="0.3877551020408163" branch-rate="0.10576923076923077" complexity="420" version="1.9" timestamp="1701428294" lines-covered="266" lines-valid="686" branches-covered="11" branches-valid="104">

```

Then when I want Sonarcloud to upload it it cannot read the test report, It seems it want a JaCoCo?

INFO: Sensor JaCoCo XML Report Importer [jacoco]

[3455](https://github.com/lind-exe/Statify/actions/runs/7059079494/job/19215935217#step:8:3456)INFO: ‘sonar.coverage.jacoco.xmlReportPaths’ is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml

[3456](https://github.com/lind-exe/Statify/actions/runs/7059079494/job/19215935217#step:8:3457)INFO: No report imported, no coverage information will be imported by JaCoCo XML Report Importer

And my coveragereport get this:

WARN: Could not import coverage report ‘.\coverage.xml’ because ‘Only dotCover HTML reports which start with “” are supported.’. Troubleshooting guide: [[Coverage] Troubleshooting guide for .NET code coverage import](https://community.sonarsource.com/t/37151)

I have only worked with workflows for 3 weeks beside building a project. I’m studying a .NET course and have only studied for 1 year and 3 months. So this is kinda confusing. How do I get the code cevarge to display on Sonarcloud.

---

<div class="post-metadata">

**Author:** ![ganncamp](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/ganncamp/32/1261_2.png) [@ganncamp](https://community.sonarsource.com/u/ganncamp)\
**Post date:** [December 4, 2023, 4:06pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/2 "2023-12-04T16:06:03Z")

</div>

Hi,

Per [the docs](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/dotnet-test-coverage/#visual-studio-code-coverage) it looks like you need to tweak your coverage command slightly to

> `dotnet test --collect "Code Coverage"`

The resulting coverage will be read automatically, with no need (for analysis purposes, anyway) to do this:

> [@Dantrew](#):
>
> ```auto
> dotnet-coverage collect "dotnet test" -f cobertura -o "coverage.xml"
> 
> ```

&nbsp;  
HTH,  
Ann

---

<div class="post-metadata">

**Author:** ![Dantrew](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/dantrew/32/52238_2.png) [@Dantrew](https://community.sonarsource.com/u/Dantrew)\
**Post date:** [December 4, 2023, 8:42pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/3 "2023-12-04T20:42:27Z")

</div>

```auto
INFO: Aggregating the HTML reports from 'D:\a\Statify\Statify\.\Statify.Tests\TestResults\39c0e905-353c-4cc9-ad8c-729302d6c55a\48d846f1-0e60-422d-859e-729084be50d8.coverage'.
WARN: Could not import coverage report '.\Statify.Tests\TestResults\39c0e905-353c-4cc9-ad8c-729302d6c55a\48d846f1-0e60-422d-859e-729084be50d8.coverage' because 'Only dotCover HTML reports which start with "<!DOCTYPE html>" are supported.'. Troubleshooting guide: https://community.sonarsource.com/t/37151
INFO: Sensor C# Tests Coverage Report Import [csharp] (done) | time=362ms

```

Then I get this instead in my workflow.

---

<div class="post-metadata">

**Author:** ![ganncamp](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/ganncamp/32/1261_2.png) [@ganncamp](https://community.sonarsource.com/u/ganncamp)\
**Post date:** [December 5, 2023, 2:45pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/4 "2023-12-05T14:45:27Z")

</div>

Hi,

Could you share your updated workflow?

&nbsp;  
Thx,  
Ann

---

<div class="post-metadata">

**Author:** ![Dantrew](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/dantrew/32/52238_2.png) [@Dantrew](https://community.sonarsource.com/u/Dantrew)\
**Post date:** [December 6, 2023, 8:07am UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/5 "2023-12-06T08:07:53Z")

</div>

Here is the full workflow now. I find the file but it doesn’t get pushed to my Sonarcloud. Everything else is shown.

```auto
name: SonarCloud
on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  build:
    name: Build and analyze
    runs-on: windows-latest
    steps:
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'zulu'

      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Cache SonarCloud packages
        uses: actions/cache@v3
        with:
          path: ~\sonar\cache
          key: ${{ runner.os }}-sonar
          restore-keys: ${{ runner.os }}-sonar
    
      - name: Cache SonarCloud scanner
        id: cache-sonar-scanner
        uses: actions/cache@v3
        with:
          path: .\.sonar\scanner
          key: ${{ runner.os }}-sonar-scanner
          restore-keys: ${{ runner.os }}-sonar-scanner
    
      - name: Install SonarCloud scanner
        if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
        shell: powershell
        run: |
          New-Item -Path .\.sonar\scanner -ItemType Directory
          dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
     
      - name: Install dotnet-coverage tool
        run: dotnet tool install --global dotnet-coverage
     
      - name: Build and analyze
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        shell: powershell
        run: |
          $coverageFilePath = $env:COVERAGE_FILE_PATH
          
          .\.sonar\scanner\dotnet-sonarscanner begin /k:"lind-exe_Statify" /o:"lind-exe" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.dotcover.reportsPaths="**/*.coverage"
          dotnet build --no-incremental
          dotnet test --collect "Code Coverage"
    
          # Attempt to find the coverage.cobertura.xml file
          $coverageFile = Get-ChildItem -Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY -Recurse -Filter "coverage.cobertura.xml" | Select-Object -ExpandProperty FullName

          if ($coverageFile) {
          # Display content of coverage.cobertura.xml for debugging
          Get-Content -Path $coverageFile

          .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
          } else {
          Write-Host "coverage.cobertura.xml not found."
          exit 1
          }

```

---

<div class="post-metadata">

**Author:** ![ganncamp](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/ganncamp/32/1261_2.png) [@ganncamp](https://community.sonarsource.com/u/ganncamp)\
**Post date:** [December 6, 2023, 4:29pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/6 "2023-12-06T16:29:08Z")

</div>

Hi,

This part looks right to me:

> [@Dantrew](#):
>
> ```auto
> dotnet build --no-incremental
> dotnet test --collect "Code Coverage"
> 
> ```

This part I don’t understand why you would make running the `end` step conditional on finding an unrelated file:

> [@Dantrew](#):
>
> `/d:sonar.cs.dotcover.reportsPaths="**/*.coverage"`

I also don’t understand

> [@Dantrew](#):
>
> ```auto
> if ($coverageFile) {
> # Display content of coverage.cobertura.xml for debugging
> Get-Content -Path $coverageFile
> 
> .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
> } else {
> Write-Host "coverage.cobertura.xml not found."
> exit 1
> }
> 
> ```

&nbsp;  
Ann

---

<div class="post-metadata">

**Author:** ![Dantrew](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/dantrew/32/52238_2.png) [@Dantrew](https://community.sonarsource.com/u/Dantrew)\
**Post date:** [December 7, 2023, 9:20am UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/7 "2023-12-07T09:20:32Z")

</div>

I was trying to find the file and specify where sonarcloud should look for it.  
Now I have just this in the last step

```auto
- name: Build and analyze
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        shell: powershell
        run: |
          $coverageFilePath = $env:COVERAGE_FILE_PATH
          
          .\.sonar\scanner\dotnet-sonarscanner begin /k:"lind-exe_Statify" /o:"lind-exe" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" 
          dotnet test --collect "Code Coverage"
          .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"

```

And it gives me the analys on all thing (ANALYSIS SUCCESSFUL, you can find the results at: [SonarCloud](https://sonarcloud.io/dashboard?id=lind-exe_Statify&branch=main)) but not the coverage part. Here is what I can find in my workflow. The dotnet coverage tool is Cobertura right? But why does it look for a JaCoco file? Therefore I tried to give the it a specific path.

```auto
INFO: Sensor JaCoCo XML Report Importer [jacoco]

[147](https://github.com/lind-exe/Statify/actions/runs/7126020883/job/19403078370#step:8:148)INFO: 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml

[148](https://github.com/lind-exe/Statify/actions/runs/7126020883/job/19403078370#step:8:149)INFO: No report imported, no coverage information will be imported by JaCoCo XML Report Importer

[149](https://github.com/lind-exe/Statify/actions/runs/7126020883/job/19403078370#step:8:150)INFO: Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms

[150](https://github.com/lind-exe/Statify/actions/runs/7126020883/job/19403078370#step:8:151)INFO: Sensor IaC CloudFormation Sensor [iac]

```

---

<div class="post-metadata">

**Author:** ![ganncamp](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/ganncamp/32/1261_2.png) [@ganncamp](https://community.sonarsource.com/u/ganncamp)\
**Post date:** [December 7, 2023, 2:36pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/8 "2023-12-07T14:36:42Z")

</div>

Hi,

All the sensors run in every analysis. Each one basically pokes its head up to see if there’s any work for it to do, and if not, then just turns back off. That’s why you see log lines about JaCoCo. You can safely ignore them.

> [@Dantrew](#):
>
> The dotnet coverage tool is Cobertura right?

The options are detailed [here in the docs](https://docs.sonarsource.com/sonarcloud/enriching/test-coverage/dotnet-test-coverage/), with a concise listing across languages [here](https://docs.sonarsource.com/sonarcloud/enriching/test-coverage/test-coverage-parameters/#c). Cobertura is only supported for Flex and Python.

> [@Dantrew](#):
>
> but not the coverage part

Can you provide a fresh, debug analysis log?

[This guide](https://community.sonarsource.com/t/how-to-find-logs-about-importing-code-coverage/73317) will help you find them.

&nbsp;  
Ann

---

<div class="post-metadata">

**Author:** ![Dantrew](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/dantrew/32/52238_2.png) [@Dantrew](https://community.sonarsource.com/u/Dantrew)\
**Post date:** [December 7, 2023, 7:42pm UTC](https://community.sonarsource.com/t/sonarcloud-code-coverage/105344/9 "2023-12-07T19:42:35Z")

</div>

```auto
name: SonarCloud
on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  build:
    name: Build and analyze
    runs-on: windows-latest
    steps:
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'zulu'

      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Cache SonarCloud packages
        uses: actions/cache@v3
        with:
          path: ~\sonar\cache
          key: ${{ runner.os }}-sonar
          restore-keys: ${{ runner.os }}-sonar
    
      - name: Cache SonarCloud scanner
        id: cache-sonar-scanner
        uses: actions/cache@v3
        with:
          path: .\.sonar\scanner
          key: ${{ runner.os }}-sonar-scanner
          restore-keys: ${{ runner.os }}-sonar-scanner
    
      - name: Install SonarCloud scanner
        if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
        shell: powershell
        run: |
          New-Item -Path .\.sonar\scanner -ItemType Directory
          dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
     
      - name: Install dotnet-coverage tool
        run: dotnet tool install --global dotnet-coverage
     
      - name: Build and analyze
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        shell: powershell
        run: |
        
          .\.sonar\scanner\dotnet-sonarscanner begin /k:"lind-exe_Statify" /o:"lind-exe" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml
          dotnet build --no-incremental
          dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml" 
          dotnet test --collect "Code Coverage"
          .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"

```

Now it works 🙂 I followed the guides again. Thanks for pointing me to the right direction.
