提高單元測試覆蓋率的意義與價值


什么是單元測試覆蓋率 蚁鳖?

單元測試覆蓋率是一種軟件測試的度量指標(biāo)醉箕,指在所有功能代碼中,完成了單元測試的代碼所占的比例放棒。有很多自動化測試框架工具可以提供這一統(tǒng)計數(shù)據(jù)间螟,其中最基礎(chǔ)的計算方式為:

單元測試覆蓋率 = 被測代碼行數(shù) / 參測代碼總行數(shù) * 100%

Note: 一般情況下厢破, 參測代碼總行數(shù)是指排除配置文件治拿、以及測試代碼本身的所有功能代碼的總行數(shù)劫谅。


單元測試的度量方式

最常見的單元測試覆蓋率的度量方式有以下三種:

1. 行覆蓋率 / 語句覆蓋
這種覆蓋率統(tǒng)計方式是最為基礎(chǔ)的同波,它可以用于體現(xiàn)參測代碼中已被執(zhí)行和未被執(zhí)行的代碼行(語句)未檩,從而可以進(jìn)一步推斷代碼的邏輯覆蓋是否全面。

2. 分支覆蓋
這種覆蓋率統(tǒng)計方式是用于統(tǒng)計代碼中所有判斷分支是否都被覆蓋冤狡,如

...
if (condition)
{
    Operation_1();
} 
else 
{
    Operation_2();
}
...

語句就會根據(jù) condition 的值產(chǎn)生兩個不同的分支操作悲雳,那么在統(tǒng)計分支覆蓋時,就需要對兩個分支都進(jìn)行校驗坦胶。值得注意的是顿苇,上例中的代碼税弃,其分支覆蓋可以被行覆蓋所取代,也就是說若上面代碼的行覆蓋率為100%幔翰, 則其分支覆蓋率亦為100%遗增。

但是如果將代碼換為三元表達(dá)式款青,如

...
condition ? Operation_1() : Operation_2();
...

此時可都,行覆蓋率在統(tǒng)計時渠牲,只要這一行代碼有被執(zhí)行,那么行覆蓋率必然為100%瘫镇,并不關(guān)心是否兩種情況都被執(zhí)行過铣除。但如此一來就沒辦法通過行覆蓋率保證其分支覆蓋率為100% 了尚粘。

3.條件覆蓋
這種覆蓋統(tǒng)計方式是針對代碼中產(chǎn)生多分支郎嫁,并且每個分支的激活條件比較復(fù)雜的情況泽铛。
代碼的分支一般都是通過流程控制語句產(chǎn)生的,而流程控制語句再激活一個分支時是需要條件的杠茬,依然以之前的代碼為例澈蝙,若condition 是幾個布爾值的組合灯荧,

...
if (Condition())
{
    Operation_1();
} 
else 
{
    Operation_2();
}
...

private bool Condition () {
  return condition_1 || condition_2 && condition_3;
}

那么此時逗载,代碼依然只有兩個分支厉斟,但是由于激活條件是取決于condition_1, condition_2, condition_3的組合情況强衡,那么在校驗條件覆蓋時感挥,就應(yīng)該考慮所有可能的組合情況,也就是8種測試用例触幼。這樣才可以使條件覆蓋的覆蓋率達(dá)到100%置谦。全面考慮條件覆蓋的做法就可以達(dá)到優(yōu)化測試的效果媒峡。

其實谅阿,覆蓋率的統(tǒng)計方式還是用很多其他種類的奔穿,這里給出的只是幾種最基礎(chǔ)的贱田。但不管怎樣男摧,完備的單元測試行覆蓋都是其他度量方式的基礎(chǔ)耗拓。當(dāng)行覆蓋率達(dá)標(biāo)之后,開發(fā)人員才會有精力修改奏司、優(yōu)化測試用例乔询,從而提高分支覆蓋率、條件覆蓋率等其他更具業(yè)務(wù)價值的單元測試覆蓋率韵洋。


提高單元測試覆蓋率的意義與價值

