讀古今文學網 > C語言解惑 > 13.10 測試用例設計技術 >

13.10 測試用例設計技術

既然無法對軟件進行徹底的測試,那麼測試用例的設計便是測試是否取得成功的根本保證。為此,測試人員必須採用那些能夠以盡量少的測試數據來發現盡量多的錯誤的測試技術。

不同的測試在選擇測試用例方面有著很大差別。白盒測試法是根據詳細設計中的邏輯流程來設計測試用例,以暴露編碼中的邏輯錯誤,如是否存在不可執行的路徑或無限循環等。屬於這類測試法的有邏輯覆蓋法。黑盒測試是用「軟件需求說明書」來設計測試用例,即把軟件看成黑盒子,對輸入進行轉換,檢查輸出的正確性。屬於這類測試法的有等價劃分法、邊值分析法、錯誤猜測法等。這些測試用例設計技術各有優缺點,沒有哪一種是最好的,更沒有一種技術能夠代替其他所有技術。同一種技術對不同的應用問題,其效果也可能相差很大。因此,對於軟件測試,通常需要聯合使用多種測試用例設計方法,才能發現軟件的各種各樣的錯誤。

13.10.1 邏輯覆蓋法

邏輯覆蓋法是針對軟件內部的邏輯結構設計測試用例的。由於無法完全測試軟件的所有路徑,所以邏輯覆蓋法採用逐級覆蓋的辦法,在每一級上有選擇地執行某些路徑,如此一級一級地進行覆蓋,逐步使路徑測試達到盡可能完善的程度。

覆蓋級別由低到高可以劃分為:

(1)語句覆蓋:每個語句至少執行一次。

(2)判定覆蓋:對於每個判定語句,執行真假兩種結果。

(3)條件覆蓋:使判定表達式中的每個簡單條件都取到各種可能的結果。

(4)判定/條件覆蓋:使判定表達式中的每個簡單條件取到各種可能的值,並且使每個判定也都取到各種可能的結果。

(5)條件組合覆蓋:使判定表達式中的簡單條件能夠得到各種可能的組合情況。

應當引起注意的是,隨著測試級別的提高,測試用例的數據量會急劇增加。

1.語句覆蓋

所謂語句覆蓋,就是選擇足夠的測試用例,使程序中的每個語句至少執行一次。例如:


float test
(float A
, float B
, float X
) 
{
           if 
((A>1
)&&
(B= =0
))
                 X=X/A
;
           if 
((A= =2
)||
(X>1
))
                 X=X+1
;
           return X
;
}
  

這是一個被測試模塊的源程序,它的流程圖如圖13-14所示。為了使模塊中的每個語句都執行一次,只需設計一個能通過路徑sacbed的測試用例即可,例如下面一組測試數據


A=2
,B=0
,X=3
  

雖然能夠覆蓋程序中的所有語句,但它對程序邏輯卻覆蓋得很少。因為數據只對兩個判斷條件為真進行了測試,如果條件為假,顯然不能發現錯誤。此外,如果將第一個判斷語句中的條件「&&」誤寫成「||」,或者將第二個判斷語句中的X>l誤寫成X>0,該測試用例無法暴露這些錯誤。由此可見,語句覆蓋是一種很弱的覆蓋標準。

圖13-14 被測試模塊流程圖

2.判定覆蓋

判定覆蓋亦稱分支覆蓋,即選擇足夠的測試用例,使程序中的每個判定的各個分支至少執行一次。

對於上述被測試模塊,如果設計兩個測試用例,使它們分別通過路徑sacbd和sabed,或者分別通過路徑sacbed和sabd,就可以滿足判定覆蓋標準。這樣的測試用例可以設計成:

(1)A=3,B=0,X=3(通過路徑sacbed)

(2)A=2,B=l,X=l(通過路徑sabd)

顯然,判定覆蓋比語句覆蓋嚴格,因為如果每個分支都執行過了:那麼每個語句也就執行過了。但是,它對程序邏輯的覆蓋程度仍然不高。例如,如果將第二個判定語句中的X>l誤寫成X>0,這兩個測試用例仍無法發現該錯誤。

