iT邦幫忙

2021 iThome 鐵人賽

DAY 2
2
Software Development

單元測試從入門到進階之路 (以 C# NUnit 3 X NSubstitute 為例)系列 第 2

Day 2-什麼是單元測試及何謂優秀的單元測試? (基礎-1)

  • 分享至 

  • xImage
  •  

最初的單元測試傳統定義

在 Roy Osherove 撰寫的單元測試的藝術中,1970 年代就已經有單元測試的概念了。並且隨著時代的推移,對於單元測試也循序漸進的完善其定義。而本書給出最初的定義如下:

一個單元測試就是一段程式碼(通常是一個方法),這段程式呼叫了另一段程式碼。然而驗證某些假設的正確性。如果這些假設是錯誤的,單元測試就會失敗。一個單元可以是一個方法或函數。


逐步更具體定義的單元測試

第一時間觀看其定義,會覺得滿合理的,畢竟單元測試的用意就是為了驗證其方法是否符合預期結果。然而,在仔細觀察其定義會發現,其定義提到的一段程式碼(通常是一個方法),這段程式呼叫了另一段程式碼,這段程式碼指的是一個工作單元,可能包山包海,可能驗證了一個方法;但也有可能驗證多個類別與函數。

換言之,可能會隨著不同的開發者,定義出不一致的單元測試風格( A 開發者寫出一隻工作單元驗證其方法的其中一個情境, B 開發者則寫出一隻工作單元驗證功能所需要考量的情況)。


https://ithelp.ithome.com.tw/upload/images/20210912/20127378hItHRBZszt.png

圖 1、A 測試員的測試單元邏輯

https://ithelp.ithome.com.tw/upload/images/20210912/20127378pVMP8oFfbH.png

圖 2、B 測試員的測試單元邏輯


也因此,本書逐步修正了最初的單元測試定義:

一個單元測試是一段程式呼叫一個工作單元,並驗證工作單元的一個具體最終結果。如果對這個最終結果的假設是錯誤的,那單元測試就失敗了。一個單元測試的範圍,可以小到一個方法,大到多個類別。


走向成為優秀的單元測試

根據上述的定義,單元測試有了更完善的解釋;然而,隨著軟體系統開發的開發週期縮短且複雜度提升,往往許多時候以往開發的單元測試成為了可怕的技術成本之一。比方說,開發一隻新功能所花費的時間為一小時,但要驗證這新功能的單元測試也同樣要花費一小時,甚至更長,身為開發商大多會選擇忽略以縮短短期內的開發時程,進而導致犧牲測試帶來的長期維護效益。Roy Osherove 在本書提出優秀的單元測試應具備以下這些特點:

  • 自動化,且可被重複執行;
  • 容易被實作;
  • 撰寫後的第二天應還具有其意義;
  • 任何人按執行皆可做測試;
  • 執行速度快;
  • 能完全掌控且被測試的單元;
  • 完全被隔離的(執行時獨立於其他測試);
  • 執行失敗,應該能清楚的呈現預期結果為何?詳述其發生的問題原因。

從以上觀點,大致上可分成幾個方向:

  1. 是否容易且可自動化被執行。舉反例來說,若單元測試會隨著 NUnit 套件版本不同 (如 ExpectedExcetption 特性) 而無法執行,則這不是好的單元測試。
  2. 執行速度是否可在幾分鐘跑完所有測試。大多開發期間,為了確認是否修改功能而影響以往的功能清單,單元測試變成了很好的參考機制,但若測試時間過長則會漸漸影響開發人員執行測試的頻率,最不理想情況則可能忽略測試。
  3. 可否快速開發基本的單元測試。如前一段提到,若開發單元測試的難度比開發功能困難,則會連帶影響開發測試的品質;其中,設計模式(Design Pattern)會直接影響單元測試難易度,要寫好的單元測試,通常會依據介面(Interface)的設計決定測試單元如何在適當的時機點介入功能並檢測需要驗證的功能(若有興趣會在單元測試-核心技術系列介紹)。

因此,總結以上敘述,Roy Osherove 在單元測試的藝術最終給出的單元測試定義如下:

一個單元測試是一段自動化的程式碼,這段程式會呼叫被測試的工作單元,之後對這個單元的單一最終結果的某些假設或期望進行驗證。單元測試幾乎都是使用單元測試框架進行撰寫的。撰寫單元測試很容易,執行起來快速。單元測試可靠、易讀、並且很容易維護。只要產品程式碼不發生變化,單元測試的執行結果是穩定一致的。

接下來,明天會提起何時該用單元測試(換種說法,就是要判別何時不該用單元測試),會提起常跟單元測試一起討論的整合測試、以及網頁開發會提到的端點測試等做比較。


上一篇
Day 1-單元測試 (前言)
下一篇
Day 3-何時用單元測試?在這之前,要先釐清除了單元測試以外的測試 (基礎-2)
系列文
單元測試從入門到進階之路 (以 C# NUnit 3 X NSubstitute 為例)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言