摘自《TestCoverage》Martin Fowler

有些時候竿刁,我們想提高項目測試覆蓋率的閾值,比如從45% 提高到80%搪缨,又或者從 95% 提高到100%食拜。
那么這個時候,我們就需要問一問自己副编,為什么要做這樣的事情负甸?提高覆蓋率的意義與價值何在?

1. 是想通過單元測試來保證代碼質(zhì)量痹届?
單元測試的覆蓋率高與代碼質(zhì)量高队腐,二者并沒有直接關(guān)系,這是因為覆蓋率的高低完全是可以“造假”的。一些沒有實際業(yè)務(wù)價值的測試用例因運而生荸型,甚至發(fā)生類似 AssertionFreeTesting 的情況辕狰,使覆蓋率“虛高”
因此,我們沒有依據(jù)說明高覆蓋率就能確保好的代碼質(zhì)量母剥。

2. 是想通過單元測試保證業(yè)務(wù)邏輯不會出錯秦爆?
用單元測試保證業(yè)務(wù)邏輯芬膝,看上去很有道理。可是仔細(xì)一想,就會發(fā)現(xiàn)這一點,其實有些不切實際罩句。一個業(yè)務(wù)功能的實現(xiàn)并不僅僅依賴于某一個方法诅福、某一個類赂乐,那么通過單元測試能夠保證的業(yè)務(wù)邏輯也是十分有限的浅役,不可能做到“不會出錯”瞪讼。
可以試想希柿,如果僅僅依靠測試金字塔最底層的單元測試盾戴,使其覆蓋率達(dá)標(biāo)就能保證業(yè)務(wù)邏輯不出錯,那么為什么還需要更高層的集成測試和功能測試,甚至探索性測試呢?
另一方面,如果是想將單元測試與業(yè)務(wù)邏輯相綁定遥金,那么方向也不應(yīng)是提高覆蓋率美莫,而應(yīng)該是提供更加符合業(yè)務(wù)場景的測試用例給已有的單元測試,也就是提高已有的單元測試質(zhì)量科阎。

如此一來述吸,這兩個問題都無法通過提高單元測試覆蓋率解決,那么我們提高覆蓋率還有什么意義與價值呢茅逮?

測試覆蓋率幫助我們找到?jīng)]有被測試的代碼挺身。
提高測試覆蓋率惨撇,可以讓我們在重構(gòu)帆卓、優(yōu)化這些沒有被測試的代碼時更有底氣剑令。

但是,最大的前提是你的測試代碼是值得信任的拄查。

那么現(xiàn)在吁津,我們可以考慮一下這兩種情況了:

  1. 將覆蓋率從 45% 提高到 80%。
  2. 將覆蓋率從 95% 提高到100%堕扶。

對于第一種情況碍脏,不到一般的初始測試覆蓋率而言,首先會讓開發(fā)人員在進(jìn)行重構(gòu)時很沒有安全感稍算,由于未被測試覆蓋的代碼量太多典尾,從而無法快速發(fā)現(xiàn)改動是否會對未覆蓋的代碼帶來不良影響。 因此糊探,在這種情況下钾埂,提高代碼的覆蓋率河闰,從而讓更多的代碼被測試,讓開發(fā)者在重構(gòu)時能更放心褥紫,這對項目更有益淤击。

而對于第二種情況,可以看到覆蓋率已經(jīng)很高了故源,那么這個時候污抬,
首先看看開發(fā)者經(jīng)常改動或重構(gòu)的代碼是否都被覆蓋,如果是绳军,則重點應(yīng)該放在優(yōu)化測試用例上印机,看看是否所有的邊界條件都被測試,所有的分支都被覆蓋等等门驾。因為這時射赛,提高已有的單元測試質(zhì)量,讓測試用例更貼近業(yè)務(wù)場景所帶來的收益會遠(yuǎn)遠(yuǎn)大于進(jìn)一步提高測試覆蓋率所帶來的收益奶是。
否則楣责,一旦重構(gòu)了未被覆蓋的參測代碼,就應(yīng)該為改代碼添加單元測試聂沙,使之被覆蓋秆麸,從而確保功能的正常運作。


