公司要求提公升單元測試的質量,其中我作為方案和推動的主導,對開發過程中的單元測試,有了一些思考和總結
單元測試編寫的目的,是面向計算機特性的,基於函式的in-out,所以單元測試的好幫手就是斷言,通過不斷的構造輸出並對結果進行斷言,我們就可以針對乙個物件以及它的函式,構建出充足的用例去包裹它,以期望它的任意行為滿足我們的需要。
最終的目的也是為了通過用例對單元測試的包裹,達到對任意物件的任意函式進行修改後,既滿足新的功能,又對舊有功能沒有影響。
基於單元測試編寫的目的,在編寫單元測試時,我們應當認為我們編寫的單元測試所面向的過程是黑盒,我們應只對輸入以及我們期望的輸出負責,即只考慮起始輸入以及最終態。
具體來說:
針對dao的單元測試,我們只應該關心測試後資料庫各個欄位的值。
針對service的測試,我們只應該關心service方法執行最終涉及到的資料庫字段,快取,訊息佇列中的值,以及service方法的返回。
針對controller的測試,我們僅應該關心controller針對httprequst的輸入以及httpresponse的輸出。而不該關心其中具體呼叫到的那些service如何執行。
其中第3點或許令人疑惑,但是我們在編寫單元測試時,我認為應該僅考慮執行的函式邏輯本身。對於其外部的依賴或者並不關心結果的方法,盡量mock掉。雖然目前的場景下service層與dao層基本耦合在一起無法拆分開來進行單元測試,但是controller層絕不應該嚴重依賴service來進行單元測試,否則單元測試最終會淪為介面測試。
同時,如果我們在測試某個模組時,不對其外部依賴做mock,那麼就會導致我們的測試依然非常臃腫。並且最可怕的是,我們對結果的斷言無法實現。比如當我們對controller進行單元測試時,即便我們不mock它所依賴的rpc(而是將他們啟動著),但是我們如何對他所依賴的那些rpc的執行正確與否進行斷言呢?難道我們要在controller層的單元測試執行完成後,在controller層對資料庫以及其他中介軟體的變化做查詢以及斷言嗎?這顯然是不現實的。
單元測試面向的應該是乙個從不呼叫其他函式(不包括第三方jar包)的函式,從其開始自底向上乙個個編寫,直到http介面層。
對於同乙個單元測試來說,它的增加與修改應該與其對應測試功能的變化相同:
當對應的功能增加了或擴充套件了,應在單元測試中對新增功能增加新的測試,對老的單元測試則應該不做修改,並保證新增功能也滿足老的測試。
當對應的功能修改了,並且不可能滿足原有的測試,此時才應當去修改原有的測試,並應當加注釋以說明。當需要修改單元測試時一定要謹慎,因為這意味著以前的經驗已經不奏效了。
依靠這些原則去編寫單元測試,我們會發現,想要寫出乙個好的便於測試的類也是比較難的。想要寫出便於測試的類以及方法,會反向要求了我們減少**間的耦合,提高**的可讀性。
單元測試的編寫不應該是大家埋頭乙個月一起閉關編寫(雖然大部分從未編寫過單元測試的系統確實需要這樣),而是乙個不斷漸進,防止犯過的錯再犯的方式。
當開發乙個新功能時,我們應當對新功能針對需求編寫單元測試,這是理所應當的。
當對乙個功能進行修改時,我們應該對該功能的單元測試進行修改,並完成該功能修改後的單元測試。
當發現某功能出現了某些意料之外的輸出(一般來說就是bug),我們在修改時,應當針對該種特殊情況編寫對應的單元測試。
經過以上3種情況的單元測試編寫,我們的單元測試會覆蓋的場景就會越來越多,我們的**也會越來越健壯,久而久之,我們對於**的修改可以純粹依賴單元測試,而減少更多邏輯上覆雜的思考。
iOS 單元測試4 單元測試編碼規範
編寫單元測試與編寫工程 略有不同。我們需要準備資料,mock物件,呼叫工程api,驗證結果。而且一般測試 都會比工程 要大。就像real world testing with xctest一文中提到 目前為止,我們的編碼庫已經縱橫 190 個檔案和 18,000 行 達到了 544 kb。我們測試部...
單元測試 單元測試文章收藏
前言 前段時間公司計畫做自動化測試,自己也打算圍繞幾個點做相關調研,現在想想呢?其實對自動化測試的概念都還不是十分清晰,當時主要還是圍繞 單元測試 向qa小夥伴學習了一段時間,現由於公司重組,學習中斷,這裡簡單記錄一些單元測試好文,留待後續參考.什麼叫自動化測試?自動化測試覆蓋率?覆蓋率如何做到的?...
單元測試之Django單元測試
每個應用,自帶tests.py 整合在django的專案檔案裡,更多是開發人員寫django自動的測試執行 3.1 前後置方法執行特點 django.test.testcase類主要由前 後置處理方法和test開頭的方法組成 特點 繼承於django.test.testcase 測試用例都是test...