SonarQube-測試報告的產生

關於 sonarQube 裡面的測試覆蓋率是需要先建立測試報告,並指定路徑提供給 sonarQube 進行分析,這樣才會顯示正確的數據,這一篇文章將會介紹一下個人的使用經驗

關於 sonarQube 的部分,請參考:SonarQube 程式碼分析工具 - 2022

導入 .net 測試報告

如果要導入.net 的測試報告,必須經由下列的四個步驟來完成

  1. 執行 SonarScanner.MSBuild.exe begin指令開始分析專案
  2. 執行 msbuild開始建構專案
  3. 執行測試工具,並將報告產生於步驟 1 的指定路徑
  4. 執行 SonarScanner.MSBuild.exe end指令結束分析

之所以會有第三個步驟,原因是SonarScanner其實並不會針對專案執行測試,或者是產生報告,它只是引用報告的數據而已

SonarScanner針對不同的語言有不同的報告導入參數需要設定,完整的清單可以到官網查看Test Coverage & Execution

官網可能改版連結也會失效,但是它們的文件的確是越寫越好,直接進官網文件搜尋關鍵字也是不錯的方式

SonarScanner for MSBuild

msbuild 有自己的 scanner,可以到這邊查看詳細資訊

若採用 dotnet framework,直接下載他們的.NET framework 4.6+ 工具下載解壓縮後就可執行SonarScanner.MSBuild.exe;若採用 dotnet core,可以考慮直接使用 dotnet tool比較方便

1
2
# 安裝 dotnet tool
dotnet tool install --global dotnet-sonarscanner --version 4.10.0

Test Coverage

Language Property Remarks
Any sonar.coverageReportPaths 通用的報告格式
c# sonar.cs.vscoveragexml.reportsPaths 針對 Visual Studio Code Coverage Report 格式的報告。多個報告以逗號分隔;也可採用萬用字元
c# sonar.cs.dotcover.reportsPaths 針對 dotCover 產生的報告所使用的參數
c# sonar.cs.opencover.reportsPaths 針對 openCover 產生的報告所使用的參數
javaScript
TypeScript
sonar.javascript.lcov.reportPaths LCOV coverage report,支援以逗號分隔的絕對/虛擬路徑

Test Execution

Language Property Remarks
Any sonar.testExecutionReportPaths 通用的報告格式
c# sonar.cs.vstest.reportsPaths VSTest reports,多個報告以逗號分隔;也可採用萬用字元
c# sonar.cs.nunit.reportsPaths NUnit execution reports,同上
c# sonar.cs.xunit.reportsPaths xUnit execution reports,同上
javaScript
TypeScript
透過jest-sonar-reporter或是karma-sonarqube-unit-reporter產生通用的報告格式

實際範例

所以重點就在於如何產生報告放在指定路徑,並透過參數告知sonarScanner

.net framework

下面這個範例專案採用的是.net framework,所以測試針對 dll 執行,產生多個 dcvr 後合併並轉為 html 報告,指定給 sonarScanner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 開始分析
SonarScanner.MSBuild.exe begin
/k:"myTestProject"
/d:sonar.host.url="http://127.0.0.1:9090"
/d:sonar.login="32aafa7ac56a55dae90d0891487e7af98506ed33"
/d:sonar.cs.dotcover.reportsPaths="report.html"
/d:sonar.cs.vstest.reportsPaths="TestResults/*.trx"
/d:sonar.exclusions=myTestProject/Scripts/Plugins/**,myTestProject/Content/**
/d:sonar.verbose=true

# 建置專案
msbuild myTestProject.Web\\myTestProject.Web.csproj /p:OutputPath="D:\\MSBuildOut\\myTestProject.Web" /p:Configuration=Debug /t:Rebuild

# 產生多個測試報告並合併結果
"D:\art\programs\JetBrains.dotCover.CommandLineTools.2019.3.1\dotCover.exe" cover /TargetExecutable="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" /TargetArguments="myTestProject.Adapter.Test.dll" /TargetWorkingDir="myTestProject.Adapter.Test\bin\debug" /Output="myTestProject.Adapter.Test.dcvr" /Filters=-:module=Dapper;-:module=myTestProject.Adapter.Test
"D:\art\programs\JetBrains.dotCover.CommandLineTools.2019.3.1\dotCover.exe" cover /TargetExecutable="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" /TargetArguments="myTestProject.Core.Test.dll" /TargetWorkingDir="myTestProject.Core.Test\bin\debug" /Output="myTestProject.Core.Test.dcvr" /Filters=-:module=Dapper;-:module=myTestProject.Core.Test;-:module=StackExchange.Redis
"D:\art\programs\JetBrains.dotCover.CommandLineTools.2019.3.1\dotCover.exe" cover /TargetExecutable="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" /TargetArguments="myTestProject.DataService.Test.dll" /TargetWorkingDir="myTestProject.DataService.Test\bin\debug" /Output="myTestProject.DataService.Test.dcvr" /Filters=-:module=Dapper;-:module=myTestProject.DataService.Test
"D:\art\programs\JetBrains.dotCover.CommandLineTools.2019.3.1\dotCover.exe" merge --Source=myTestProject.Adapter.Test.dcvr;myTestProject.Core.Test.dcvr;myTestProject.DataService.Test.dcvr --Output=Merged.dcvr
"D:\art\programs\JetBrains.dotCover.CommandLineTools.2019.3.1\dotCover.exe" report --source=merged.dcvr --output=report.html --reportType=html


vstest.console.exe /Logger:trx;LogFileName=myTestProject.Adapter.trx "myTestProject.Adapter.Test\bin\Debug\myTestProject.Adapter.Test.dll"
vstest.console.exe /Logger:trx;LogFileName=myTestProject.Core.trx "myTestProject.Core.Test\bin\Debug\myTestProject.Core.Test.dll"
vstest.console.exe /Logger:trx;LogFileName=myTestProject.DataService.trx "myTestProject.DataService.Test\bin\Debug\myTestProject.DataService.Test.dll"

# 結束分析
SonarScanner.MSBuild.exe end /d:sonar.login="32aafa7ac56a55dae90d0891487e7af98506ed33"

.netCore 2

這個範例是 .netCore,scanner 就不一樣了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 開始分析
dotnet sonarscanner begin
/k:"TestProject"
/d:sonar.host.url="http://127.0.0.1:9090"
/d:sonar.login="2c244539263ac8b5c4b4414b2b8c190a8ca873d9"
/d:sonar.cs.dotcover.reportsPaths="AppCoverageReport.html"

# 建置專案
dotnet build TestProject.sln

# 產生報告
dotCover cover
--TargetExecutable="C:\Program Files\dotnet\dotnet.exe"
--TargetWorkingDir="TestProject.Tests"
--TargetArguments="test \"TestProject.Tests.csproj\""
--Filters=-:TestProject.Tests
--output=AppCoverageReport.html
--reportType=HTML

# 結束分析
dotnet sonarscanner end /d:sonar.login="2c244539263ac8b5c4b4414b2b8c190a8ca873d9"

參考連結

[Coverage & Test Data] Generate Reports for C#, VB.net

這一篇文章提供了產生報告的範例指令

Test Coverage & Execution

官網文件

結論

這邊的測試報告我都採用 dotCover 來做,但是它並不是免費使用的;但仍舊有替代方案可選擇,不過我就不另外贅述了
關於測試報告的部分我覺得對於 sonarQube 是很重要的一個環節,因為主打的是軟體品質管理,少了測試報告的部分就差很多

2022-06-15:上述是有錯誤的,其實 dotCover Cli Command 是可以免費使用的,需要購買使用的是 dotCover GUI 版本