我對單元測試和測試驅動開發的見解
大部分公司即使要求編寫單元測試也是先寫業務代碼,再編寫測試代碼去測試。由于開發人員水平不齊,業務代碼不能保證質量,可能導致難以測試。我收集了經常遇到一些阻礙測試的
什么是單元測試
(廢話想說一些:如果我們聽到一個陌生的概念,不去追問它是什么,它有什么用?直接進行任務去完成這個概念描述的事,那么,我們可能很難理解我們為什么要這么做,也可能做不好。)
-
概念解釋
單元測試是針對一個工作單元設計的測試。這里的工作單元一般是指對一個方法的一個要求。
-
單元測試優點
我們可以集中精力針對于一個特定的工作單元進行測試,排除其它邏輯干擾,使編寫測試更加容易。如果測試失敗,也能很快鎖定哪里出現缺陷。
-
單元測試的特征
-
與其它代碼隔離:單元測試代碼不影響其它代碼,需建立獨立項目文件;
-
與其他開發人員隔離:每個開發人員編寫的單元測試不互相干擾;
-
有針對性:單元測試是針對一個特定的工作單元編寫的;
-
可重復:單元測試可以重復運行,并且保證每次結果都正確;
-
可預測:能夠確定方法輸入X,將返回Y。
阻礙開發人員編寫單元測試可能的原因
大部分公司即使要求編寫單元測試也是先寫業務代碼,再編寫測試代碼去測試。由于開發人員水平不齊,業務代碼不能保證質量,可能導致難以測試。我收集了經常遇到一些阻礙測試的問題。
-
依賴其它類
-
業務邏輯沒有返回值,直接影響數據庫或者其它
-
業務邏輯復雜,需要很多驗證
-
其它外部資源:數據庫、文件、配置、緩存等
當然還有很多情況阻止著我們編寫單元測試。解決的辦法遵循三個點:
一是編寫業務代碼嚴格執行單一職責原則;
二是面向接口編程,使用依賴注入;
三是利用工具模擬外部資源。
== 另外一點 ==
我們總將一些靜態資源封裝成靜態類,當這些類也參與業務邏輯,那么就會影響編寫單元測試。比如:架構組將操作Redis的庫編寫成靜態類,如果執行測試將會影響Redis數據。令人頭疼的是,基本上所有的免費框架都不支持Mock靜態類。目前,我采取的方法是使用JustMock的付費功能。經驗有限,希望發到博客有大神指出解決方案。
測試驅動開發——TDD
-
TDD 的理念
當我們拿到需求,按照瀑布流開發的模式進行的發,應當是創建業務項目,編寫業務代碼,需要的話編寫測試代碼,測試工程師測試,然后驗收發布。
而在TDD中,我們需要面對需求編寫測試代碼。先寫測試代碼,我相信很多人都會覺得很困惑,沒有邏輯,沒有方法,測試代碼測試什么?TDD的理念是測試先行。
-
TDD 的好處
-
嚴格根據TDD思維,遵循SOLID原則 開發能保證代碼質量
-
TDD 確保了代碼與業務需求高度一致性
-
TDD 鼓勵創建更簡單、針對性更強的庫和API
-
TDD 要落實測試單元,需要鼓勵與業務方持續溝通
-
TDD 有助于清除無用代碼。無用代碼實際上維護成本非常高
-
TDD 提供了內置的回歸測試。再次執行測試代碼可檢查修改一個方法邏輯會不會影響到其它現有功能
-
TDD 阻止遞歸錯誤。每個測試都針對系統缺陷,那么,同樣的錯誤不會再次發生
-
TDD 開發應用程序的系統是開放的、可擴展的、靈活的系統。
以上都是廢話,我還沒完整體驗過真正的TDD開發線上系統。理解測試驅動開發的理念,能讓我們編寫更漂亮的代碼倒是真的。
TDD 的三個階段:
-
紅燈階段
編寫貼合需求的測試代碼,盡量保證覆蓋需求每個點。
-
綠燈階段
編寫適當代碼,使測試通過。合理命名一個方法名,然后簡短完成方法??赡芤粋€范湖bool型的方法只寫一個返回代碼。
-
重構階段
這個階段是真正完成業務邏輯的階段。因為我們編寫的測試代碼已經完整滿足業務需要,所以,我們只需要根據測試代碼,編寫完業務代碼,再通過測試即可。
完成一項工程,不要期待只走一遍流程就完成了,寫代碼從來沒有容易的事,很多時候,我們都需要反反復復修改,不僅僅是需求更改,也為了讓我們“以前”寫過的代碼更整潔。
我目前還是覺得,很艱難能堅持TDD模式開發,很難讓你的團隊的伙伴都轉變思維,從測試代碼開始。但不妨礙我們去體會TDD,我們帶著測試的思維去寫業務代碼,時刻都想著,我這樣設計會不會很難測試。如果我們的代碼讓我們很難測試,我相信他大概率也不是好的代碼。
原文轉自:https://www.cnblogs.com/jimizhou/p/11435807.html