總結(jié)

  1. 單元測試僅用來保證代碼所對應(yīng)的功能正常及汉,若想將之與業(yè)務(wù)結(jié)合沮趣,需要貼合業(yè)務(wù)場景的測試用例。
  2. 單元測試覆蓋率僅用來找出未被測試的代碼坷随,若想通過覆蓋率保證業(yè)務(wù)邏輯房铭,需要進(jìn)一步優(yōu)化已有單元測試的質(zhì)量。
  3. 提高單元測試覆蓋率僅對之前沒有測試覆蓋或覆蓋極其不足的代碼有顯著增益温眉,若想對已經(jīng)被測試高度覆蓋的代碼進(jìn)行優(yōu)化缸匪,需要著眼于提升已有的測試用例質(zhì)量。
  4. 團(tuán)隊合作開發(fā)类溢,應(yīng)盡量保證自己每次提交的代碼都已經(jīng)全部被測試覆蓋凌蔬。

參考文章

TestCoverage
AssertionFreeTesting
單元測試之覆蓋率淺談

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豌骏,隨后出現(xiàn)的幾起案子龟梦,更是在濱河造成了極大的恐慌,老刑警劉巖窃躲,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件计贰,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒂窒,警方通過查閱死者的電腦和手機躁倒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門荞怒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秧秉,你說我怎么就攤上這事褐桌。” “怎么了象迎?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵荧嵌,是天一觀的道長。 經(jīng)常有香客問我砾淌,道長啦撮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任汪厨,我火速辦了婚禮赃春,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘劫乱。我一直安慰自己织中,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布衷戈。 她就那樣靜靜地躺著狭吼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脱惰。 梳的紋絲不亂的頭發(fā)上搏嗡,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音拉一,去河邊找鬼。 笑死旧乞,一個胖子當(dāng)著我的面吹牛蔚润,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播尺栖,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼嫡纠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了延赌?” 一聲冷哼從身側(cè)響起除盏,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挫以,沒想到半個月后者蠕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡掐松,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年踱侣,在試婚紗的時候發(fā)現(xiàn)自己被綠了粪小。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡抡句,死狀恐怖探膊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情待榔,我是刑警寧澤逞壁,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站锐锣,受9級特大地震影響猾担,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜刺下,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一绑嘹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧橘茉,春花似錦工腋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至翁潘,卻和暖如春趁冈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拜马。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工渗勘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俩莽。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓旺坠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扮超。 傳聞我的和親對象是個殘疾皇子取刃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 1.測試與軟件模型 軟件開發(fā)生命周期模型指的是軟件開發(fā)全過程、活動和任務(wù)的結(jié)構(gòu)性框架出刷。軟件項目的開發(fā)包括:需求璧疗、設(shè)...
    宇文臭臭閱讀 6,721評論 5 100
  • 1.測試與軟件模型 軟件開發(fā)生命周期模型指的是軟件開發(fā)全過程、活動和任務(wù)的結(jié)構(gòu)性框架馁龟。軟件項目的開發(fā)包括:需求崩侠、設(shè)...
    Mr希靈閱讀 21,952評論 7 278
  • 測試現(xiàn)在被普遍認(rèn)為“保證產(chǎn)品質(zhì)量”這個籠統(tǒng)的說法下啦膜,而測試本身是什么呢有送?今天我們就測試本身跟大家一起討論。 測試是...
    西邊人閱讀 4,604評論 2 52
  • 文章來自:http://blog.csdn.net/mj813/article/details/52451355 ...
    好大一只鵬閱讀 9,189評論 2 126
  • 第115篇 《五月抒懷》 一別家鄉(xiāng)有數(shù)日僧家,滿口佳肴味還留雀摘; 念念不忘父母情,苦口婆心勸兒悠八拱。 每逢夜來倍寂寥阵赠,遠(yuǎn)望...
    好郝說話閱讀 180評論 0 2