單元測試:開篇明義

Ocean&&Star發表於2020-12-31

一個單元測試是一段自動化的程式碼,這段程式碼呼叫被測試的工作單元,之後對這個單元的單個最終結果的某個假設進行檢驗。單元測試幾乎都是用單元測試框架編寫的。單元測試容易編寫,能快速執行。單元測試可靠、可讀,並且可維護。一個工作單元可以小到只包含一個方法,也可以大到包括實現某個功能的多個類和函式。

作為開發人員,或多或少,都在某種程度上進行過單元測試,比如,寫完程式碼在提交之前自己先測試下。也許你是用一個控制檯來呼叫一個函式進行測試,也是是特意建立介面程式來檢查某個元件的功能,或是乾脆在實際應用程式中進行各種手工操作。最終的結果都是讓你能在一定程度上確信程式碼工作正常,可以移交給他人。

這樣的單元測試方法,有以下幾個缺點:

  • 單元測試程式碼難於維護,甚至當時測完就被刪了,即使有保留,也會經常發現以前(或一個月前、或一年前)寫的測試程式碼無法執行;
  • 一個人寫的單元測試,無法共享給團隊裡其他人執行。
  • 無法一鍵執行寫過的所有單元測試。
  • 無法在幾分鐘內跑完所有單元測試。
  • 無法在幾分鐘內快速新建一個基本單元測試。

要解決這些問題,可以:

  • 使用單元測試框架編寫單元測試;
  • 視單元測試程式碼跟產品程式碼同樣重要,也要納入版本管理,跟隨產品程式碼一起維護。
  • 好的單元測試規範,學習他人總結的最佳實踐,能讓事半功倍。

一個優秀單元測試應具有如下特質:

  • 它應該是自動化的,可重複執行;
  • 它應該用一個單元測試框架編寫;
  • 它應該容易實現;
  • 它應該執行速度很快;
  • 團隊任何人都可以一鍵執行它;
  • 它應該是完全隔離的(獨立於其他測試的執行);
  • 如果失敗了,應該很容易發現什麼是期待的結果,進而定位問題所在。

單元測試框架

單元測試框架是一個專門用於編寫、執行和檢視單元測試及其結果的框架,單元測試框架向開發人員提供進行單元測試的程式碼庫和模組。

基本上每一種常用的程式語言都有一個單元測試框架,通常單元測試框架都以它們支援的語言的開頭字母加上Unit作為名字,它們統稱為xUnit框架。C語言的單元測試框架是CUnit,C++的是CppUnit,Java的是JUnit,.NET的是NUnit,Python的是PyUnit。不是所有的單元測試框架都這麼命名,但大部分如此。
在這裡插入圖片描述
某些程式語言直接支援單元測試,他們的語法允許直接進行單元測試的宣告而不需要匯入第三方庫,比如C#、D語言。

更多的單元測試框架可參閱(需翻牆): List of unit testing frameworks

單元測試誰完成

除非有明確的分工,否則單元測試往往是由程式設計師自己來完成,最終受益的也是程式設計師自己。可以這麼說,程式設計師有責任編寫功能程式碼,同時也就有責任為自己的程式碼編寫單元測試。執行單元測試,就是為了證明這段程式碼的行為和我們期望的一致。

什麼時候開始單元測試

千萬不要等到專案後期再進行單元測試,那樣就失去檢查程式碼、預防缺陷的意義了。

很多人覺得為軟體編寫單元測試的最佳時機是軟體編碼完成以後,但是越來越多的人選擇在產品程式碼編寫之前寫單元測試,這種方法稱之為測試驅動開發(Test-Driven Development,TDD)。這是一種不同於傳統軟體開發流程的新型的開發方法,它要求在編寫某個功能的程式碼之前先編寫測試程式碼,然後編寫功能程式碼使測試通過,通過測試來推動整個開發的進行。

說到TDD,就不得不提到極限程式設計(ExtremeProgramming,簡稱XP),TDD是極限程式設計中的一個重要組成部分。Kent Beck先生最早在其極限程式設計方法論中,向大家推薦“測試驅動”這一最佳實踐,還專門撰寫了《測試驅動開發》一書,詳細說明如何實現。經過幾年的迅猛發展,測試驅動開發已經成長為一門獨立的軟體開發技術,其名氣甚至蓋過了極限程式設計。

有人將TDD和蓋房子進行類比,讓我印象深刻:

蓋房子的時候,工人師傅砌牆,會先用樁子拉上線,以使磚能夠壘的筆直,因為壘磚的時候都是以這根線為基準的。TDD就像這樣,先寫測試程式碼,就像工人師傅先用樁子拉上線,然後編碼的時候以此為基準,編寫出符合這個測試的功能程式碼,通過測試來推動整個開發的進行。

對單元測試的質疑

目前,在國內眾多中小型IT公司眾,鮮有將單元測試作為一種文化融入研發組織,做的好更是寥寥。應該來說是從意識形態上對單元測試的重視度不夠,也許未來會慢慢改變。

如果要在組織中引入單元測試,往往會遇到很多質疑。其中質疑最嚴重的聲音是:單元測試會不會給專案增加時間!

公司老闆、團隊領導者、專案經理和客戶通常是最關注時間的人,這幫人也是專案的關鍵人、決策人,不說服這些人,將很難再專案中引入單元測試。

沒錯,單元測試確實會增加開發功能所需的時間,但是單元測試提升了程式碼質量。專案中整體程式碼質量的提高,可以縮短後續專案維護時間(主要是通過可維護性和容易修護缺陷實現的),從而縮短產品的交付週期。

更多的質疑和回答,可以參考《單元測試的藝術(第2版)》中的9.5章節,裡面描述的很詳盡。

相關文章