單元測試-【轉】論單元測試的重要性

yoylee_web發表於2019-01-21

本文章轉自:http://www.51testing.com/html/00/n-3724000.html ,只供學習使用。

系列導航

點選跳轉到系列博文目錄導航

1 什麼是單元測試

單元測試是對軟體組成單元進行測試,其目的是檢驗軟體基本組成單位的正確性,測試的物件是軟體設計的最小單位:函式。(維基百科)

2 單元測試不是整合測試

這裡需要強調一個觀念,那就是單元測試只是測試一個方法單元,它不是測試一整個流程。舉個例子來說,一個Login頁面,上面有兩個輸入框和一個button。兩個輸入框分別用於輸入使用者名稱和密碼。點選button以後,有一個UserManager會去執行performlogin操作,然後將結果返回,更新頁面。

那麼我們給這個東西做單元測試的時候,不是測這一整個login流程。這種整個流程的測試:給兩個輸入框設定正確的使用者名稱和密碼,點選login button, 最後頁面得到更新。叫做整合測試,而不是單元測試。當然,整合測試也是有他的必要性的,然而這不是我們每個程式設計師應該花多少精力所在的地方。在這方面,有一個理論叫做Test Pyramid,如下圖所示:
在這裡插入圖片描述
Test Pyramid理論基本大意是,單元測試是基礎,是我們應該花絕大多數時間去寫的部分,而整合測試等應該是金字塔上面能看見的那一小部分。

為什麼是這樣呢?因為整合測試設定起來很麻煩,執行起來很慢,發現的bug少,在保證程式碼質量、改善程式碼設計方面更起不到任何作用,因此它的重要程度並不是那麼高,也無法將它納入我們正常的工作流程中。

而單元測試則剛好相反,它執行速度超快,能發現的bug更多,在開發時能引導更好的程式碼設計,在重構時能保證重構的正確性,因此它能保證我們的程式碼在一個比較高的質量水平上。同時因為執行速度快,我們很容易把它納入到我們正常的開發流程中。

至於為什麼整合測試發現的bug少,而單元測試發現的bug多,這裡也稍作解釋,因為整合測試不能測試到其中每個環節的每個方面,某一個整合測試執行正確了,不代表另一個整合測試也能執行正確。而單元測試會比較完整的測試每個單元的各種不同的狀況、臨界條件等等。一般來說,如果每一個環節是對的,那麼在很大的概率上,整個流程就是對的。雖然不能保證整個流程100%一定是對的。所以,整合測試需要有,但應該是少量,單元測試是我們應該花重點去做的事情。

很多時候大家會把單元測試跟整合測試搞混, 其實只要記住單元測試面向的物件是最小程式單元: 函式,它是面向軟體應用開發者而言的, 而整合測試一般是面向測試人員進行黑盒測試的,不是開發者重點關注的地方。

3 為什麼很多人不寫單元測試

網上有些文章關於這個問題做了一些討論, 我把原因貼出來:

  • 不知道怎麼編寫單元測試
  • 單元測試價值不高,完全是浪費時間
  • 業務邏輯比較簡單,不值得編寫單元測試

說實話,在著手去看單元測試之前,上面的原因我基本上也都存在,相信很多人跟我有同樣的想法.
但是細看這些原因歸根結底就是不瞭解單元測試,下面根據網上的文章和我自己理解去反駁這些觀點.
1:不知道怎麼編寫單元測試
  這肯定是沒有接觸過單元測試,根本不瞭解單元測試會帶給你什麼,你能從中得到什麼益處. 設想一下,當你開發完一個功能模組的時候,你如何確定你的模組沒有 bug 呢?如果涉及到具體的業務,你會執行 debug 模式,然後一點一點的深入到程式碼中去檢視嗎?如果你一直都是這樣,那麼你早就已經 OUT 了。趕快去了解一下單元測試的工具吧,你會收穫很大的。這在Android開發中更是非常"蛋疼"的,每次專案編譯執行少則2-3分鐘,多則可能十幾分鍾,如果每次都是真機除錯會耽誤大量的時間在上面.
2:單元測試價值不高,完全是浪費時間
  這種說法其實是錯誤的。為什麼這麼說呢?在日常的開發中,程式碼的完工其實並不等於開發的完工。如果沒有單元測試,那麼如何保證程式碼能夠正常執行呢?測試人員做的只是業務上的整合測試,也就是黑盒測試,對單個的方法是沒有辦法測試的,而且,測試出的 bug 的範圍也會很廣,根本不能確定 bug 的範圍,還得去花時間來確定 bug 出在什麼地方。難道這就不浪費時間了嗎?甚至,這樣的方式,時間浪費的會更多。
3:業務邏輯比較簡單,不值得編寫單元測試
  所謂的業務邏輯比較簡單,其實是相對的。當你對某一塊業務邏輯很熟悉的時候,你自然會認為它很簡單。然而,單元測試的必要性並不是僅僅在於測試程式碼的功能是否正確,還在於,當其他同事在瞭解你的業務的時候,能夠很快的通過單元測試來熟悉程式碼的功能,甚至不用去讀程式碼,就能夠知道它做了哪些事情。因此,寫單元測試不僅是解放了自己,更方便了別人。

4 TDD 測試驅動開發

在這裡插入圖片描述
  Test-Driven Development, 測試驅動開發, 是敏捷開發的一項核心實踐和技術,也是一種設計方法論。TDD原理是開發功能程式碼之前,先編寫測試用例程式碼,然後針對測試用例編寫功能程式碼,使其能夠通過。由於TDD對開發人員要求非常高,跟傳統開發思維不一樣,因此實施起來相當困難。
  測試驅動開發有好處也有壞處。因為每個測試用例都是根據需求來的,或者說把一個大需求分解成若干小需求編寫測試用例,所以測試用例寫出來後,開發者寫的執行程式碼,必須滿足測試用例。如果測試不通過,則修改執行程式碼,直到測試用例通過。
  好處,通過測試的執行程式碼,肯定滿足需求,而且有助於介面程式設計,降低程式碼耦合,也極大降低bug出現機率(如果是極限程式設計,幾乎是不可能有bug)。
  壞處,1.投入開發資源(時間和精力);2.由於測試用例在未進行程式碼設計前寫;很有可能限制開發者對程式碼整體設計
  Note: 個人認為我們也沒有必要完全按照TDD模式進行開發, 但是這種思想是需要我們借鑑的,在有很多複雜邏輯處理的地方應用這種開發模式還是非常有必要的.

5 單元測試工具

既然單元測試如此重要,那我們使用哪種單元測試工具呢?
對於pure Java程式碼來說, 採用JUnit做基礎的單元測試框架, Mockito用來mock物件等,AssertJ豐富斷言支援等。

相關文章