一、覆蓋率概念
覆蓋率是用來度量測試完整性的一個手段,是測試技術有效性的一個度量。分為:白盒覆蓋、灰盒覆蓋和黑盒覆蓋;測試用例設計不能一味追求覆蓋率,因為測試成本隨覆蓋率的增加而增加。
覆蓋率=(至少被執行一次的item數)/item的總數
二、白盒覆蓋率***
白盒測試時基於程序結構的邏輯驅動測試,白盒覆蓋中最常見的是邏輯覆蓋(也叫代碼覆蓋或結構化覆蓋),邏輯覆蓋包括:語句覆蓋、判定覆蓋、條件覆蓋、判定條件覆蓋、條件組合覆蓋、路徑覆蓋。
1.語句覆蓋(Statement Coverage)
指在測試時運行被測程序后,程序中被執行到的可執行語句的比率:
語句覆蓋率=(至少被執行一次的語句數量)/(可執行的語句總數)
例:
case1:(2,0,3) 語句覆蓋率=?
case2:(2,1,3) 語句覆蓋率=?
分析:案例中可執行的語句總數有2條:X=X/A和X=X+1;
case1走ace路線,2條語句都被執行了,所以語句覆蓋率為2/2,即100%;
case1走abe路線,只執行了1條語句,所以語句覆蓋率為1/2,即50%;
總結:case1中語句覆蓋率達到了100%,看似很完美,但是並不能百分百的發現bug,若上例中兩個被測程序段邏輯有問題,條件語句寫成:
會發現語句覆蓋率依然為100%,但是發現不了邏輯運算中出現的錯誤;即使語句覆蓋率達到百分百也有缺陷發現不了,所以覆蓋率只是我們度量的手段。
2.判定覆蓋率(Decision Coverage)
判定覆蓋,也叫分支覆蓋(Branch Coverage),是指在測試時運行被測試程序后,程序中所有判斷語句的取真和取假分支被執行到的比率:
判定覆蓋率=(判定結果被評價的次數)/(判定結果的總數)
例:
case1:(2,0,3) 判定覆蓋率=?
case2:(1,0,1) 判定覆蓋率=?
分析:案例中判斷語句的取真和取假分支共有4個:T1\F1\T2\F2
case1走T1-T2路線,2個判斷分支被執行,所以判定覆蓋率為2/4,即50%;
case1走F1-F2路線,2個判斷分支被執行,所以判定覆蓋率為2/4,即50%;
總結:case1和case2加起來剛好可以達到判定覆蓋率100%,但是同樣地,依然會有缺陷發現不了,例如將源程序改為:
3.條件覆蓋(Condition Coverage)
指在測試時運行被測程序后,所有判斷語句中每個條件的可能取值(真值和假值)出現過的比率:
條件覆蓋率=(條件操作數值至少被評價一次的數量)/(條件操作數值的總數)
分析:案例中有兩條判斷語句,每個語句有兩個條件,即4個條件,每個條件有兩個取值,所以條件操作數值的總數為8個,測試用例如下:
總結: 每個case的覆蓋率為4/8,50%,三個用例加起來剛好實現條件覆蓋率100%。但是下面兩條用例也可以實現100%覆蓋,但是卻沒有覆蓋所有分支,所以說條件覆蓋也會有缺陷發現不了。
4.判定-條件覆蓋(Decision Condition Coverage)
是指設計足夠的測試用例,使得判斷中每個條件的所有可能取值至少執行一次,同時每個判斷本身的所有可能判斷結果至少執行一次,也即要求各個判斷的所有可能的條件取值組合至少執行一次,也叫分支條件覆蓋;實際上就是判定覆蓋率和條件覆蓋率的組合。
判定條件覆蓋率=(條件操作數值或判定結果至少被評價一次的數量)/(條件操作數值總數+判定結果總數)
分析:從表面上看,判定條件覆蓋測試了所有的條件的取值,但是事實並非如此。因為往往某些條件掩蓋了另一些條件,對於條件表達式(A>1)and(B=0)來說,若(A>1)的測試結果為真,則還要測試(B=0),才能決定表達式的值;而若條件表達式(A>1)的測試結過果為假時,可以立刻確定表達式的結果為假。這是,往往不再測試條件表達式(B=0)的取值了,這樣的話條件B就沒有檢查,對於(A=2)or(X>1)來說也是同樣的道理。因此,詞用判定-條件覆蓋,邏輯表達式中的錯誤不一定能夠查出來。
總結: 為了能夠防止某些條件掩蓋另一些條件,必須將邏輯表達式分解為單個條件,轉換成如下圖所示的單一條件的嵌套條件結構,這樣可以針對每一條件和判定設計測試用例,防止測試中隊某些條件的側漏。
5.條件組合覆蓋(Multiple Condition Coverage)
基本思想是,設計足夠的測試用例,使得每個判定中條件的各種可能組合都至少出現一次。
條件組合覆蓋率=(條件組合至少被評價一次的數量)/(條件組合總數)
分析:每個判定中條件的各種可能組合如下,條件組合總數為8中。
總結:上面測試用例達到了100%的條件組合覆蓋,但是它所走的路徑只有3條,沒有達到100%的路徑覆蓋,所以條件組合覆蓋也不是十全十美的。
6.路徑覆蓋 (Path Coverage)
指在測試時運行被測程序后,程序中所有可能的路徑被執行過的比率:
路徑覆蓋率=(至少被執行一次的路徑數)/(總的路徑數)
分析:案例中總的路徑為4條,分別為ace,abd,abc,acd,下面4條例子實現了100%的路徑覆蓋。
case1:(2,0,3) 覆蓋路徑ace
case2:(1,0,1) 覆蓋路徑abd
case3:(1,0,3) 覆蓋路徑abc
case4:(3,0,1) 覆蓋路徑acd
總結:對於這組測試用例,路徑覆蓋達到了100%,但是很明顯沒有達到100%條件覆蓋(B!=0未取到) ,所以說路徑覆蓋也不是零缺陷的,進一步說明了覆蓋率只是我們度量的手段。
7.其他覆蓋
a.指令塊覆蓋(Instruction Blocks Coverage,IB Coverage)
是語句覆蓋的一個變體,其唯一的區別是計算方式的不同,在這里指令塊表示函數內部的一個序列語句,在這一個序列語句中不存在控制語句(會引起分支)
指令塊覆蓋=(至少被執行一次的指令塊數量)/(系統中指令塊總數)
例:一次測試中,在第一個控制點走了3條指令的分支,在第二個控制點走了空指令分支,那么其指令塊覆蓋式2/4,即50%;其語句覆蓋式(5+3)/15,即53.33%;
b.判定路徑覆蓋(Decision-to-Decision paths Coverage,DDP Coverage)
是判定覆蓋的一個變體,這里的判定指的是一個序列語句,其起始位置是函數入口或一個判定(如If,while,switch等)的開始,結束位置是下一個判定的開始。具體如下圖:
通過計算哪些判定路徑已經走過,哪些沒走過,我們就可以得到DDP覆蓋率了,公式如下:
DDP 覆蓋=(至少被執行到一次的判定路徑數量)/(系統中判定路徑總數)
三、灰盒覆蓋率
1.接口覆蓋(Interface Coverage)
接口覆蓋,又稱入口點覆蓋,要求通過設計一定的用例使得系統的每個接口被測試到。
接口覆蓋=(至少被執行一次的接口數量)/(系統中接口的總數)
2.函數覆蓋(True Coverage)
函數覆蓋是針對系統或一個子系統的測試的,它表示在該測試中,有哪些函數被測試到了,其被測試到的頻率有多大,這些函數在系統所有函數中占的比例有多大,函數覆蓋是一個比較容易自動化的技術,同時也易於理解。其公式如下:
函數覆蓋=(至少被執行一次的函數數量)/(系統中函數的總數)
四、黑盒覆蓋率
在實際測試中,與黑盒相關的覆蓋率比較少,主要是功能覆蓋率(Functional Coverage),功能覆蓋中最常見的是需求覆蓋(Requirement Coverage),其含義是通過設計一定的測試用例,要求每個需求點都被測試到。
需求覆蓋=(被驗證到的需求數量)/(總的需求數量)
五、面向對象的覆蓋率
1.繼承上下文覆蓋
2.基於狀態的上下文覆蓋
3.基於線程的上下文覆蓋
六、案例
為以下所示的程序段設計一組測試用例,要求分別滿足語句覆蓋、判定覆蓋、條件覆蓋、判定條件覆蓋、條件組合覆蓋和路徑覆蓋,並畫出相應的程序流程圖。
思路: 首先根據程序代碼畫出程序流程圖 ,然后根據程序流程圖分別列出各種覆蓋率的條件,然后設計測試用例,設計完一個用例標記下覆蓋了多少條件,依次往下,直到覆蓋了所有的條件。
用例:
七、重點
1.需要掌握:一個測試用例的各種覆蓋率為多少?
覆蓋率100%的情況下需要設計多少用例?
2.各種測試覆蓋率之間的關系