引子
當我第一篇部落格釋出,並被張善友老師的公眾號轉載之後,在公眾號文章和部落格園的留言中,許多開發者紛紛表示,單元測試作為企業行為,與實施的技術棧不同,不是開發者個人行為,實施單元測試花費的時間精力過於龐大,與實際效果嚴重不對等,而且如果過度的採用單元測試,也會增加新的測試點,因為單元測試程式碼本身就需要進行測試等。
從這些回覆可以看出,程式員要不要編寫單元測試這種話題,大概做傳統開發時,問程式員要不要寫專案檔案一樣充滿爭議。正如大家都深刻明白專案檔案的重要性,但是一旦程式員需要編寫專案檔案了,往往會對這個事情產生抵觸情緒,這實際上是絕大多數開發者的通病。
單元測試也是這樣的矛盾糾結體。在長沙.net技術社群就有不少朋友紛紛表示,他們都曾經試圖在公司推動單元測試的應用,但是受到了自上而下的反對聲,最終迫於壓力,只能放棄。 而之所以阻力這麼大,其主要原因是編寫單元測試會增加額外的時間,因為編寫單元測試,不僅僅只是編寫一個簡單的測試入口,而是一系列步驟,但是領導要求在最短的時間看到效果,並且有的領導還經常改變主意,如果設計了一個優秀的單元測試用例,有時候甚至會因為無法適應需求的變化,而最終腐爛。
顯然,使用單元測試和更高的單元測試的程式碼改寫率,大概是一個試金石。過去在長沙還很少有企業會問開發者會不會使用單元測試,但是近年來越來越多的企業會問候選人程式碼改寫率的問題,所以作為開發者,可以嘗試從單元測試開始,努力提高自己的程式碼習慣,編寫更加高質量的程式碼。
有哪些公司在要求編寫單元測試?
過去,單元測試一直是專業軟體公司的首選,有一位原諾基亞核心部門的開發者說為諾基亞內部,對單元測試的要求很高,雖然沒有達到百分之百,但也有非常高的要求,在《構建之法》中,鄒欣老師介紹了微軟的開發實踐,也對單元測試改寫率提出了很高的要求。 當然有的讀者或許會嗤之以鼻,這些都是古典軟體公司,舉這些例子有什麼意義呢?中國式IT 公司,哪家都是996,哪裡還有什麼時間實行單元測試?
然而,優秀的網際網路公司都開始推行devops 作為企業資訊化建設過程中的最佳實踐標準,持續整合和持續釋出都對單元測試有很高的要求,例如在阿裡巴巴java 開發者手冊中,就明確提出了以下一系列指標,要求開發者務必採用單元測試方法,盡可能的提高程式碼質量。
-
【強制】好的單元測試必須遵守 AIR 原則。
-
…此處省略七百字
-
【推薦】單元測試的基本標的:陳述句改寫率達到 70% ;核心模組的陳述句改寫率和分支改寫率都要達到 100%
參見原文阿裡巴巴Java 開發者手冊,由此可見,單元測試已經作為一種行之有效的手段,顯然已經成為了中國優秀網際網路企業的必然之選。
單元測試中的程式碼改寫率有什麼用?
在十年前,部落格園《程式碼改寫率淺談》(參考資料1)一文,深入淺出的介紹了單元測試的四種型別, 包括陳述句改寫,判定改寫,條件改寫,路徑改寫四種型別,作者指出,單元測試改寫率結果,有以下作用:
a. 改寫率資料只能代表你測試過哪些程式碼,不能代表你是否測試好這些程式碼。
b. 不要過於相信改寫率資料。
c. 不要只拿陳述句改寫率(行改寫率)來考核你的測試人員。
d. 路徑改寫率 > 判定改寫 > 陳述句改寫
e. 測試人員不能盲目追求程式碼改寫率,而應該想辦法設計更多更好的案例,哪怕多設計出來的案例對改寫率一點影響也沒有。
在軟體開發過程中盲目的追求的高程式碼改寫率,往往得不償失,尤其是為了提高程式碼改寫率而做的單元測試,往往只會成為累贅。
合理的操作形式應該是基於實際用例出發,設定更多的用例場景,實現基於使用者場景驅動的單元測試改寫,像在阿裡巴巴開發者手冊中說的,測試人員與開發人員配合,共同完成測試用例改寫,就是一種不錯的應用實踐。
當然,即便測試缺位,開發者也完全應該主動的承擔更多單元測試的職能,盡可能多的思考使用者場景中可能存在的變數。
編寫好的單元測試的一些小技巧
有朋友問,怎麼寫好單元測試?有什麼書推薦麼?我很慚愧,我自己的程式碼單元測試的改寫率還相當低,可能沒辦法給出指導,我想多看書肯定是沒錯的,而編寫單元測試的書,還挺多的,例如這一本,《單元測試的藝術》,一看就是基於C#的,可以試一試。
而想入單元測試的門,可以看看我後面找到的一系列引文,相信能給你帶來方便。
1、單元測試框架:XUnit、NUnit、MSTest等.
2、測試執行工具:xunit.runner.visualstudio 。類似如:Resharper的xUnit runner外掛。
3、模擬框架:Moq、RhinoMocks、NSubstitute、FakeItEasy等。
前者是阿裡巴巴開發者手冊中提到的一種方法,在有的場景下也挺實用的,不過有開發者指出,可以使用模擬記憶體資料庫來解決這個問題更為妥當,例如使用Effort.EF6,透過nuget獲取,使得建立一個偽造的、供EF容易使用的記憶體資料庫成為可能。與這類似的,還可以使用HttpSimulator來模擬http 請求。
靜態類為程式碼編寫帶來了許多便利,但是也使得程式碼測試變得相對困難,而使用單例樣式進行改良則使得操作更可控。
總結
我覺得,技術是解決問題的方法,而良好的程式碼習慣則是自身心法,尤其是單元測試,更是一種好習慣,先別總想著擔心自己被淘汰,努力的使自己習慣更好,總會獲得無窮收穫。
參考資料1:《程式碼改寫率淺談》https://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html?tt_from=copy_link&utm;_source=copy_link&utm;_medium=toutiao_ios&utm;_campaign=client_share.
參考資料2:《程式碼改寫率強迫症》https://www.infoq.cn/article/test-coverage-ocd.
參考資料3:《程式碼改寫率 (Code Coverage)從簡到繁》
https://www.cnblogs.com/jacksundatashare/p/5083352.html.
參考資料4,《C#單元測試,帶你快速入門》http://www.cnblogs.com/zhaopei/p/UnitTesting.html?from=singlemessage&isappinstalled;=0.
碼字不易啊..哈哈
(本文是作者為社群貢獻的內容,贊賞的所有費用都將作為長沙.NET技術社群運營費用,感謝您的關註,讓我們一起努力,共同創造長沙.NET技術社群更好的明天)