为什么我们要做单元测试?(二)
引子
當(dāng)我第一篇博客發(fā)布,并被張善友老師的公眾號轉(zhuǎn)載之后,在公眾號文章和博客園的留言中,許多開發(fā)者紛紛表示,單元測試作為企業(yè)行為,與實施的技術(shù)棧不同,不是開發(fā)者個人行為,實施單元測試花費的時間精力過于龐大,與實際效果嚴(yán)重不對等,而且如果過度的采用單元測試,也會增加新的測試點,因為單元測試代碼本身就需要進(jìn)行測試等。
?從這些回復(fù)可以看出,程序員要不要編寫單元測試這種話題,大概做傳統(tǒng)開發(fā)時,問程序員要不要寫項目文檔一樣充滿爭議。正如大家都深刻明白項目文檔的重要性,但是一旦程序員需要編寫項目文檔了,往往會對這個事情產(chǎn)生抵觸情緒,這實際上是絕大多數(shù)開發(fā)者的通病。
單元測試也是這樣的矛盾糾結(jié)體。在長沙.net技術(shù)社區(qū)就有不少朋友紛紛表示,他們都曾經(jīng)試圖在公司推動單元測試的應(yīng)用,但是受到了自上而下的反對聲,最終迫于壓力,只能放棄。?而之所以阻力這么大,其主要原因是編寫單元測試會增加額外的時間,因為編寫單元測試,不僅僅只是編寫一個簡單的測試入口,而是一系列步驟,但是領(lǐng)導(dǎo)要求在最短的時間看到效果,并且有的領(lǐng)導(dǎo)還經(jīng)常改變主意,如果設(shè)計了一個優(yōu)秀的單元測試用例,有時候甚至?xí)驗闊o法適應(yīng)需求的變化,而最終腐爛。?
顯然,使用單元測試和更高的單元測試的代碼覆蓋率,大概是一個試金石。過去在長沙還很少有企業(yè)會問開發(fā)者會不會使用單元測試,但是近年來越來越多的企業(yè)會問候選人代碼覆蓋率的問題,所以作為開發(fā)者,可以嘗試從單元測試開始,努力提高自己的代碼習(xí)慣,編寫更加高質(zhì)量的代碼。
有哪些公司在要求編寫單元測試?
過去,單元測試一直是專業(yè)軟件公司的首選,有一位原諾基亞核心部門的開發(fā)者說為諾基亞內(nèi)部,對單元測試的要求很高,雖然沒有達(dá)到百分之百,但也有非常高的要求,在《構(gòu)建之法》中,鄒欣老師介紹了微軟的開發(fā)實踐,也對單元測試覆蓋率提出了很高的要求。?當(dāng)然有的讀者或許會嗤之以鼻,這些都是古典軟件公司,舉這些例子有什么意義呢?中國式IT 公司,哪家都是996,哪里還有什么時間實行單元測試??
然而,優(yōu)秀的互聯(lián)網(wǎng)公司都開始推行devops 作為企業(yè)信息化建設(shè)過程中的最佳實踐標(biāo)準(zhǔn),持續(xù)集成和持續(xù)發(fā)布都對單元測試有很高的要求,例如在阿里巴巴java 開發(fā)者手冊中,就明確提出了以下一系列指標(biāo),要求開發(fā)者務(wù)必采用單元測試方法,盡可能的提高代碼質(zhì)量。
【強(qiáng)制】好的單元測試必須遵守 AIR 原則。
...此處省略七百字
【推薦】單元測試的基本目標(biāo):語句覆蓋率達(dá)到 70% ;核心模塊的語句覆蓋率和分支覆蓋率都要達(dá)到 100%?
參見原文阿里巴巴Java 開發(fā)者手冊,由此可見,單元測試已經(jīng)作為一種行之有效的手段,顯然已經(jīng)成為了中國優(yōu)秀互聯(lián)網(wǎng)企業(yè)的必然之選。
單元測試中的代碼覆蓋率有什么用?
代碼覆蓋率是單元測試的重要衡量指標(biāo),反映了單元測試中測試用例對被測代碼的覆蓋程度,是對代碼的測試質(zhì)量衡量的重要指標(biāo)。
在十年前,博客園《代碼覆蓋率淺談》(參考資料1)一文,深入淺出的介紹了單元測試的四種類型,?包括語句覆蓋,判定覆蓋,條件覆蓋,路徑覆蓋四種類型,作者指出,單元測試覆蓋率結(jié)果,有以下作用:
a. 覆蓋率數(shù)據(jù)只能代表你測試過哪些代碼,不能代表你是否測試好這些代碼。?
b. 不要過于相信覆蓋率數(shù)據(jù)。
c. 不要只拿語句覆蓋率(行覆蓋率)來考核你的測試人員。?
d. 路徑覆蓋率 > 判定覆蓋 > 語句覆蓋?
e. 測試人員不能盲目追求代碼覆蓋率,而應(yīng)該想辦法設(shè)計更多更好的案例,哪怕多設(shè)計出來的案例對覆蓋率一點影響也沒有。?
在軟件開發(fā)過程中盲目的追求的高代碼覆蓋率,往往得不償失,尤其是為了提高代碼覆蓋率而做的單元測試,往往只會成為累贅。
合理的操作形式應(yīng)該是基于實際用例出發(fā),設(shè)定更多的用例場景,實現(xiàn)基于用戶場景驅(qū)動的單元測試覆蓋,像在阿里巴巴開發(fā)者手冊中說的,測試人員與開發(fā)人員配合,共同完成測試用例覆蓋,就是一種不錯的應(yīng)用實踐。
當(dāng)然,即便測試缺位,開發(fā)者也完全應(yīng)該主動的承擔(dān)更多單元測試的職能,盡可能多的思考用戶場景中可能存在的變數(shù)。
編寫好的單元測試的一些小技巧
技巧一,多看書肯定是不錯的
有朋友問,怎么寫好單元測試?有什么書推薦么?我很慚愧,我自己的代碼單元測試的覆蓋率還相當(dāng)?shù)?#xff0c;可能沒辦法給出指導(dǎo),我想多看書肯定是沒錯的,而編寫單元測試的書,還挺多的,例如這一本,《單元測試的藝術(shù)》,一看就是基于C#的,可以試一試。?
?而想入單元測試的門,可以看看我后面找到的一系列引文,相信能給你帶來方便。?
技巧二,運用測試框架?
1、單元測試框架:XUnit、NUnit、MSTest等.
2、測試運行工具:xunit.runner.visualstudio 。類似如:Resharper的xUnit runner插件。?
3、模擬框架:Moq、RhinoMocks、NSubstitute、FakeItEasy等。??
技巧三,靈活的運用事務(wù)回滾或內(nèi)存數(shù)據(jù)庫,避免單元測試數(shù)據(jù)污染正常數(shù)據(jù)
前者是阿里巴巴開發(fā)者手冊中提到的一種方法,在有的場景下也挺實用的,不過有開發(fā)者指出,可以使用模擬內(nèi)存數(shù)據(jù)庫來解決這個問題更為妥當(dāng),例如使用Effort.EF6,通過nuget獲取,使得創(chuàng)建一個偽造的、供EF容易使用的內(nèi)存數(shù)據(jù)庫成為可能。與這類似的,還可以使用HttpSimulator來模擬http 請求。?
技巧四,使用依賴注入和單例模式改良不可測代碼
靜態(tài)類為代碼編寫帶來了許多便利,但是也使得代碼測試變得相對困難,而使用單例模式進(jìn)行改良則使得操作更可控。?
總結(jié)
人生苦短,擼碼不易。從選擇成為開發(fā)者的那一天起,我們就被迫承受了許多壓力,尤其是技術(shù)發(fā)展的不確定性,更是如此,你永遠(yuǎn)也不知道自己當(dāng)下的選擇是否正確,說不定你今天最為熟悉的技術(shù)或框架,明天就涼涼了。尤其是現(xiàn)在的各種自媒體,時不時的發(fā)幾篇文章來輸出焦慮,巴不得天天說優(yōu)勝劣汰才能獲得讀者的關(guān)注一般,讓開發(fā)者們壓力更大。
我覺得,技術(shù)是解決問題的方法,而良好的代碼習(xí)慣則是自身心法,尤其是單元測試,更是一種好習(xí)慣,先別總想著擔(dān)心自己被淘汰,努力的使自己習(xí)慣更好,總會獲得無窮收獲。
參考資料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:《代碼覆蓋率強(qiáng)迫癥》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.
碼字不易啊..哈哈
(本文是作者為社區(qū)貢獻(xiàn)的內(nèi)容,贊賞的所有費用都將作為長沙.NET技術(shù)社區(qū)運營費用,感謝您的關(guān)注,讓我們一起努力,共同創(chuàng)造長沙.NET技術(shù)社區(qū)更好的明天)
總結(jié)
以上是生活随笔為你收集整理的为什么我们要做单元测试?(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core 沉思录 - 结
- 下一篇: 程序员修神之路--提高网站的吞吐量