3.條件覆蓋

一個判定的條件表達式往往是一個由若干簡單條件所組成的復合條件。例如前例中的條件表達式(A>l)&&(B==0),由兩個簡單條件A>l、B==0和邏輯運算符「&&」構成。所以,對於復合條件的判定採用判定覆蓋標準進行測試,顯然不夠嚴格。為此,可以採用一個更強的覆蓋標準——條件覆蓋,即選擇足夠多的測試用例,使得判定中的每個簡單條件都取到各種可能的結果。

在圖13-14的例子中,共有兩個判定,每個判定的條件表達式都由兩個簡單條件組成。為了滿足條件覆蓋標準,所選擇的測試用例應當使得在a點出現下述各種結果:

A>l,A≤l,B=0,B≠0

在b點應當出現的結果是:

A=2,A≠2,X>l,X≤l

只需使用以下兩個測試用例就可以滿足這些條件:

(1)A=2,B=0,X=4(通過路徑sacbed,在a點滿足A>l,B=0;在b點滿足A=2,X>l)

(2)A=l,B=l,X=l(通過路徑sabd,在a點滿足A≤l,B≠0;在b點滿足A≠2,X≤l)

一般說來,條件覆蓋比判定覆蓋嚴格,因為它使條件表達式中的每個簡單條件都取得了兩種不同的結果,而判定覆蓋則不保證這一點。但是,也可能出現相反的情況,即滿足條件覆蓋標準,卻不滿足判定覆蓋標準。例如,以下兩個測試用例就是這種情況,它使得第二個判定的條件表達式總為真:

(1)A=2,B=0,X=l(通過路徑sacbed,在a點滿足A>1,B=0;在b點滿足A=2,X≤l)

(2)A=l,B=l,X=2(通過路徑sabed,在a點滿足A≤l,B≠0;在b點滿足A≠2,X>l)

4.判定/條件覆蓋

針對上面的問題,可以採用另一種覆蓋標準,這就是判定/條件覆蓋。它的含義是,選擇足夠的測試用例,使得判定表達式中的每個簡單條件取到各種可能的值,並且使每個判定也都取到各種可能的結果。

對於圖13-14中的程序,下面兩個測試用例滿足判定/條件覆蓋標準:

(1)A=2,B=0,X=4

(2)A=l,B=l,X=l

這兩組數據就是為了滿足條件覆蓋標準最初選用的測試用例。因此,判定/條件覆蓋有時並不比條件覆蓋強多少。

5.條件組合覆蓋

條件組合覆蓋是更強的覆蓋標準,它要求選擇更多的測試用例,以便使每個判定表達式中的簡單條件能夠取到各種可能的組合情況。

對於圖13-14中的程序,共有下面8種可能的條件組合:


(1
)A>l
,B=0   
(2
)A>l
,B
≠0   
(3
)A
≤l
,B=0    
(4
)A
≤l
,B
≠0
(5
)A=2
,X>l   
(6
)A=2
,X
≤l   
(7
)A
≠2
,X>l    
(8
)A
≠2
,X
≤l
  

為了使這8種條件組合至少出現一次,可以使用以下4組測試數據:


(1
)A=2
,B=0
,X=4 
(針對1
、5
兩種組合,通過路徑sacbed
)
(2
)A=2
,B=l
,X=l 
(針對2
、6
兩種組合,通過路徑sabed
)
(3
)A=l
,B=0
,X=2 
(針對3
、7
兩種組合,通過路徑sabed
)
(4
)A=l
,B=l
,X=l 
(針對4
、8
兩種組合,通過路徑sabd
)。
  

顯然,滿足條件組合覆蓋標準的測試用例,一定滿足判定覆蓋、條件覆蓋和判定/條件覆蓋標準。因此,條件組合覆蓋標準是最強的一種覆蓋標準。但是,滿足條件組合覆蓋標準的測試用例,不一定能通過程序中的所有路徑。例如,上述4組測試用例,就沒有測試到路徑sacbd。

一般說來,條件組合覆蓋標準比其他標準優越。但是任何一種邏輯覆蓋標準都不足以成為唯一的測試標準,還需要用其他的測試方法加以補充。

13.10.2 等價劃分法

等價劃分是一種黑盒測試設計技術。其目的在於系統性地確定測試用例,從而使得到的測試用例對發現某類錯誤有極高的概率。

這種方法建立在以下的假定基礎之上。如果將軟件輸入數據的可能值劃分成若干類,每一類的一個典型值在測試中的作用與這一類中所有其他值的作用等價。也就是說,如果某一類中的一個例子發現了錯誤,那麼該等價類中的其他例子也能發現同樣的錯誤;反之,如果某一類中的一個例子沒有發現錯誤,那麼該等價類中的其他例子也不會發現錯誤。因此,採用等價劃分方法測試軟件,只需從每個等價類中選擇一組數據作為測試用例,從而實現了用較少的測試用例發現盡可能多的錯誤。

使用等價劃分法設計測試用例,首先必須按照軟件的功能說明分析輸入條件,確定輸入數據的各種有效等價類和無效等價類。合理等價類,系指軟件合理的一類輸入數據;不合理等價類,系指非法的一類輸入數據。

劃分等價類在很大程度上取決於軟件人員的經驗。一般說來,以下幾條原則可作為劃分等價類的依據:

(1)輸入條件中規定了輸入數據的取值範圍,則可據此劃分出一個合理等價類和兩個不合理等價類。例如,考試成績的取值範圍是從0至100,那麼合理的等價類為大於等於0且小於等於100的數,小於0的數和大於100的數均為不合理的等價類。

(2)輸入條件中規定了輸入數據的個數,則可據此劃分出一個合理等價類和兩個不合理等價類。例如,體育比賽取前三名的成績(不考慮並列第幾名的情況),那麼,合理的等價類為三個輸入數據,而小於三個輸入數據以及大於三個輸入數據均為不合理的等價類。

(3)輸入條件中規定了輸入數據必須遵循的規則,則可據此劃分出一個合理等價類和若干個不合理等價類。例如,標識符的規則有一條是第一個字符必須是字母,那麼第一個字符為字母者為合理的等價類,而第一個字符為數字以及其他特殊符號者為不合理等價類。

(4)若輸入條件中規定了輸入數據的一組值,而且軟件對不同的輸入值採取不同的處理,則每個允許的輸入值是一個合理的等價類,其他值則為不合理的等價類。例如,正高級職稱的輸入值分教授、研究員和教授級高級工程師三種,那麼每一種職稱可以作為一個等價類,而除上述三種職稱之外的值為不合理的等價類。

(5)若規定輸入數據為整型,則可以劃分為正整數、零和負整數三個合理等價類,而小數則為不合理的等價類。

劃分出輸入數據的等價類以後,便可根據等價類設計測試用例。設計測試用例時應按以下四個步驟來進行:

(1)設計一個新的測試用例,使它盡可能多地涉及那些尚未被涉及的合理等價類;

(2)重複第一步,直至新選擇的測試用例己涉及了所有的合理等價類;

(3)設計一個新的測試用例,使它涉及一個尚未被涉及的不合理等價類;

(4)重複第三步,直至所選擇的測試用例已涉及了所有的不合理等價類。

需要指出的是,在選擇不合理等價類的測試用例時,應使每個例子僅涉及一個不合理等價類。這是因為,軟件中的一個錯誤條件往往會抑制對其他錯誤條件的檢測。一個例子涉及兩個以上的不合理等價類,就會使一部分軟件功能沒有被測試到。

13.10.3 邊值分析法

經驗表明,軟件在處理邊緣情況時容易發生錯誤。例如,在下標、數據結構、標量和循環變量取最大值、最小值及其臨界值時往往出現錯誤。因此,使用針對這個區域的測試用例,能提高軟件測試發現錯誤的概率。這種測試用例的設計方法稱為邊值分析法。

