軟件測試|動態測試技術

動態測試是指通過運行代碼來觀察代碼運行狀況,利用查看代碼和實現方法得到的信息來確定哪些需要測試、哪些不需要測試、如何開展測試,動態測試又稱為結構化測試。常見的動態測試方法有:語句覆蓋、判定覆蓋、條件覆蓋、判定/條件覆蓋、路徑覆蓋和基本路徑覆蓋。

以如圖10-8 所示的程序流程圖為例,對動態測試技術進行分析。

軟件測試|動態測試技術

一、語句覆蓋

語句覆蓋是指在測試過程中,設計若干個測試用例,然後運行被測試程序,保證程序中每條可執行的語句至少被執行一次。若干個測試用例是指使用最小的測試用例數來覆蓋所有的執行語句。

如圖10-8 所示的程序流程圖,只要設計一個測試用例即可,執行的路徑為acdfg。

測試用例:iLoop=9,szT= "/*",bIs=T;

語句覆蓋的優點如下:

(1)能夠檢查所有語句。

(2)結構簡單的代碼的測試效果較好。

(3)容易實現自動測試。

(4)代碼覆蓋率比較高。

(5)如果是程序塊覆蓋,則不涉及程序塊中的源代碼。

上面的實例中看似每條語句都被執行了一次,但依然存在問題,語句覆蓋無法測試到以下幾個方面的內容:

(1)條件語句中邏輯運算符的正確性無法測試。

如實例中的第二個判斷條件szT== "/*"&&bIs==T,如果將該測試用例更改為szT=="a"&&bIs==F,那麼同樣會執行路徑acde,如果程序中錯誤地將邏輯條件“與”寫成了“或”,是無法測試出錯誤的。

(2)循環次數錯誤、跳出循環條件錯誤。

如實例中的第一個判斷條件程序錯誤地寫成了iLoop<=10,那麼執行第一個測試用例還是無法測試出錯誤。

(3)語句覆蓋率高並不代表測試很全面。

如下面的代碼,執行x=2 的測試用例,測試結果語句的覆蓋率達到99%,但是程序中一個重要的分支沒有被測試到,存在嚴重的缺陷。

軟件測試|動態測試技術

二、判定覆蓋

判定覆蓋是指設計若干測試用例,運行被測程序,使程序中每個判斷的取真分支和取假分支至少經歷一次,即判斷的真假值均被滿足。判定覆蓋又稱為分支覆蓋。

如圖10-8 所示的程序流程圖,只要設計三個測試用例即可,執行的路徑分別為ab、acde 和acdfg。

測試用例1:iLoop=11;

測試用例2:iLoop=9,szT= "/*",bIs=F;

測試用例3:iLoop=9,szT= "/*",bIs=T;

可以看出,這三個測試用例不僅滿足判定覆蓋還滿足語句覆蓋,所以其實判定覆蓋是語句覆蓋的一種增強版形式。因此語句覆蓋存在的缺點在判定覆蓋中依然存在,具體的缺點如下:

(1)條件語句中邏輯運算符的正確性無法測試。

(2)循環次數錯誤無法測試。

(3)跳出循環條件錯誤無法測試。

三、條件覆蓋

條件覆蓋是指設計若干測試用例,執行被測程序以後,確保每個判斷中每個條件的可能取值至少滿足一次。

首先將程序中每個分支中的條件取值情況列出來,如圖10-8 所示的程序流程圖,各分支條件取值和標記見表10-4。

軟件測試|動態測試技術

接著對條件進行組合,保證每個條件的取值至少被執行一次,再根據組合條件寫出測試用例。在本例中只要兩個測試用例即可覆蓋到每個條件的取值情況。

軟件測試|動態測試技術

那麼條件覆蓋一定會滿足分支覆蓋嗎?仔細分析表10-5 的測試用例可以發現,有一條分支並沒有被執行,即路徑acdfg。

所以,條件覆蓋的優點是可以檢查所有的條件錯誤;缺點是不能保證每個分支被覆蓋,即不能實現對每個分支的檢查,同時相對於語句覆蓋,測試用例的數量也會增多。所以為了在條件覆蓋的基礎上達到分支覆蓋,必須使用判定/條件覆蓋分析法。

四、判定/條件覆蓋

判定/條件覆蓋是指設計若干個測試用例,然後運行被測程序,使得判斷中每個條件的所有可能至少出現一次,並且每個判斷本身的判定結果也至少出現一次。

首先將程序中每個分支中的條件取值和分支組合的取值情況列出來,如圖10-8 所示的程序流程圖,各分支條件取值和分支組合取值見表10-6。

軟件測試|動態測試技術

接著對條件進行組合,保證每個條件的取值以及每個分支至少被執行一次,再根據組合條件寫出測試用例。在本例中只要兩個測試用例即可覆蓋到每個條件的取值情況,測試用例見表10-7。

