[Jenkins]持續整合之路(六)使用MSTest framework建立單元測試(MSTest and VSTest Runner Plugin)

走過前幾天持續整合之路,每天我們可以確保專案擁有能編譯正確的程式版本,完成了最基本的版控和Daily Build要求。不過,我們開發的log程式沒經過測試,執行整合後,如果直接佈署上SIT/QA測試機,一定有被開單和罰站的風險,雖然面對可怕的使用者,我們心無雜念,更練就老僧入定的技巧,但還是要讓自己能免於老闆的關心,來補簡單的單元測試,讓CI Server幫我們持續整合,未來收到千變萬化的使用者需求,我們也能既快速又自動的執行基本測試。

進入第四個水管關卡(Test及Scan)

 

建立測試專案

首先是建立單元測試專案(Unit Test Project)來測試我們前一篇建置的Log程式庫。 

執行下列步驟,以建立單元測試:

1.在方案總管中,以滑鼠右鍵按一下 Log方案,然後依序選取 [加入] 和 [新增專案]。

2.在 [新增專案] 對話方塊中,選取Visual C# 節點,然後選取測試,[單元測試專案(.NET Framework)]。確定好專案名稱後按下確定按鈕。

 

以滑鼠右鍵按一下 UnitTestLog 專案,然後依序選取 [新增] 和 [參考]。 在 [參考管理員] 對話方塊中,確定已選取 [方案] 索引標籤,然後選取 Log專案,如下圖所示。

 

使用NuGet管理員依序安裝Nlog及Nlog.Config

 

打開NLog.config,依序在Targets及Rules區塊新增以下設定

Targets

<target name="logfile" xsi:type="File" fileName="C:\temp\log\${shortdate}\debug.log"
        layout="${date}| ${level} | ${message}"/>
<target name="fatalfile" xsi:type="File" fileName="C:\temp\log\${shortdate}\fatal.log"
        layout="${date}| ${level} | ${message}"/>

 

Rules(Routing條件)

<logger name="*" levels="Trace,Debug,Info,Warn,Error" writeTo="logfile" />
<logger name="*" level="Fatal" writeTo="fatalfile" />

 

UnitTest1.cs單元測試程式碼如下:

using System;
using System.IO;
using Log;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestLog
{
    [TestClass]
    public class UnitTest1
    {
        log Logger = new log();
        string Iso8601Foramt = "yyyy-MM-dd";
        [TestMethod]
        public void LogDebugTest()
        {
            Logger.write("測試偵錯", LevelEnum.Debug);
            Assert.IsTrue(File.Exists($"" +
                            $"C:\\temp\\log\\{DateTime.Now.ToString(Iso8601Foramt)}\\debug.log"));
        }

        [TestMethod]
        public void LogFatalTest()
        {
            Logger.write("測試嚴重錯誤", LevelEnum.Fatal);
            Assert.IsTrue(File.Exists($"" +
                          $"C:\\temp\\log\\{DateTime.Now.ToString(Iso8601Foramt)}\\fatal.log"));

        }
    }
}

 

執行所有測試(Ctrl + R,A)

 

透過發現第二個測試方法失敗,我們會發現其中Fatal嚴重錯誤時,是沒有產生Fatal檔案的,這也是我們上一篇留下的Bug。實體路徑下,也沒有Fatal.log

 

撰寫完測試後,我們現在有一個測試正常、一個測試錯誤的測試專案了,下一步我們把他放到CI Server上整合,這邊我們先將測試專案程式簽入(Check in)TFS

 


安裝MSTest、MSTest Runner、VSTest Runner

CI JOB增加單元測試(Unit Test)的步驟前,我們得先安裝和組態幾個Plugin。

1.進入JenKins網站,管理 Jenkins > 管理外掛程式

 

2.過濾條件輸入MSTest,勾選MSTest及MSTestRunner 兩個plugin安裝,最後按下直接安裝按鈕。

 

3.過濾條件輸入VSTest,勾選VSTestRunner plugin安裝,最後按下直接安裝按鈕。

 

*由於目前MSTest V2單元測試專案以CLI執行時,會發生找不到測試方法執行的情形,如果要用MSTest V2專案,就必須改用VSTest Runner,舊版的MSTest專案仍然可以使用MSTest Runner。

 


組態MSTest Runner /VSTest Runner Plugin

1.管理 Jenkins > Global Tool Configuration

 

2.找到下方的MSTest區塊,按一下新增MSTest按鈕

 

3.依序設定測試框架名稱及測試執行檔位置

  • MSTest 14
  • Path to MSTest(不能只輸入目錄,一定要輸入完整執行檔案的名稱) C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe

 

*只輸入目錄,不輸入MSTest.exe,將會出現以下錯誤訊息

Access is denied

FATAL: MSTest command execution failed

java.io.IOException: Cannot run program "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\" (in directory "T:\Program Files (x86)\Jenkins\workspace\tfs-core"): CreateProcess error=5, 存取被拒。

 

4.新增VSTest,依序設定名稱及執行檔目錄(路徑前後要用雙引號包起來)

Name: VSTest 15

Path: "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe"

5.最後按下儲存按鈕。

*由於產生的測試檔的命名,為了避免測試圖表的累積數目錯誤,使用VSTest Runner時,也許需要另外加上Windows命令進行刪除。

cd TestResults
del *.trx

 


組態CI JOB加入MSTest Runner或是VSTest Runner(擇一)

1.在LOG專案頁面,按一下組態選項。

 

2.在建置階段中,新增一個建置步驟-Run Unit Test sWith MSTest

 

3.選擇上一步驟組態的MSTest名稱、要測試的專案以及產生的測試結果檔案名稱

 

4.在建置後階段,新增一個建置後動作Publish MSTest test result report,最後按下儲存按鈕。

 

5.預設要抓測試結果檔的路徑就是**/*.trx

 

6.馬上執行建置!就可以收到測試結果。

 

如果要選擇VSTest,也可以在建置階段新增Run unit tests with VSTest.console步驟

 

又多走了一點路了~

*有時間繼續補Web UI及SQL自動化測試。

 


參考

使用 IntelliTest 為程式碼產生單元測試

在 Visual Studio 中開始使用 Live Unit Testing

MSTestRunner Plugin

MSTest Plugin

VsTestRunner Plugin