Jenkins-pipeline-加入單元測試報告

將 Jenkins 的 pipeline 專案加入單元測試的一些注意事項

套件

Jenkins 可以搭配下列兩個套件來加入單元測試報告,直接在 plugin 頁面進行安裝即可

  1. VSTest Runner
  2. MSTest Runner

設定

目前設定流程:Git–>NuGet–>Build–>Deploy

加入單元測試:Git–>NuGet–>Test–>Build–>Deploy

各個環節的細部設定就不提了,以下是單元測試的設定範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
stage('nuget') {
// nuget
}
stage('build Test') {
bat label: '', script: '''
chcp 65001
msbuild MyProject.Core.Test\\MyProject.Core.Test.csproj /p:Configuration=Debug /t:Rebuild
'''

vsTest cmdLineArgs: '/Logger:trx;LogFileName=MyProject.Core.trx', testFiles: 'MyProject.Core.Test\\bin\\Debug\\MyProject.Core.Test.dll'
mstest testResultsFile: 'TestResults/MyProject.Core.trx'

if (currentBuild.result == "FAILURE") {
error('測試失敗')
}
}

.net6

如果專案是.NET6,直接可以透過 CLI 下指令去測試,並產生報告檔,再接著透過 mstest 指定報告檔的路徑就可以了

1
2
3
4
5
6
7
8
9
stage('unitTest') {
bat returnStatus: true, script: '''
chcp 65001
c:
cd C:\\Program Files\\dotnet
dotnet test -c Release "D:\\MyProject.Core.Test\\MyProject.Core.Test.csproj" --filter TestCategory=UnitTest --logger "trx;LogFileName=unit_tests.xml"
'''
mstest testResultsFile: '**/unit_tests.xml'
}

踩過的坑

工具版本不一

LAB 環境已經有點久了,所以安裝的軟體都還蠻舊的,使用msbuild的指令在 LAB 環境與 Local 環境有差異,需要加上一些參數並指定版本,為了避免這樣的情況,希望可以使用相同的設定,因此需要將 Jenkins 主機上的工具程式更新

微軟有提供一個東西叫做BuildTools,而且很神奇的非常難找到下載點,還好在這篇文章 Build Tools for Visual Studio 裏面有好心人士直接提供直接下載連結

下載後安裝buildTools,將頁籤切換到個別工具,找到測試相關類別底下有一個中文叫做測試工具的核心功能 - 建置工具,打勾才會安裝VSTest.console.exe

Jenkins 外掛設定

怕影響到其他使用原有舊程式的 Jenkins 專案,所以沒有設定path,使用到msbuild以及VSTest.console.exe的地方,都透過絕對路徑來呼叫,而絕對路徑中間有空格,就必須要使用雙引號將整段括起來
若不須考慮舊專案,可以直接在系統環境變數中將路徑加上,這樣在指令列就不需要輸入完整路徑呼叫工具

接著是 Jenkins 的 plugin 設定,需要在JenkinsGlobal Tool Configuration裡面設定好工具程式的呼叫方式,此處可以直接用雙引號將絕對路徑打上,如果先前有設定path,也可以直接輸入執行檔名稱就好。以VSTest.Console.exe為例,可以直接設定

1
"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"

工作區目錄與發佈目錄

因為在 LAB 環境有區分工作區目錄、發佈目錄,所以最好遵循著流程,測試通過之前都操作都在工作區做,所以建議在 Git 下載原始碼之後,就直接在工作區建置測試專案,接著測試通過後才進行發佈

測試失敗後未能中斷 pipeline

利用if指令判斷當前狀態來決定是否中斷,範例可參考先前的設定

中斷 pipeline

在 Jenkins pipeline 中整合另外一篇文章Jenkins 檢查前端編譯程式有無簽入版控,測試了一下後發現若發生錯誤未能中斷 pipeline,查了一下,解決的方式如下

使用 bat 去執行命令,可以讓回傳狀態碼,然後將它存到變數內

1
2
3
4
def x = bat(
returnStdout: true,
script: "exit 1"
)

然後再 stage 的區段之內,透過if判斷式來拋error

1
2
3
if (x == 1) {
error('something wrong!')
}

其他

Code Coverage 並沒有加入,一方面是因為我沒有使用VSTest.console.exe或是NCover做出來,以前曾經有做過DotCover.exe的覆蓋率報告,但是它不是免費的,所以不能用在公司的機器上,而我自己若需要覆蓋率的資訊,現在其實也都使用Rider的功能去看我的 Production Code 還有哪個邏輯分支沒有被覆蓋到,它是屬於哪一個測試案例,我有沒有需要為此寫一個測試,所以在 Jenkins 上面也不太需要報告;而且單元測試覆蓋率其實一直有個爭議,很容易讓大家追求這個數據要越高越好,但其實這也是一種浪費,有興趣了解的人可以自行查詢一下,我很推薦 91 的這篇文章:測試覆蓋率與 TDD 的正確心態,裡面的童子軍法則其實就是每天進步一點點的概念,這樣的方式也比較容易達成,至少把自己製造的垃圾帶走吧~