軟件測試|動態測試技術

該實例中只要設計三個測試用例即可覆蓋所有分支中的條件檢查和分支檢查,那麼判定/條件覆蓋分析法能覆蓋所有的路徑嗎?答案是肯定的,判定/條件覆蓋分析法並不一定能覆蓋所有路徑的檢查,但該實例中恰好全部覆蓋了所有的路徑。

所以判定/條件覆蓋分析法的優點是既考慮了每個條件的檢查,又考慮了每個分支的檢查,發現錯誤的能力強於單獨的分支覆蓋和條件覆蓋;缺點是判定/條件覆蓋並不能全面覆蓋所有路徑,並且相對前面幾種分析方法,其測試用例數量也有所增加。

五、路徑覆蓋

前面討論的多種覆蓋準則,有的雖提到了所走路徑問題,但尚未涉及到路徑的覆蓋。而路徑能否全面覆蓋在軟件測試中是一個重要問題,因為程序要取得正確的結果,就必須消除遇到的各種障礙,沿著特定的路徑順利執行。只有程序中的每一條路徑都得到測試,才能說程序受到了全面檢驗。

路徑覆蓋是指設計足夠多的測試用例,覆蓋程序中所有可能的路徑。

如圖10-8 所示的程序流程圖,只要設計三個測試用例即可覆蓋所有路徑,測試用例見表10-8。

軟件測試|動態測試技術

路徑覆蓋看似可以完成覆蓋程序中的所有路徑,但對於一個複雜的循環語句,則很難全面覆蓋所有執行路徑。如圖10-9 所示的循環程序,其包含的不同執行路徑條數達520,假定對每一條路徑進行測試需要1 毫秒,一年工作365×24 小時,要想把所有路徑測試完需3170 年。

軟件測試|動態測試技術

所以在實際的測試過程中要做到完全的路徑覆蓋是無法實現的,為解決這一難題,只能把覆蓋的路徑數壓縮到一定限度內。

六、基本路徑覆蓋

基本路徑覆蓋法是指在程序控制流圖的基礎上,通過分析控制結構的環路複雜性,導出基本可執行路徑集合,設計測試用例的方法。該方法把覆蓋的路徑數壓縮到一定限度內,程序中的循環體最多隻執行一次。設計出的測試用例要保證在測試中,程序的每一個可執行語句至少執行一次。基本路徑覆蓋分析法步驟如下:

(1)從詳細設計導出控制流圖。

符號“○”為控制流圖的一個結點,表示一個或多個無分支的源程序語句。箭頭為邊,表示控制流的方向。

常見的順序結構、If 選擇結構、While 重複選擇結構、Until 重複選擇結構和Case 多分支選擇結構控制流圖畫法如圖10-10 所示。

軟件測試|動態測試技術

在選擇或多分支結構中,分支的匯聚處應有一個匯聚結點。邊和結點圈定的區域叫做區域,當對區域計數時,圖形外的區域也應記為一個區域。如果判斷中的條件表達式是由一個或多個邏輯運算符(OR、AND、NAND、NOR)連接的複合條件表達式,則需要改為一系列只有單條件的嵌套的判斷。如圖10-11 所示為程序流程圖與控制流圖的關係。

軟件測試|動態測試技術

(2)確定控制流圖的環形複雜度。

環形複雜度也稱為圈複雜度,它是一種為程序邏輯複雜度提供定量尺度的軟件度量。程序的環形複雜度是指程序基本路徑集中的獨立路徑數量,這是確保程序中每個可執行語句至少執行一次所必需的測試用例數目的上限。獨立路徑是指程序中至少引入了一個新的處理語句集合或一個新條件的程序通路。從控制流圖的角度來說,獨立路徑是指必須至少包含一條在本次定義路徑之前不曾用過的邊。

環形複雜度以圖論為基礎,為我們提供了非常有用的軟件度量。可用如下三種方法來計算環形

複雜度:

第一種方法:計算控制流圖中的區域數量,控制流圖中的區域等於環形複雜度。

第二種方法:給定控制流圖G 的環形複雜度V(G),定義V(G) = E-N+2(其中E 是控制流圖中邊的數量,N 是控制流圖中的結點數量)。

第三種方法:給定控制流圖G 的環形複雜度V(G),也可定義為 V(G) = P+1(其中P 是控制流圖G 中的結點,但該結點至少需要輸出2 條或2 條以上的邊)。

(3)確定獨立路徑的基本集。

(4)導出測試用例,確保基本路徑集中的每一條路徑都被執行。

【實例】使用基本路徑覆蓋法對下面一段程序進行分析,並導出測試用例,被測試代碼如下:

軟件測試|動態測試技術

軟件測試|動態測試技術

軟件測試|動態測試技術

軟件測試|動態測試技術


分享到:


相關文章: