Alan Tsai 的學習筆記


學而不思則罔,思而不學則殆,不思不學則“網貸” 為現任微軟最有價值專家 (MVP)、微軟認證講師 (MCT) 、Blogger、Youtuber:記錄軟體開發的點點滴滴 著重於微軟技術、C#、ASP .NET、Azure、DevOps、Docker、AI、Chatbot、Data Science

[iThome第8屆鐵人賽 10]執行測試 1 - XUnit .Net

經過一段時間的介紹,相信對於使用psake來建制專案已經沒什麼問題了 - 我們就要開始進入建制的下個階段,也就是測試。

專案建制起來只是基本條件,但是單元測試是否有通過才是保證程式碼品質的一種方式,因此,不跑單元測試更本就不完整。

在接下來幾篇,將會介紹幾個常見的unit test的framework,先從xunit開始。

準備Xunit 測試專案

首先,我們先建立一個新的Library 專案 ,然後透過nuget安裝:

  1. Install-Package xunit -Version 2.1.0 - xunit的test framework
  2. Install-Package Microsoft.AspNet.Mvc -Version 5.2.3 - 等一下測試controller,所以需要有mvc的reference


再來,我們就建立一個簡單的test測試HomeController的Contact方法:

public class HomeControllerTest
{
 [Fact]
 public void Contact()
 {
  // Arrange
  HomeController controller = new HomeController();

  // Act
  ViewResult result = controller.Contact() as ViewResult;

  // Assert
  Assert.NotNull(result);
 }
}

準備好了之後,我們就可以準備build script的部分。

準備測試的執行環境

在準備build script之前,我們需要知道,測試是如何執行的。

一般來說,如果我們是開發,可能就直接用VS的Test Runner來執行,不過每一個test framework一定有提供console執行的版本,所以我們第一件事情就是要把這個console程式下載下來。

再來,我們就可以在psake建立一個新的task,用作於執行xunit的測試。

最後,如果執行成功的話,我們就可以看到結果

1. 在build專案安裝xunit的console runner

安裝xunit的console runner:Install-Package xunit.runner.console -Version 2.1.0

2. 準備build script - task 定義

首先,我們在default.ps1定義一個新的task,XunitTest

由於這個task可以被單獨執行,因此相依性也要設定好,看起來就會是:

task XunitTest -depens Compile -description "執行Xunit測試"{
 Write-Host "準備執行Xunit測試"

 Write-Host "完成執行Xunit測試"
}

3. 準備build script - 參數定義

在確認執行之前,我們要先定義好幾個參數:

取得執行Xunit的Console Runner位置 - $xunitExe
由於我們buildProject有加入xunit的 console runner,因此在package可以找到

測試結果要儲存的位置 - $xunitTestResultDirectory
我們 會把不同測試Framework分開放,所以會建立一個專門放Xunit

要執行測試的路徑確認 - $xunitTestPath
這個邏輯是透過看看建制出來的專案有沒有 xunit 開頭的dll - 有就算是要被執行。這裡面取得的結果是DirectoryInfo,原因我們稍後提到
$xunitExe = ((Get-ChildItem("$solutionDirectory\packages\xunit.runner.console*")).FullName |
     Sort-Object $_ | select -Last 1) + "\tools\xunit.console.exe"

$xunitTestResultDirectory = "$buildTestResultDirectory\Xunit"

$xunitTestPath =  Get-ChildItem $buildTempDirectory -Recurse -Filter xunit*.dll | 
      Select -ExpandProperty DirectoryName -Unique | % { [io.directoryinfo]$_ }

4. 準備執行 xunit console runner

要執行xunit console runner,我們首先要找出所有要執行的dll清單,在上面我們已經找到了所有專案路徑的清單,所以可以用這個取得所有的dll清單。

建制出來的dll名稱會和專案名稱一樣,因此我們可以用for迴圈方式把每一個找到的xunit專案路徑變成對應的dll路徑,然後最後在把他這個清單組成一個空白分開的字串

# 組執行的dll

$testDlls = $xunitTestPath | % {$_.FullName + "\" + $_.Name + ".dll" }

$testDllsJoin = [string]::Join(" ", $testDlls)

再來就是要確認執行xunit console runne所會使用的參數:

$dll 路徑
這個就是上面組出來的參數

-xml $路徑
執行結果要用 xml 格式 儲存在某個路徑

-html $路徑
執行結果用html格式儲存在某個路徑

-nologo
讓執行的時候,不出現xunit相關的logo資訊 - 減少輸出的內容

-noshadow
本來執行測試的時候,xunit會複製一份出來避免執行測試的時候資源被使用。不過我們用script執行之後,能夠確認不會有其他用到,所以可以不用做複製的動作,加快執行速度。
exec{ &$xunitExe $testDllsJoin -xml $xunitTestResultDirectory\xUnit.xml `
                -html $xunitTestResultDirectory\xUnit.html `
                -nologo -noshadow}
如果對於還有那些參數可以傳入有興趣,可以直接執行Xunit的console,不要傳入任何參數,就會看到所有可以輸入的參數清單。

最後,加入一些日誌方面的資訊,task變成:

task XunitTest -depends Compile -description "執行Xunit測試" `
{
 # 取得Xunit project的路徑
 $xunitTestPath =  Get-ChildItem $buildTempDirectory -Recurse -Filter xunit*.dll | 
      Select -ExpandProperty DirectoryName -Unique | % { [io.directoryinfo]$_ }

 if(Test-Path $xunitTestPath){

  Write-Host "建立Xunit測試結果的資料夾 $xunitTestResultDirectory"
  New-Item $xunitTestResultDirectory -ItemType Directory | Out-Null

  Write-Host "總共有 $($xunitTestPath.Count) 個專案"

  Write-Host ($xunitTestPath | Select $_.Name)

  Write-Host "準備執行Xunit測試"

  # 組執行的dll

  $testDlls = $xunitTestPath | % {$_.FullName + "\" + $_.Name + ".dll" }

  $testDllsJoin = [string]::Join(" ", $testDlls)

  Write-Host "執行的 Dll: $testDllsJoin"

  exec{ &$xunitExe $testDllsJoin -xml $xunitTestResultDirectory\xUnit.xml `
    -html $xunitTestResultDirectory\xUnit.html `
    -nologo -noshadow}
  
  Write-Host "完成執行Xunit測試"
 }

}

最後,把XUnitTest加入Test的相依task

task Test -depends Compile, Clean, XunitTest -description "執行Test" { 
 Write-Host $testMsg
}

執行Xunit的測試

到目前為止,準備都完成了,這個時候執行build.ps1,我們就會看到除了建制之外,單元測試也有被執行。

image
執行的output結果

然後我們在testResult\Xunit下面也有對應檔案產生出來

image
執行完結果內容

結語

在這篇,介紹了如何建立出XUnit的測試結果,並且我們可以看到最後執行完的產出。在未來,其實可以把產出的xml做二次加工而產生出更漂亮的報告,目前來說我們先執行到這一步。

在下一篇,我們要來看看另外一個常見的test framework,NUnit的task建立方式。


如果文章對您有幫助,就請我喝杯飲料吧
街口支付QR Code
街口支付QR Code
台灣 Pay QR Code
台灣 Pay QR Code
Line Pay 一卡通 QR Code
Line Pay 一卡通 QR Code
街口支付QR Code
支付寶QR Code
街口支付QR Code
微信支付QR Code
comments powered by Disqus