1 白盒測試的概念
白盒測試也稱結構測試或邏輯驅動測試,是一種測試用例設計方法,它從程序的控制結構導出測試用例。(測試用例由測試輸入數據以及與之對應的輸出結果組成。)
白盒測試使用被測單元內部如何工作的信息,允許測試人員對程序內部邏輯結構及有關信息來設計和選擇測試用例,對程序的邏輯路徑進行測試。基於一個應用代碼的內部邏輯知識,測試是基於覆蓋全部代碼、分支、路徑、條件。
2 白盒測試的主要目的
- 保證一個模塊中的所有獨立路徑至少被執行一次;
- 對所有的邏輯值均需要測試真、假兩個分支;
- 在上下邊界及可操作範圍內運行所有循環;
- 檢查內部數據結構以確保其有效性。
3 測試覆蓋標準
白盒法特點:以程序的內部邏輯為基礎設計測試用例,所以又稱為邏輯覆蓋法。應用白盒法時,手頭必須有程序的規格說明以及程序清單。
白盒法考慮的是測試用例對程序內部邏輯的覆蓋程度。最徹底的白盒法是覆蓋程序中的每一條路徑,但是由於程序中一般含有循環,所以路徑的數目極大,要執行每一條路徑是不可能的,只能希望覆蓋的程度儘可能高些。
圖1 程序流程圖
圖1包括了一個執行達20次的循環。那麼它所包含的不同執行路徑數高達520(=1013)條,若要對它進行窮舉測試,覆蓋所有的路徑。假使測試程序對每一條路徑進行測試需要1毫秒,同
樣假定一天工作24小時,一年工作365天, 那麼要想把如圖所示的小程序的所有路徑測試完,則需要3170年。
為了衡量測試的覆蓋程度,需要建立一些標準,目前常用的一些覆蓋標準從低到高分別是:
- 語句覆蓋:是一個比較弱的測試標準,它的含義是:選擇足夠的測試用例,使得程序中每個語句至少都能被執行一次。它是最弱的邏輯覆蓋,效果有限,必須與其它方法交互使用。
- 判定覆蓋(也稱為分支覆蓋):執行足夠的測試用例,使得程序中的每一個分支至少都通過一次。判定覆蓋只比語句覆蓋稍強一些,但實際效果表明,只是判定覆蓋,還不能保證一定能查出在判斷的條件中存在的錯誤。因此,還需要更強的邏輯覆蓋準則去檢驗判斷內部條件。
- 條件覆蓋:執行足夠的測試用例,使程序中每個判斷的每個條件的每個可能取值至少執行一次;條件覆蓋深入到判定中的每個條件,但可能不能滿足判定覆蓋的要求。
- 判定/條件覆蓋:執行足夠的測試用例,使得判定中每個條件取到各種可能的值,並使每個判定取到各種可能的結果。判定/條件覆蓋有缺陷。從表面上來看,它測試了所有條件的取值。但是事實並非如此。往往某些條件掩蓋了另一些條件。會遺漏某些條件取值錯誤的情況。為徹底地檢查所有條件的取值,需要將判定語句中給出的複合條件表達式進行分解,形成由多個基本判定嵌套的流程圖。這樣就可以有效地檢查所有的條件是否正確了。
- 條件組合覆蓋:執行足夠的例子,使得每個判定中條件的各種可能組合都至少出現一次。這是一種相當強的覆蓋準則,可以有效地檢查各種可能的條件取值的組合是否正確。它不但可覆蓋所有條件的可能取值的組合,還可覆蓋所有判斷的可取分支,但可能有的路徑會遺漏掉。測試還不完全。
4 白盒測試的主要方法
- 邏輯驅動測試
- 語句覆蓋
- 判定覆蓋(分支覆蓋)
- 條件覆蓋
- 判定/條件覆蓋
- 條件組合覆蓋
- 基本路徑測試
- 設計足夠多的測試用例,運行所測程序,要覆蓋程序中所有可能的路徑。這是最強的覆蓋準則。但在路徑數目很大時,真正做到完全覆蓋是很困難的,必須把覆蓋路徑數目壓縮到一定限度。
4.1 邏輯驅動測試
4.1.1 語句覆蓋
程序1如下:
PROCEDURE M(VAR A,B,X:REAL);
BEGIN
IF (A>1) AND (B=0) THEN X:=X/A ;
IF (A=2) OR (X>1) THEN X:=X+1 ;
END
圖2 程序流程圖
為使程序中每個語句至少執行一次,只需設計一個能通過路徑ace的例子就可以了,就可達到「語句覆蓋」標準。例如選擇輸入數據為:
A=2,B=0,X=3
缺點: 從上例可看出,語句覆蓋實際上是很弱的
- 如果第一個條件語句中的AND錯誤地編寫成OR,上面的測試用例是不能發現這個錯誤的;
- 又如第三個條件語句中X>1誤寫成X>0,這個測試用例也不能暴露它;
- 此外,沿著路徑abd執行時,X的值應該保持不變,如果這一方面有錯誤,上述測試數據也不能發現它們。
4.1.2 判定覆蓋(分支覆蓋)
對程序1,如果設計兩個用例,使它們能通過路徑ace和abd,或者通過路徑acd和abe,就可達到「判定覆蓋」標準,為此,可以選擇輸入數據為:
- A=3,B=0,X=1 (沿路徑acd執行);
- A=2,B=1,X=3(沿路徑abe執行)
優點:「分支覆蓋」比「語句覆蓋」嚴格,因為如果每個分支都執行過了,則每個語句也就執行過了。
缺點:但是,「分支覆蓋」還是很不夠的
- 兩個測試用例未能烤爐到A<=1的情況
- 兩個測試用例未能檢查沿著路徑abd執行時,X的值是否保持不變。
4.1.3 條件覆蓋
一個判定中往往包含了若干個條件,如程序中,判定 (A>1) AND (B=0)包含了兩個條件: A>1以及 B=0,所以可引進一個更強的覆蓋標準——「條件覆蓋」。
程序1有四個條件:
A>1 、B=0、A=2、X>1
為了達到「條件覆蓋」標準,需要執行足夠的測試用例使得在a點有:
A>1、A≤1、B=0、B≠0
以及在b點有:
A=2、A≠2、X>1、X≤1
現在只需設計以下兩個測試用例就可滿足這一標準:
- A=2,B=1,X=4 (沿路徑abe執行);
- A=1,B=0,X=1 (沿路徑abd執行)。
優點:「條件覆蓋」通常比「分支覆蓋」強,因為它使一個判定中的每一個條件都取到了兩個不同的結果,而判定覆蓋則不保證這一點。
缺點:「條件覆蓋」並不包含「分支覆蓋」,如兩個用例沒有有覆蓋判定(A>1 and B=0)為True的情況
4.1.4 判定/條件覆蓋
程序1,以下用例是滿足判定/條件覆蓋:
- A=2,B=0,X=4 (沿ace路徑)
- A=1,B=1,X=1 (沿abd路徑)
優點:既有「條件覆蓋」,又有「判定覆蓋」
缺點:分支/條件覆蓋從表面來看,它測試了所有條件的取值,但是實際上某些條件掩蓋了另一些條件。
- 對於第一個表達式(A>1 and B=0)如果(A>1)為假則一般的編譯器不在判斷是否B=0了。
- 對於第二個表達式(A=2 or X>1)來說,若A=2測試結果為真,就認為表達式的結果為真,這時不再檢查(X>1)條件了。
因此,採用分支/條件覆蓋,邏輯表達式中的錯誤不一定能夠查出來了。
4.1.5 條件組合覆蓋
程序1,以下用例是滿足條件組合覆蓋:
再看程序1,我們需要選擇適當的用例,使得下面 8種條件組合都能夠出現:
1) A>1, B=0 2) A>1, B≠0 3) A≤1, B=0 4) A≤1, B≠0
5) A=2, X>1 6) A=2, X≤1 7) A≠2, X>1 8) A≠2, X≤1
5) 、6) 、7)、8)四種情況是第二個 IF語句的條件組合,而X的值在該語句之前是要經過計算的,所以還必須根據程序的邏輯推算出在程序的入口點X的輸入值應是什麼。
下面設計的四個用例可以使上述 8種條件組合至少出現一次:
- A=2,B=0,X=4 使 1)、5)兩種情況出現 (沿ace路徑);
- A=2,B=1,X=1 使 2)、6)兩種情況出現 (沿abd路徑);
- A=1,B=0,X=2 使 3)、7)兩種情況出現 (沿abe路徑);
- A=1,B=1,X=1 使 4)、8)兩種情況出現 (沿abd路徑)。
優點:既有「條件覆蓋」,又有「判定覆蓋」,還有「條件組合覆蓋」
缺點:上面四個例子雖然滿足條件組合覆蓋,但並不能覆蓋程序中的每一條路徑,例如路徑acd就沒有執行
4.1.6 黑盒法補充測試用例
通過前面邏輯驅動測試方法,可以得到兩點結論:
- 「條件組合覆蓋」標準比其他標準優越。
- 即使達到任何一種覆蓋標準,其測試效果仍然是不徹底的,我們還需要用其他的測試方法作補充。
一個參考的黑盒法補充策略是:
1) 在任何情況下都需使用邊界值分析(這個方法應包括對輸入和輸出的邊界值進行分析)。
2) 必要的話,再用等價分類法補充一些測試用例。
3) 再用錯誤推測法附加測試用例。
4) 檢查上述例子的邏輯覆蓋程度,如果未能滿足某些覆蓋標準,則再增加足夠的測試用例。
5) 如果功能說明中含有輸入條件的組合情況,則一開始就可先用因果圖(判定表)法。
4.2 路徑測試
路徑測試就是設計足夠多的測試用例,覆蓋被測試對象中的所有可能路徑。
4.2.1 基本路徑測試
程序1是很簡單的程序函數,只有四條路徑。但在實踐中,一個不太複雜的程序,其路徑都是一個龐大的數字,要在測試中覆蓋所有的路徑是不現實的。為了解決這一難題,只得把覆蓋的路徑數壓縮到一定限度內,例如,程序中的循環體只執行一次。
基本路徑測試就是這樣一種測試方法,它在程序控制圖的基礎上,通過分析控制構造的環行複雜性,導出基本可執行路徑集合,從而設計測試用例的方法。設計出的測試用例要保證在測試中程序的每一個可執行語句至少執行一次。
在程序控制流圖的基礎上,通過分析控制構造的環路複雜性,導出基本可執行路徑集合,從而設計測試用例。包括以下4個步驟和一個工具方法:
- 程序的控制流圖:描述程序控制流的一種圖示方法。
- 程序圈複雜度:McCabe複雜性度量。從程序的環路複雜性可導出程序基本路徑集合中的獨立路徑條數,這是確定程序中每個可執行語句至少執行一次所必須的測試用例數目的上界。
- 導出測試用例:根據圈複雜度和程序結構設計用例數據輸入和預期結果。
- 準備測試用例:確保基本路徑集中的每一條路徑的執行。
工具方法:
- 圖形矩陣:是在基本路徑測試中起輔助作用的軟體工具,利用它可以實現自動地確定一個基本路徑集。
1) 控制流圖
在介紹基本路徑方法之前,必須先介紹一種簡單的控制流表示方法,即流圖。流圖是對待測試程序過程處理的一種表示。流圖使用下面的符號描述邏輯控制流,每一種結構化構成元素有一個相應的流圖符號。
圖3 流圖符號
流圖只有二種圖形符號
- 圖中的每一個圓稱為流圖的結點,代表一條或多條語句。
- 流圖中的箭頭稱為邊或連接,代表控制流。
任何過程設計都要被翻譯成控制流圖。
在將程序流程圖簡化成控制流圖時,應注意:
- 在選擇或多分支結構中,分支的匯聚處應有一個匯聚結點。
- 邊和結點圈定的區域叫做區域,當對區域計數時,圖形外的區域也應記為一個區域。
圖4 控制流圖
如果判斷中的條件表達式是由一個或多個邏輯運算符 (OR, AND) 連接的複合條件表達式,則需要改為一系列只有單條件的嵌套的判斷。
圖5 程序結構轉化成流圖
2) 獨立路徑
獨立路徑:至少沿一條新的邊移動的路徑
圖6 獨立路徑
對以上路徑的遍歷,就是至少一次地執行了程序中的所有語句
3) 基本路徑測試
第一步:畫出控制流圖
流程圖用來描述程序控制結構。可將流程圖映射到一個相應的流圖(假設流程圖的菱形決定框中不包含複合條件)。
- 流圖中圓,稱為流圖的結點,代表一個或多個語句。一個處理方框序列和一個菱形決測框可被映射為一個結點;
- 流圖中的箭頭,稱為邊或連接,代表控制流,類似於流程圖中的箭頭。一條邊必須終止於一個結點,即使該結點並不代表任何語句(例如:if-else-then結構);
- 由邊和結點限定的範圍稱為區域。計算區域時應包括圖外部的範圍。
圖7 程序流程圖
圖8 程序流程圖和對應的控制流圖
第二步:計算圈複雜度
圈複雜度是一種為程序邏輯複雜性提供定量測度的軟體度量,將該度量用於計算程序的基本的獨立路徑數目,為確保所有語句至少執行一次的測試數量的上界。
獨立路徑必須包含一條在定義之前不曾用到的邊。
有以下三種方法計算圈複雜度:
- 流圖中區域的數量對應於環型的複雜性;
- 給定流圖G的圈複雜度V(G),定義為V(G)=E-N+2,E是流圖中邊的數量,N是流圖中結點的數量;
- 給定流圖G的圈複雜度V(G),定義為V(G)=P+1,P是流圖G中判定結點的數量。
第三步:導出測試用例
根據上面的計算方法,可得出四個獨立的路徑。(一條獨立路徑是指,和其他的獨立路徑相比,至少引入一個新處理語句或一個新判斷的程序通路。V(G)值正好等於該程序的獨立路徑的條數。)
- 路徑1:4-14
- 路徑2:4-6-7-14
- 路徑3:4-6-8-10-13-4-14
- 路徑4:4-6-8-11-13-4-14
第四步:準備測試用例
為了確保基本路徑集中的每一條路徑的執行,根據判斷結點給出的條件,選擇適當的數據以保證某一條路徑可以被測試到,滿足上面例子基本路徑集的測試用例是:
路徑1:4-14
輸入數據:iRecordNum=0,或者取iRecordNum<0的某一個值 預期結果:x=0
路徑2:4-6-7-14
輸入數據:iRecordNum=1,iType=0 預期結果:x=2
路徑3:4-6-8-10-13-4-14
輸入數據:iRecordNum=1,iType=1 預期結果:x=10
路徑4:4-6-8-11-13-4-14
輸入數據:iRecordNum=1,iType=2 預期結果:x=20
必須注意,一些獨立的路徑,往往不是完全孤立的,有時它是程序正常的控制流的一部分,這時,這些路徑的測試可以是另一條路徑測試的一部分。
4) 工具方法:圖形矩陣
導出控制流圖和決定基本測試路徑的過程均需要機械化,為了開發輔助基本路徑測試的軟體工具,稱為圖形矩陣(graph matrix)的數據結構很有用。
利用圖形矩陣可以實現自動地確定一個基本路徑集。一個圖形矩陣是一個方陣
- 其行/列數控制流圖中的結點數,每行和每列依次對應到一個被標識的結點,
- 矩陣元素對應到結點間的連接(即邊)。
對每個矩陣項加入連接權值(link weight),圖矩陣就可以用於在測試中評估程序的控制結構,連接權值為控制流提供了另外的信息。最簡單情況下,連接權值是 1(存在連接)或0(不存在連接),但是,連接權值可以賦予更有趣的屬性:
- 執行連接(邊)的概率。
- 穿越連接的處理時間。
- 穿越連接時所需的內存。
- 穿越連接時所需的資源。
感謝每一個認真閱讀我文章的人!!!
如果下面這些資料用得到的話可以直接拿走:
1、自學開發或者測試必備的完整項目源碼與環境
2、測試工作中所有模板(測試計劃、測試用例、測試報告等)
3、軟體測試經典面試題
4、Python/Java自動化測試實戰.pdf
5、Jmeter/postman接口測試全套視頻獲取
我個人整理了我這幾年軟體測試生涯整理的一些技術資料,包含:電子書,簡歷模塊,各種工作模板,面試寶典,自學項目等。如果在學習或工作中遇到問題可以直接進群詢問,群里也會有大神幫忙解答,需要的可以評論區找我呀。