原創(chuàng)|使用教程|編輯:鄭恭琳|2021-01-07 11:05:38.350|閱讀 527 次
概述:如果代碼覆蓋率對您來說是個問題,請確保您對其進(jìn)行了正確測量,并從您運(yùn)行的所有測試中對其進(jìn)行了測量。利用自動JUnit代碼覆蓋率測試用例生成來快速構(gòu)建和擴(kuò)展測試,以獲得有意義的、可維護(hù)的完整代碼覆蓋率。單元測試覆蓋率是確保您正確測量所有內(nèi)容的好方法。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
如果代碼覆蓋率對您來說是個問題,請確保您對其進(jìn)行了正確測量,并從您運(yùn)行的所有測試中對其進(jìn)行了測量。利用自動JUnit代碼覆蓋率測試用例生成來快速構(gòu)建和擴(kuò)展測試,以獲得有意義的、可維護(hù)的完整代碼覆蓋率。單元測試覆蓋率是確保您正確測量所有內(nèi)容的好方法。
我最近寫了一篇關(guān)于陷入代碼覆蓋率百分比陷阱的討論,這引發(fā)了質(zhì)量討論,所以我想我將更深入地探討代碼覆蓋率問題和解決方案。具體來說,涵蓋率本身,自動生成的JUnit測試的值以及如何識別有問題的單元測試。以及如何在執(zhí)行方面繼續(xù)做得更好。
讓我們從覆蓋率指標(biāo)本身以及我們?nèi)绾斡?jì)算代碼覆蓋率開始。代碼覆蓋率數(shù)字通常是無意義的,或充其量是誤導(dǎo)的。如果您“確實(shí)”擁有100%的代碼覆蓋率,那又意味著什么?您是如何測量的?
有很多不同的方法來衡量覆蓋率。
衡量代碼覆蓋率的一種方法是從需求角度出發(fā)。您是否對每一項(xiàng)要求都進(jìn)行了測試?這是一個合理的開始……但這并不意味著所有代碼都已經(jīng)過測試。
衡量代碼覆蓋率的另一種方法(別笑,我實(shí)際上是在現(xiàn)實(shí)世界中聽到的)是通過測試的次數(shù)。真的,我是真的!這是一個非常糟糕的指標(biāo),顯然毫無意義。是比簡單地計(jì)算您擁有多少個測試還差?我不能說。
然后我們來嘗試確定執(zhí)行了什么代碼。常見的覆蓋率指標(biāo)包括語句覆蓋率、行覆蓋率、分支覆蓋率、決策覆蓋率、多個條件覆蓋率,或者更全面的MC/DC或修改后的條件/決策覆蓋率。
當(dāng)然,最簡單的方法是線路覆蓋率,但是您可能已經(jīng)看到,工具對此進(jìn)行了不同的衡量,因此覆蓋率將有所不同。執(zhí)行代碼行并不意味著您已經(jīng)檢查了該代碼行中可能發(fā)生的所有不同情況。這就是為什么安全關(guān)鍵標(biāo)準(zhǔn)(例如用于汽車功能安全的ISO 26262和用于機(jī)載系統(tǒng)的DO-178B/C)都需要MC/DC。
這是一個簡單的代碼示例,假設(shè)x,y和z為布爾值:
If ( (x||y) && z) { doSomethingGood(); } else {doSomethingElse();}
在這種情況下,無論我的值是多少,該行都被“覆蓋”了。誠然,這是一種將所有內(nèi)容都放在一行上的草率方法,但是您看到了問題。人們實(shí)際上以這種方式編寫代碼。但是,讓我們整理一下。
If ( (x||y) && z) { doSomethingGood(); } else { doSomethingElse(); /* because code should never doSomethingBad() */
一目了然,我可能會得出這樣的結(jié)論:我只需要兩個測試——一個將整個表達(dá)式評估為TRUE并執(zhí)行doSomethingGood() (x=true, y=true, z=true),而另一個則評估為FALSE并執(zhí)行doSomethingElse() (x=false, y=false, z=false)。行覆蓋率說我們很高興,“一切都經(jīng)過測試。”
但是請稍等,可以通過多種方式測試主表達(dá)式:
這是一個簡單的示例,但它說明了這一點(diǎn)。我這里需要進(jìn)行4個測試才能真正正確地覆蓋代碼,至少在我關(guān)心MC/DC覆蓋率的情況下。當(dāng)我完成一半時,行覆蓋率會說100%。我將再一次不再詳細(xì)說明MC/DC的價值。這里的重點(diǎn)是,無論您使用哪種方法衡量覆蓋率,通過斷言進(jìn)行驗(yàn)證的內(nèi)容都有意義是很重要的。
許多人陷入的另一個陷阱是添加了一種不復(fù)雜的工具來自動生成單元測試。
簡單的測試生成工具可以創(chuàng)建無需任何聲明即可執(zhí)行代碼的測試。這樣可以避免測試變得嘈雜,但實(shí)際上意味著您的應(yīng)用程序不會崩潰。不幸的是,這并不能告訴您應(yīng)用程序是否在執(zhí)行應(yīng)做的事情,這很重要。
下一代工具通過根據(jù)它們可以自動捕獲的任何特定值創(chuàng)建斷言來工作。但是,如果自動生成會產(chǎn)生大量斷言,則最終會產(chǎn)生大量麻煩。這里沒有中間立場。您要么擁有易于維護(hù)但毫無意義的東西,要么擁有值得懷疑的維護(hù)噩夢。
首先,許多自動生成單元測試的開源工具看起來很有價值,因?yàn)槟母采w率非??臁U嬲膯栴}在于維護(hù)。通常,在開發(fā)過程中,開發(fā)人員會付出額外的努力來微調(diào)自動生成的斷言,以創(chuàng)建他們認(rèn)為干凈的測試套件。但是,斷言是脆弱的,不能隨著代碼的更改而適應(yīng)。這意味著開發(fā)人員在下次發(fā)布時必須再次執(zhí)行大部分“自動”生成。測試套件可以重用。如果您無法重復(fù)使用它們,則說明您做錯了什么。
這也不能掩蓋一個可怕的想法,即在第一次運(yùn)行時,當(dāng)您具有較高的覆蓋率時,測試中的斷言沒有應(yīng)有的意義。僅僅因?yàn)榭梢詳嘌阅承〇|西,并不意味著應(yīng)該這樣做,或者甚至是正確的事情。
public class ListTest { private List<String> list = new ArrayList<>(); @Test public void testAdd() { list.add(“Foo”); assertNotNull(list); } }
理想情況下,斷言將檢查代碼是否正常運(yùn)行,并且當(dāng)代碼工作不正常時,斷言將失敗。有很多斷言都不是很容易的,我們將在下面進(jìn)行探討。
如果您要以覆蓋率高、可靠、干凈的測試套件為代價來拍攝高覆蓋率的產(chǎn)品,那么您將失去價值。一套維護(hù)良好的測試套件使您對代碼充滿信心,甚至是快速安全重構(gòu)的基礎(chǔ)。嘈雜和/或毫無意義的測試意味著您不能依賴測試套件,不能重構(gòu),甚至不能發(fā)布。
人們對代碼進(jìn)行衡量(尤其是根據(jù)嚴(yán)格的標(biāo)準(zhǔn))時,會發(fā)現(xiàn)他們發(fā)現(xiàn)自己的代碼比自己想要的要低。通常,這最終導(dǎo)致他們追逐承保率。讓我們開始報(bào)道吧!現(xiàn)在,您可能會因?yàn)椴缓侠淼男拍疃萑胛kU的境地,即自動化JUnit測試已經(jīng)創(chuàng)建了有意義的測試,或者通過手工創(chuàng)建了意義不大且維護(hù)成本很高的單元測試。
在現(xiàn)實(shí)世界中,維護(hù)測試套件的持續(xù)成本遠(yuǎn)遠(yuǎn)超過了創(chuàng)建單元測試的成本,因此從一開始就創(chuàng)建良好的干凈單元測試非常重要。您會知道這一點(diǎn),因?yàn)槟梢栽诔掷m(xù)集成(CI)流程中始終運(yùn)行測試。如果您僅在發(fā)行時運(yùn)行測試,則表明測試噪音大。具有諷刺意味的是,這使得測試變得更糟,因?yàn)樗鼈儧]有得到維護(hù)。
軟件測試自動化還不錯,實(shí)際上,這是必要的,因?yàn)樗哂挟?dāng)今常見的復(fù)雜性和時間壓力。但是,自動生成價值通常比其價值更麻煩。與隨意創(chuàng)建斷言相比,基于擴(kuò)展值,監(jiān)視實(shí)際系統(tǒng)以及創(chuàng)建復(fù)雜的框架、模擬和存根的自動化提供了更多的價值。
測量
第一步是衡量并獲得有關(guān)您當(dāng)前覆蓋率的報(bào)告,否則,您將不會知道自己的位置以及情況是否會好轉(zhuǎn)。進(jìn)行此操作時,衡量所有測試活動(包括單元、功能、手冊等)并正確匯總覆蓋率非常重要。這樣,您將盡最大的努力去努力——在完全未經(jīng)測試的代碼上,而不是端到端測試涵蓋但沒有碰巧的代碼上單元測試。Parasoft可以準(zhǔn)確地匯總來自多個運(yùn)行和多種類型測試的代碼覆蓋率,從而為您提供準(zhǔn)確的位置信息。有關(guān)此方面的更多信息,請參見我們的白皮書:全面的代碼覆蓋率—測試實(shí)踐的合計(jì)覆蓋率。
構(gòu)架
為您創(chuàng)建單元測試框架的工具是一個很好的入門方法。確保這些工具連接到Mockito和PowerMock等常見的模擬框架,因?yàn)閷?shí)際代碼很復(fù)雜,并且需要存根和模擬。但這還不夠,您需要能夠:
您可以手動完成所有這些操作,但是這會花費(fèi)大量時間和精力。這是利用自動化的絕佳場所——例如,Parasoft Jtest在IDE中實(shí)時提供自動建議,并與開源框架(JUnit,Mockito,PowerMock等)集成,以幫助用戶創(chuàng)建、擴(kuò)展和維護(hù)他們的JUnit測試套件并提供更廣泛的覆蓋率。如果您對此技術(shù)感到好奇,則可以了解有關(guān)人們?yōu)槭裁从憛拞卧獪y試又如何重新喜愛上它的更多信息。
如果覆蓋率對于您的項(xiàng)目來說是一個問題,請確保您對其進(jìn)行了正確的衡量,并從您運(yùn)行的所有測試中對所有方面進(jìn)行了衡量。隨著您開始使用單元測試擴(kuò)展覆蓋率,您可以利用指導(dǎo)性的測試創(chuàng)建來快速創(chuàng)建和擴(kuò)展測試,以獲取有意義的可維護(hù)代碼覆蓋率。Parasoft Jtest將創(chuàng)建隨著代碼的增長和更改而可維護(hù)的測試,因此您不必一遍又一遍地執(zhí)行相同的工作。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn