爲何從前那些.NET開發者都不寫單元測試呢?

楔子

四年前我雖然也寫了不少年代碼,因爲公司雖然規模不小,卻並不是一家規範化的軟件公司,所以在項目中嚴格意義上來講並無架構設計、也不寫單元測試,後來有幸加入了一家公司,這家公司雖然也是一家小公司,可是好歹曾經聘請過一位架構師,這位架構師使用spring.net 搭建了一套基礎的技術架構,並在公司推廣使用EnterpriseArchiture(EA)軟件設計UML圖,可是因爲種種緣由,他試用期還沒過,只是簡單的設計了幾個業務以後就離職了。程序員

我加入這家公司的時候距離這位架構師離職也已經有至關長的時間,未能直接學習的機會,可是很是還能接觸到這位優秀架構師留下來的部分代碼和資料,這爲個人職場之路打開了新的窗戶,從這些資料中學到了許多以前一直想學可是沒機會學的內容,並第一次接觸到單元測試這種技術。spring

然而,值得諷刺的是,在他搭建的項目架構中,單元測試代碼也只有一個簡單的示例,並無針對業務功能編寫任何的具體測試代碼,而實際上經手這個項目的開發者已經超過了幾十我的,其實這也從一個側面說明中國至關一部分.Net 開發者跟我同樣,幾乎都不寫單元測試。甚至是很多開源代碼貢獻者,他們貢獻的開源組件,也並無設計單元測試的代碼。可是再來看國外的一些優秀的開源組件,每每也都會提供單元測試的代碼,TDD實際上正是一種很是便捷高效門檻低的設計模式。編程

後來,我經手的每個項目都會按照TDD的方式寫單元測試,可是依然沒有深入領悟單元測試的精髓,只是把它當作代碼調試的一個入口而已。其實這種單元測試依然不合格,尤爲是認真的運行一下代碼覆蓋率報告以後,就會發現,單元測試的代碼覆蓋率只有10個點,與微軟的官方標準單元測試覆蓋率100%相比,簡直就是不合格。設計模式

什麼是單元測試?

一直以來你們有一種錯誤的理念,老是認爲單元測試做爲一種測試方法,主要是由測試工程師來主導的一種測試手段。並不是如此,借用教科書上的說法,單元測試做爲一種最基礎的測試手段,其主要做用是「在計算機編程中,針對程序模塊(最軟件設計中的最小單元)進行正確性檢驗的測試工做。」架構

以前曾經閱讀過一篇文章,做者提了一個例子,他說他兒子在使用樂高積木作玩偶過程當中,組裝完一些零部件以後,就會試圖去測試一下部件是否可以正常運轉,做者說這種過程實際上就是一種單元測試。他認爲,單元測試的思想其實廣泛存在於人類文明的發展過程當中,從人類開始製做工具來講,就須要使用單元測試的方法對工具的可用性進行測試。尤爲是進入工業時代以來,傳統制造業尤爲重視產品質量,爲了提升產品質量,採起了一系列措施,這種例子其實不勝枚舉。框架

去年我曾經有幸爲一家國企開發過一些質量管理系統,並深刻了解了這些企業的質量管理流程,雖然從宏觀層面來看,以互聯網經濟爲表明的新興經濟對以包括製造業在內的實體經濟帶來了許多衝擊,可是依然那些優秀的製造業企業依然堅決的將產品質量做爲核心競爭力,並經過互聯網的這種模式,讓企業的發展得到了新的機遇。工具

軟件行業其實本質上和製造業沒有那麼巨大的區別,以軟件開發過程當中,由軟件工程師們開發出來的每個方法實際上就是開發者們解決虛擬世界生存問題的零部件,每個產品或應用就是這樣的工具。在一個軟件開發過程當中,每每須要涉及到多人操做,常常須要調用別人編寫的模塊代碼。尤爲是在面向互聯網開發中,若是不能認真的對待每一行代碼,就有可能一些疏忽大意形成不可彌補的後果。單元測試

所以作好單元測試,不只僅只是開發者們應該採用的一種測試手段,而是應該是一種基本的技術手段,對咱們開發的每一行代碼,都應該使用單元測試進行覆蓋,本身負責的模塊定義應該儘可能明確,模塊內部的更改不會影響他模塊,讓模塊的質量獲得穩定和良好的保證。學習

爲何你們認爲單元測試不合時宜?

固然,大部分開發者也許明白這個道理,可是卻認爲單元測試不合時宜,主要包括如下幾點:測試

1,沒有時間 
---- 在軟件開發過程當中,每每以完成任務爲第一要務,而因爲時間計劃的安排,單元測試的設計和實踐均須要花費大量的時間完成,過分的使用單元測試會拖延項目的進度,並且花費的邊界成本高昂而收效甚微。 
---- 筆者認爲,跟隨代碼一塊兒,設計和應用單元測試,並不會顯著的帶來時間上的損害,反而會讓開發者更加關注代碼自己的目的,讓輸入輸出和計算過程更爲合理。

2,計劃會變化:需求變化快,單元測試跟不上需求的變化 
因爲軟件產品需求的不肯定性,致使以前設計的單元測試並不是符合項目的實際功能性需求,不必花費這個精力設計這種沒用的場景。 
----筆者認爲,需求變化與是否應用單元測試關係不大。

3,單元測試是用來找Bug的,應該有測試來編寫 
單元測試做爲一種測試手段,是爲了發現代碼中存在的bug。 
--- 筆者認爲:單元測試的目的是爲了讓程序做者更加快捷的發現代碼中存在的問題,並在第一時間發現和解決,從而保障軟件質量。

4,有程序員定義的單元測試沒有意義,由於程序員設定的邏輯場景就有可能不許確 
單元測試做爲由程序員根據實際用例出發設計的測試流程,自己可能並不是符合業務的實際應用須要,所以單元測試應該由最瞭解需求的人來進行設計。並且完成單元測試設計後,也須要有了解需求的人對單元測試用例和代碼進行審查。 
--- 筆者認爲:由程序員開發的單元測試沒有意義,那麼他寫的代碼呢?寫代碼自己就是爲了完成指定的用例場景,若是單元測試都不合理,那麼如何確保代碼自己就合理?

五、TDD測試驅動,不過是一種形式主義,自己就不合時宜 
在TDD模式中,測試先於開發,因此須要通過良好的設計和定義,最好可以解耦合各個模塊,讓代碼更加完美的匹配測試代碼。可是這種代碼自己就要求經驗豐富的開發者才能完成,而可以完成這種能力的,自己就屬於優秀開發者,並不須要設計單元測試代碼。 
-- 筆者認爲:優秀的開發者,自己不只僅只是由於他們出身優秀,而是由於他們掌握了包括單元測試等在內的優秀學習方法並天天都在實踐。

好的單元測試的標準

筆者最近閱讀《構建之美》(初版)深入認同提出的關於好的單元測試的標準,例如如下幾點: 
一、單元測試應該在最低的功能\參數上驗證程序的正確性。 
二、單元測試應該由最熟悉代碼的人(程序的做者)來寫。 
三、單元測試事後,機器狀態保持不變。---筆者認爲,不只僅機器的狀態應該保持不變,數據中存儲的數據關係也應該保持不變,例如,經過單元測試錄入的數據,應該在完成測試後自動回滾,或者添加測試戳記後,手動清除。 
四、單元測試要快(一個測試的運行時間是幾秒鐘,而不是幾分鐘)。 
五、單元測試應該產生可重複、一致的結果。 
六、單元測試具備獨立性的特色,單元測試的運行、經過、失敗不依賴於別的測試,能夠認爲構造數據,以保持單元測試的獨立性。 
七、單元測試應該負載全部的代碼路徑。 
八、單元測試應該繼承到自動測試的框架中。 
九、單元測試必須與產品代碼一塊兒保存和維護。

何妨不試一試呢?

在軟件企業的發展前期,每每會因爲技術上的一些偶發性突破,取得短時間的優點,可是隨着企業的規模發展,使用更加規範化甚至成爲形式化的方式確保產品的質量是必然趨勢,而單元測試則是一種看似簡單,但卻效果顯著的手段,相信經過一段時間的實踐,就會深入的領悟到其中的妙處。

因爲時間倉促,可能沒什麼乾貨,下一篇再進一步討論單元測試、代碼覆蓋率的問題。

相關文章
相關標籤/搜索