單元測試Unit Test (一) ─認識單元測試

有句話說開發人員皆應『先寫測試,再寫產品程式碼』。
不要直接寫功能,應該從單元測試開始,因為它能幫助你開發有品質好維護的程式碼。
這篇是單元測試的第一篇,會說明基本概念,後面幾篇會用實例讓大家了解單元測試的撰寫過程。

本篇會帶出:
1. 單元測試的重要性
2. 介紹Visual Studio的MS Test
3. 測試案例的其中一種格式Gherkin ( Cucumber)

此篇用Visual Studio 2022、C#語言。

單元測試的重要性

單元測試是什麼?
針對程式的最小可測試單元(例如函式、方法或類別)進行測試,驗證是否符合預期的結果。

為甚麼要寫單元測試?
✔寫單元測試,我們需要:
1.列出測試情境(測試案例)
2.讓每一個測試案例符合預期結果

✔過程中你會發現,單元測試可以:
1.輕鬆地重複執行大量測試案例
2.確保每增加一個案例都能得到符合預期的結果
3.讓改 A 壞 B 馬上現形
4.協助程式碼重構,避免因重構而引入新的錯誤

例如:D 測試寫出來,執行測試會一併測 A、B、C、D,就能知道 D 的修改是否會影響 A、B、C。
也就是回歸測試(Regression Testing),當每次完成新功能後,除了針對新的功能測試外,也同時檢查以前的功能有沒有受到影響。

✔當完成每一個測試案例的預期,你的程式碼將能:
1.覆蓋接近100%的使用情境
2.後續的更改和維護也能依靠單元測試,快速發現並解決問題
3.幫助團隊成員更好地理解代碼、進行協作和修復問題

從上述可見,單元測試是保證程式碼品質的重要手段。

單元測試工具─Visual Studio的MSTest

打開Visual Studio→建立新的專案→MSTest測試專案(.NET Core)

命名專案名稱→架構選最新的(我的是.NET 7.0)

開啟後剛剛的命名就會是方案與專案的名稱。
如下圖,一建立MSTest系統就會送UnitTest.cs和Using.cs。

UnitTest.cs

如下圖,大家可以先在任一個紅框處按右鍵"重新命名",重新命名一個紅框,另一個也會跟著改喔。
舉例,我要寫出LINQ的Where功能,所以我可以把UnitTest命名為"MyWhere"。

黃框處,
UnitTest是class,[TestMethod]是關鍵字,一個[TestMethod]裡面放一個測試情境

下圖我已經先將專案名稱改為MyLinqTests,
因為之後我會在MyLinqPractice方案下加放一個類別庫,
分成"Unit Test測試"和"Production Code產品"兩個區塊。

Using.cs

裡面是C#10才開始有的global using,提供MSTest 框架測試相關的類型和屬性,
它可以讓這個專案內的每個類別檔案都using這一行。
而不需要在每個測試類別或方法中都額外加上 using 宣告。

用MSTest寫一個單元測試的完整經過我會寫在下一篇。

這邊繼續介紹MSTest的系統功能,

  • 跑測試
    寫完TestMethod後,可以到工具列的測試執行所有測試
    快捷鍵:按Ctrl+R, A (等於按住Ctrl去按R、全部放開去按A)
    測試結果顯示在測試總管視窗。
  • 測試總管視窗Test Explorer
    工具列的檢視測試總管
    單元測試的重點,就是要讓測試總管視窗內的測試案例全部綠燈。
    若有紅燈,要看旁邊顯示的錯誤訊息提示,改到全部測試案例綠燈通過為止。
測試總管路徑

單元測試撰寫格式

Gherkin (Cucumber)小黃瓜

Gherkin 是一種編寫測試案例的語言。
使用人類語言的關鍵詞(例如 Given、When、Then)和場景(Scenarios)來描述系統行為和測試案例。

Given-When-Then

是一種用於撰寫測試案例的結構化方式,用於明確描述測試的前置條件、觸發條件和預期結果。
"Given-When-Then" 也被稱為 "3A Pattern" 或 "AAA Pattern"。
有助於測試案例的清晰和可讀性。

3A Pattern:

  1. Given ( Arrange )前情題要、前置條件:
    描述在測試執行之前需要設定的環境或狀態。
    →例如,把測試對象new起來。
  2. When ( Act )做甚麼事、觸發條件:
    描述觸發測試行為的操作或事件。
    →例如,使用被測試對象。
  3. Then ( Assert )期望結果:
    描述期望從觸發條件得到的結果。
    程式碼關鍵字:Assert.AreEqual(放預期結果, 實際結果)
    ⭐或安裝NuGet套件中的FluentAssertions,就可以使用X.Should().BeEquivalentTo(X的預期結果)。比Assert.AreEqual(放預期結果, 實際結果)更口語化。
安裝FluentAssertions

單元測試其他注意事項

  • 先讓測試通過,再來重構Refactor
  • 用Github記錄每一步
    ✔一個單字作為開頭記錄這次的意圖:
    Refactor(重構)
    Style(e.g.,重新命名、格式排版)
    Feature(寫功能)
    Fix(修bug)

我學習時喜歡做數位筆記,但寫程式時,筆記會變得困難。
因為過程會不斷優化程式碼,改了之後就會忘記是怎麼從上一步到這一步的。

這時Github就是我學習過程的救星😍

我每寫一點程式碼就Git Commit,
Github會幫我標記出改變的地方
我也能在[Git變更]的[傳入訊息]筆記下這次改變的重點

參考資料

謝謝觀看,此為新手的學習筆記整理,若有錯誤,煩請指正🙏