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