为什么从前那些.NET开发者都不写单元测试呢?
楔子
四年前我雖然也寫了很多年代碼,由于公司雖然規(guī)模不小,卻并非一家規(guī)范化的軟件公司,因此在項目中嚴格意義上來說并沒有架構(gòu)設(shè)計、也不寫單元測試,后來有幸加入了一家公司,這家公司雖然也是一家小公司,但是好歹曾經(jīng)聘請過一位架構(gòu)師,這位架構(gòu)師使用spring.net 搭建了一套基礎(chǔ)的技術(shù)架構(gòu),并在公司推廣使用EnterpriseArchiture(EA)軟件設(shè)計UML圖,但是由于種種原因,他試用期還沒過,只是簡單的設(shè)計了幾個業(yè)務(wù)之后就離職了。
我加入這家公司的時候距離這位架構(gòu)師離職也已經(jīng)有相當(dāng)長的時間,未能直接學(xué)習(xí)的機會,但是非常還能接觸到這位優(yōu)秀架構(gòu)師留下來的部分代碼和資料,這為我的職場之路打開了新的窗戶,從這些資料中學(xué)到了許多之前一直想學(xué)但是沒機會學(xué)的內(nèi)容,并第一次接觸到單元測試這種技術(shù)。
然而,值得諷刺的是,在他搭建的項目架構(gòu)中,單元測試代碼也只有一個簡單的示例,并沒有針對業(yè)務(wù)功能編寫任何的具體測試代碼,而實際上經(jīng)手這個項目的開發(fā)者已經(jīng)超過了幾十個人,其實這也從一個側(cè)面說明中國相當(dāng)一部分.Net 開發(fā)者跟我一樣,幾乎都不寫單元測試。甚至是不少開源代碼貢獻者,他們貢獻的開源組件,也并沒有設(shè)計單元測試的代碼。但是再來看國外的一些優(yōu)秀的開源組件,往往也都會提供單元測試的代碼,TDD實際上正是一種非常便捷高效門檻低的設(shè)計模式。
后來,我經(jīng)手的每一個項目都會按照TDD的方式寫單元測試,但是依然沒有深刻領(lǐng)悟單元測試的精髓,只是把它當(dāng)做代碼調(diào)試的一個入口而已。其實這種單元測試依然不合格,尤其是認真的運行一下代碼覆蓋率報告之后,就會發(fā)現(xiàn),單元測試的代碼覆蓋率只有10個點,與微軟的官方標(biāo)準單元測試覆蓋率100%相比,簡直就是不合格。
什么是單元測試?
一直以來大家有一種錯誤的理念,總是認為單元測試作為一種測試方法,主要是由測試工程師來主導(dǎo)的一種測試手段。并非如此,借用教科書上的說法,單元測試作為一種最基礎(chǔ)的測試手段,其主要作用是“在計算機編程中,針對程序模塊(最軟件設(shè)計中的最小單元)進行正確性檢驗的測試工作。”
之前曾經(jīng)閱讀過一篇文章,作者提了一個例子,他說他兒子在使用樂高積木做玩偶過程中,組裝完一些零部件之后,就會試圖去測試一下部件是否能夠正常運轉(zhuǎn),作者說這種過程實際上就是一種單元測試。他認為,單元測試的思想其實普遍存在于人類文明的發(fā)展過程中,從人類開始制作工具來說,就需要使用單元測試的方法對工具的可用性進行測試。尤其是進入工業(yè)時代以來,傳統(tǒng)制造業(yè)尤其重視產(chǎn)品質(zhì)量,為了提高產(chǎn)品質(zhì)量,采取了一系列措施,這種例子其實不勝枚舉。
去年我曾經(jīng)有幸為一家國企開發(fā)過一些質(zhì)量管理系統(tǒng),并深入了解了這些企業(yè)的質(zhì)量管理流程,雖然從宏觀層面來看,以互聯(lián)網(wǎng)經(jīng)濟為代表的新興經(jīng)濟對以包括制造業(yè)在內(nèi)的實體經(jīng)濟帶來了許多沖擊,但是依然那些優(yōu)秀的制造業(yè)企業(yè)依然堅定的將產(chǎn)品質(zhì)量作為核心競爭力,并通過互聯(lián)網(wǎng)的這種模式,讓企業(yè)的發(fā)展獲得了新的機遇。
軟件行業(yè)其實本質(zhì)上和制造業(yè)沒有那么巨大的區(qū)別,以軟件開發(fā)過程中,由軟件工程師們開發(fā)出來的每一個方法實際上就是開發(fā)者們解決虛擬世界生存問題的零部件,每一個產(chǎn)品或應(yīng)用就是這樣的工具。在一個軟件開發(fā)過程中,往往需要涉及到多人操作,經(jīng)常需要調(diào)用別人編寫的模塊代碼。尤其是在面向互聯(lián)網(wǎng)開發(fā)中,如果不能認真的對待每一行代碼,就有可能一些疏忽大意造成不可彌補的后果。
因此做好單元測試,不僅僅只是開發(fā)者們應(yīng)該采用的一種測試手段,而是應(yīng)該是一種基本的技術(shù)手段,對我們開發(fā)的每一行代碼,都應(yīng)該使用單元測試進行覆蓋,自己負責(zé)的模塊定義應(yīng)該盡量明確,模塊內(nèi)部的更改不會影響他模塊,讓模塊的質(zhì)量得到穩(wěn)定和良好的保證。
為什么大家認為單元測試不合時宜?
當(dāng)然,大部分開發(fā)者也許明白這個道理,但是卻認為單元測試不合時宜,主要包括以下幾點:
1,沒有時間?
---- 在軟件開發(fā)過程中,往往以完成任務(wù)為第一要務(wù),而由于時間計劃的安排,單元測試的設(shè)計和實踐均需要花費大量的時間完成,過度的使用單元測試會拖延項目的進度,而且花費的邊界成本高昂而收效甚微。?
---- 筆者認為,跟隨代碼一起,設(shè)計和應(yīng)用單元測試,并不會顯著的帶來時間上的損害,反而會讓開發(fā)者更加關(guān)注代碼本身的目的,讓輸入輸出和計算過程更為合理。
2,計劃會變化:需求變化快,單元測試跟不上需求的變化?
由于軟件產(chǎn)品需求的不確定性,導(dǎo)致之前設(shè)計的單元測試并非符合項目的實際功能性需求,沒必要花費這個精力設(shè)計這種沒用的場景。?
----筆者認為,需求變化與是否應(yīng)用單元測試關(guān)系不大。
3,單元測試是用來找Bug的,應(yīng)該有測試來編寫?
單元測試作為一種測試手段,是為了發(fā)現(xiàn)代碼中存在的bug。?
--- 筆者認為:單元測試的目的是為了讓程序作者更加快捷的發(fā)現(xiàn)代碼中存在的問題,并在第一時間發(fā)現(xiàn)和解決,從而保障軟件質(zhì)量。
4,有程序員定義的單元測試沒有意義,因為程序員設(shè)定的邏輯場景就有可能不準確?
單元測試作為由程序員根據(jù)實際用例出發(fā)設(shè)計的測試流程,本身可能并非符合業(yè)務(wù)的實際應(yīng)用需要,因此單元測試應(yīng)該由最了解需求的人來進行設(shè)計。而且完成單元測試設(shè)計后,也需要有了解需求的人對單元測試用例和代碼進行審查。?
--- 筆者認為:由程序員開發(fā)的單元測試沒有意義,那么他寫的代碼呢?寫代碼本身就是為了完成指定的用例場景,如果單元測試都不合理,那么如何確保代碼本身就合理?
5、TDD測試驅(qū)動,不過是一種形式主義,本身就不合時宜?
在TDD模式中,測試先于開發(fā),所以需要經(jīng)過良好的設(shè)計和定義,最好能夠解耦合各個模塊,讓代碼更加完美的匹配測試代碼。但是這種代碼本身就要求經(jīng)驗豐富的開發(fā)者才能完成,而能夠完成這種能力的,本身就屬于優(yōu)秀開發(fā)者,并不需要設(shè)計單元測試代碼。?
-- 筆者認為:優(yōu)秀的開發(fā)者,本身不僅僅只是因為他們出身優(yōu)秀,而是因為他們掌握了包括單元測試等在內(nèi)的優(yōu)秀學(xué)習(xí)方法并每天都在實踐。
好的單元測試的標(biāo)準
筆者最近閱讀《構(gòu)建之美》(第一版)深刻認同提出的關(guān)于好的單元測試的標(biāo)準,例如以下幾點:?
1、單元測試應(yīng)該在最低的功能\參數(shù)上驗證程序的正確性。?
2、單元測試應(yīng)該由最熟悉代碼的人(程序的作者)來寫。?
3、單元測試過后,機器狀態(tài)保持不變。---筆者認為,不僅僅機器的狀態(tài)應(yīng)該保持不變,數(shù)據(jù)中存儲的數(shù)據(jù)關(guān)系也應(yīng)該保持不變,例如,通過單元測試錄入的數(shù)據(jù),應(yīng)該在完成測試后自動回滾,或者添加測試戳記后,手動清除。?
4、單元測試要快(一個測試的運行時間是幾秒鐘,而不是幾分鐘)。?
5、單元測試應(yīng)該產(chǎn)生可重復(fù)、一致的結(jié)果。?
6、單元測試具有獨立性的特點,單元測試的運行、通過、失敗不依賴于別的測試,可以認為構(gòu)造數(shù)據(jù),以保持單元測試的獨立性。?
7、單元測試應(yīng)該負載所有的代碼路徑。?
8、單元測試應(yīng)該繼承到自動測試的框架中。?
9、單元測試必須與產(chǎn)品代碼一起保存和維護。
何妨不試一試呢?
在軟件企業(yè)的發(fā)展前期,往往會由于技術(shù)上的一些偶發(fā)性突破,取得短期的優(yōu)勢,但是隨著企業(yè)的規(guī)模發(fā)展,使用更加規(guī)范化甚至成為形式化的方式確保產(chǎn)品的質(zhì)量是必然趨勢,而單元測試則是一種看似簡單,但卻效果顯著的手段,相信通過一段時間的實踐,就會深刻的領(lǐng)悟到其中的妙處。
由于時間倉促,可能沒什么干貨,下一篇再進一步討論單元測試、代碼覆蓋率的問題。
?
轉(zhuǎn)載于:https://www.cnblogs.com/xiyuanMore/p/10618130.html
總結(jié)
以上是生活随笔為你收集整理的为什么从前那些.NET开发者都不写单元测试呢?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 学习笔记 反射与迭代器
- 下一篇: 看《你必须知道的.NET》有感--工厂模