運用邊值分析法設計測試用例依賴軟件人員的經驗和創造性。一般來說,以下幾條原則可用做選擇測試用例的依據:

(1)若輸入條件中規定了輸入數據的取值範圍,則可在合理等價類中選擇一些恰到好處且剛剛處於範圍之內的邊界值的例子。另外再從不合理等價類中選擇一些恰好越過邊界的例子。例如,輸入值的範圍是-1.0~1.0,則可選擇-1.0、1.0、-0.99、-1.01和1.01作為測試用例。

(2)若輸入條件中規定了輸入數據的個數,則可選擇最小個數、最大個數,比最大個數多1、比最小個數少1、比最小個數多1、比最大個數少1等幾種情況設計測試用例。例如,在輸入字符串時,規定字符串可由1~256個字符組成,則可分別設計有1個字符、256個字符、2個字符、255個字符、0個字符和257個字符的用例。

(3)若輸入數據為有序集合結構,如順序文件、線性表等,則應特別注意對集合的第一個、最後一個元素以及空集設計測試用例。

邊值分析法不同於等價劃分法,它不是從一個等價類中任選一個例子作代表,而是選一個或幾個例子,使得該等價類的邊界條件成為測試的主要目標。此外,邊值分析法不僅注意輸入條件,它還根據輸出條件,即輸出的等價類設計測試用例。但是,由於輸入值的邊界不一定與輸出值的邊界相對應,所以要設計出使輸出處於邊界條件的測試用例住往是很困難的。儘管如此,在設計測試用例時考慮到這種情況仍然是十分重要的。

13.10.4 因果圖法

等價劃分法和邊值分析法的缺點是沒有測試輸入條件的組合。往往存在這一種情況,雖然分別使用每組測試用例時,軟件都能正常工作,但是輸入數據的某種組合卻能暴露出錯誤。不過,要檢查所有輸入條件的組合併非容易,即使是一個比較小的程序或模塊,可能的輸入條件的組合數目也往往十分巨大。如果沒有一種系統的方法是難以設計條件組合測試用例的。這種方法就是因果圖法。它利用輸入條件(即原因)和輸出或程序狀態的改變(即效果)之間的邏輯關係設計測試用例,以便實現輸入條件的組合測試。

用因果圖法設計測試用例按以下四個步驟進行:

(1)為一個程序列出原因(輸入條件)和效果(輸出或程序狀態)並為每個原因和效果規定一個標識符;

(2)繪製因果圖;

(3)將因果圖轉換成判定表;

(4)按判定表的每一規則設計一個測試用例。

13.10.5 錯誤猜測法

使用等價劃分法和邊值分析法可以設計出具有代表性的測試用例。但是,不同類型和不同特點的軟件通常又有一些特殊的容易出錯的情況。對於這些情況往往無法採用特定的技術來設計測試用例,只能靠軟件人員的經驗和直覺來推測軟件中可能存在的各種錯誤,從而針對這些錯誤設計測試用例,這就是錯誤猜測法。

錯誤猜測法沒有確定的原則,一般要憑經驗來假定錯誤類型。例如本章列舉的編碼錯誤及模塊測試內容,就是常見的軟件錯誤的經驗總結。又如,輸入數據為零或輸出數據為零;輸入表格為空或只有一項;輸入參數具有默認值等均是容易出錯的地方。

此外,對於解決特定問題的軟件,應根據其功能,猜測軟件設計中容易忽視的情況。例如,對於排序程序應著重檢測:1輸入表為空;2輸入表中只有一項;3輸入表中所有的項具有相同的值;4輸入表已經是排序的或逆序的。對於一個採用二分法的查詢程序應著重檢測:1被查詢的表只有一項;2表的項數恰好等於2的冪次;3表的項數比2的冪次多1或少1;4被查詢的值正好在表中的第一項、最後一項或中間項。這些均是設計時往往被忽視而處理中易出錯的情況。