在上篇介紹了OpenCover的基本運作概念和為什麼要使用OpenCover,在這篇將會實際把OpenCover整合到Build Script裡面。
準備Build Script
要把OpenCover整合進入Build script需要做幾個事情:
- 把OpenCover加入到Build專案
- 建立一個Helper用來執行OpenCover
- 準備好執行Helper的參數
- 調整測試呼叫方式
把OpenCover加入到Build專案
這個部分需要先用Nuget把Opencover加入(Install-Package Opencover),之後,在Build Script裡面會多增加一個property
:
$openCoverExe = (Get-PackagePath $packageDirectoryPath "OpenCover") + "\tools\OpenCover.Console.exe"
建立一個Helper用來執行OpenCover
在上篇提到,其實opencover有一個profiler,這個profiler會執行Test Runner,然後profiler會監控test runner記錄執行測試的涵蓋率。
因此,變成不直接呼叫TestRunner了,而是透過OpenCover,因此建立一個helper方法會方便呼叫測試。
OpenCover其實有滿多的設定,下面會一個一個介紹:
- target
- 這個是用來執行Test Runner的路徑
- targetargs
- 這邊是指要傳入給target的參數
- output
- 這邊指的是Opencover的涵蓋率結果要儲存的位置
- register
- 一直有提到OpenCover有一個profiler,這個profiler其實是一個com的library,因此要使用的話需要註冊和給權限。這邊我們使用參數
user
指的是profiler的權限同等於 目前user,因此避免到時候換build server或者換環境會有環境設定問題 - filter
- 還記得上篇提到關於filter用來決定那些Assembly要涵蓋進來那些要排除,這個就是這邊傳入。
- excludebyattribute
- 上篇提到透過attribute方式設定那些要過濾
- excludebyfile
- 上篇提到,透過檔名過濾的地方
- skipautoprops
- 這個指的是 程式碼裡面用的Property (常說的getter和setter,例如:
public string Name{get;set;}
),因為一般沒有邏輯,所以加入這個參數表示那些不要進入涵蓋範圍 - mergebyhash
- 這個指的是,同一個dll可能會被多次載入(不同test framework等),加入這個設定表示,不管載入幾次,只要hash一樣,永遠算1次
- mergeoutput
- 還記得提到說有不同test framework如何整合結果在一起?只要有設定這個參數,加上所有的output path一致,就會把結果整合
- hideskipped
- 上面雖然有提供一些過濾方式,但是最後報表還是會有包含,只是說那些被忽略而已。因此這個參數能夠把被忽略的不在報告顯示。如果要讓報告乾淨一些,就可以讓他們不顯示
- returntargetcode
- 這個指的是,最後的exit code要用target的作為回傳,這樣如果執行test有失敗,才能夠看到
對於幾個參數有了解之後,在helper就增加了一個Run-TestWithOpenCover
:
function Run-TestWithOpenCover { [CmdletBinding()] param([Parameter(Position=0,Mandatory=1)]$testRunnerExe, [Parameter(Position=1,Mandatory=1)]$testRunnerArg, [Parameter(Position=2,Mandatory=1)]$openCoverExe, [Parameter(Position=3,Mandatory=1)]$openCoverResult, [Parameter(Position=4,Mandatory=1)]$filter, [Parameter(Position=5,Mandatory=1)]$excludeAttribute, [Parameter(Position=6,Mandatory=1)]$excludeFiles) Exec { &$openCoverExe "-target:$testRunnerExe" ` "-targetargs:$testRunnerArg" ` "-output:$openCoverResult" ` -register:user ` "-filter:$filter" ` -excludebyattribute:$excludeAttribute ` -excludebyfile:$excludeFiles ` -skipautoprops ` -mergebyhash ` -mergeoutput ` -hideskipped:All ` -returntargetcode} }
"-targetargs:$testRunnerArg" `
,這個原因是在Powershell如果參數有空白,要連參數名一起用雙引號包住。 準備好執行Helper的參數
Helper準備好了之後,在default.ps1
要準備好幾個會傳入的參數,最主要是filter的參數的部分。所以,和其他參數一樣,現在Property裡面定義:
$openCoverResult = "$buildTestCoverageDirectory\openCover.xml" $openCoverFilter = "+[*]* -[xunit.*]* -[*.NunitTest]* -[*.Tests]* -[*.XunitTest]*" $openCoverExcludeAttribute = "System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute" $openCoverExcludeFie = "*\*Designer.cs;*\*.g.cs;*\*.g.i.cs"
這些參數的用意透過剛剛介紹的參數作用應該很清楚,這邊就不做額外介紹。
在結束之前,還有一個地方要調整,就是BundleConfig.cs
。
這邊將會用ExcludeFromCodeCoverageAttribute
加入到他的Class裡面,用來把它排除在Coverage裡面
[ExcludeFromCodeCoverage] public class BundleConfig { ....
調整測試呼叫方式
最後,就是調整3個測試的執行方式。做法都一樣,把本來呼叫exec改成呼叫在第二步建立的helper,有差別的地方都是在testRunnerExe
和testRunnerArg
首先是Xunit:
$xmlResult = "$xunitTestResultDirectory\xUnit.xml" $htmlResult = "$xunitTestResultDirectory\xUnit.html" $targetArg = "$testAssembly -xml $xmlResult -html $htmlResult -nologo -noshadow" Run-TestWithOpenCover -testRunnerExe $xunitExe ` -testRunnerArg $targetArg ` -openCoverExe $openCoverExe ` -openCoverResult $openCoverResult ` -filter $openCoverFilter ` -excludeAttribute $openCoverExcludeAttribute ` -excludeFiles $openCoverExcludeFie `
再來是NUnit:
$targetArg = "$testAssembly --result=$nunitTestResultDirectory\nUnit.xml" Run-TestWithOpenCover -testRunnerExe $nunitExe ` -testRunnerArg $targetArg ` -openCoverExe $openCoverExe ` -openCoverResult $openCoverResult ` -filter $openCoverFilter ` -excludeAttribute $openCoverExcludeAttribute ` -excludeFiles $openCoverExcludeFie `
最後是MSTest:
$targetArg = "$testAssembly /Logger:trx" Run-TestWithOpenCover -testRunnerExe $msTestExe ` -testRunnerArg $targetArg ` -openCoverExe $openCoverExe ` -openCoverResult $openCoverResult ` -filter $openCoverFilter ` -excludeAttribute $openCoverExcludeAttribute ` -excludeFiles $openCoverExcludeFie `
執行結果
以上都做完之後,就可以執行做測試,並且會看到Coverage分數:
結語
在這篇調整了build script,讓opencover進入並且產生出了測試涵蓋率的結果。
但是,這個結果畢竟比較偏summary,看不出到底那些沒cover到,所以在下篇將會進一步去看OpenCover所產生的結果xml,和如何把它轉換成人看得懂的格式
沒有留言 :
張貼留言