在軟件單元測試時活玲,考慮到軟件單元的所有情況有時是非常困難的拧额。能不能采取一些有效的辦法碘裕,能夠在可接受的單元測試用例數量的前提下,提高測試的有效性呢?本文對常用的單元測試用例設計方法進行介紹柠贤,期待對大家有一定的借鑒作用香浩。
1、等價類劃分(Equivalence Class Partitioning)
等價類劃分法將程序所有可能的輸入數據和輸出(有效的和無效的)劃分成若干個等價類臼勉,然后從每個等價類中選取具有代表性的數據作為測試用例邻吭,從而保證測試用例具有完整性和代表性。
形成測試區(qū)間的數據不只是函數/過程的參數宴霸,也可以是軟件可以訪問的全局變量囱晴,系統(tǒng)資源等,這些變量或資源可以是以數值瓢谢,也可能是以其他形式存在畸写,如狀態(tài)。
例1:計算絕對值的函數的設計說明如下:
根據輸入和輸出恩闻,可以劃分出如下的2個輸入的等價類和一個輸出的等價類:
針對該例子艺糜,我們可以設計以下2個測試用例:
1)Test Case1:輸入4,返回4幢尚,覆蓋 I1和O1
2)Test Case2:輸入-10,返回10翅楼,覆蓋I2和O1
2尉剩、邊界值分析(Boundary Value Analysis)
通常大量的錯誤發(fā)生在輸入或輸出范圍的邊界上,而不是發(fā)生在輸入輸出范圍的內部毅臊。
邊界值分析法是對輸入或輸出的邊界值進行測試的一種方法理茎,通常邊界值分析法是作為對等價類劃分法的補充,此時的測試用例通常來自等價類的邊界管嬉。
如例1的絕對值的例子中:
根據邊界值分析方法得出的測試用例有:
Test Case1 :輸入0皂林,返回0
Test Case2 :輸入僅比0大的數,返回輸入的正數
Test Case3 :輸入最大正實數蚯撩,返回輸入的正實數
Test Case4 :輸入僅比0小的數础倍,返回0-輸入的值
Test Case5 :輸入最小的負實數,返回0-輸入的值
3胎挎、基本路徑測試(Basis Path Testing)
基本路徑測試法是在程序控制流圖的基礎上沟启,通過分析控制構造的圈復雜度,導出基本可執(zhí)行路徑集合犹菇,從而設計測試用例的方法德迹。設計出的測試用例能夠保證程序的每個可執(zhí)行語句至少執(zhí)行一次。這種單元測試用例的方法首先要創(chuàng)建出程序的控制流圖揭芍,之后確定程序的圈復雜度胳搞,最后進行測試用例的設計。
3.1 創(chuàng)建出程序的控制流圖
程序的控制流程圖是描述程序控制流的一種圖示方法,與程序流程圖類似肌毅。程序控制流圖只有圓形和箭頭兩種圖形符號币厕。圓形稱為控制流圖的一個結點,表示一個或多個無分支的語句或源程序語句芽腾;箭頭稱為邊或連接旦装,代表控制流。需要注意的是摊滔,在創(chuàng)建程序的控制流圖時阴绢,如果判斷中的條件表達式是由一個或多個邏輯運算符(OR, AND)連接的復合條件表達式,則需要改為一系列只有單條件的嵌套的判斷艰躺。
如下面代碼的控制流圖:
3.2 計算圈復雜度
圈復雜度是一種度量程序邏輯復雜性的軟件度量指標呻袭,是程序的基本的獨立路徑數目,即為確保所有語句至少執(zhí)行一次的測試數量腺兴。根據程序控制流圖有以下三種計算方法:
a) 控制流圖中封閉區(qū)域的數量左电,其中圖所在的平面認為是一個區(qū)域
上圖的圈復雜度為3 (區(qū)域中的藍色部分)
b) 控制流圖中邊的數量減去結點數量+2
V(G) = E – N + 2
上圖中,圈復雜度為? : 7-6+2 = 3
c) 控制流圖中判定結點的數量+1
V(G) = P + 1
其中P為控制流圖中判定結點的數量
上圖判定結點為2個页响,因此圈復雜度為3
3.3 編寫測試用例
根據圈復雜度計算結果和程序控制流圖篓足,得出獨立路徑數和相應的獨立路徑。根據獨立的路徑闰蚕,分別設計輸入條件數據栈拖,使程序分別執(zhí)行到所有獨立路徑,即可得到相應的測試用例没陡。
如之前的數據流圖涩哟,根據圈復雜度,得出有3個獨立的路徑盼玄,根據相應的獨立路徑贴彼,分別設計輸入條件,則可以確定3個測試用例:
Test Case1 :
執(zhí)行路徑: 1-2-6
輸入條件: C1 = 11? 埃儿;? C2任意
Test Case2 :
執(zhí)行路徑: 1-3-4-6
輸入條件: C1 = 8器仗,? C2 = 8
Test Case3 :
執(zhí)行路徑: 1-3-5-6
輸入條件: C1 = 8,? C2 = 12
4蝌箍、基于測試覆蓋度的測試用例設計
單元測試中青灼,經常還提到一個測試覆蓋度的概念,比如語句覆蓋妓盲、分支覆蓋等杂拨,也是一種單元測試用例的設計方法。具體可以參見楊老師的文章:談談測試覆蓋度悯衬,在此不在贅述弹沽。
5檀夹、軟件設計說明導出的測試(Specification derived test)
我們按照以上所有的方法都進行了單元測試用例,我們的代碼就沒有問題了嗎策橘?我們看下圖的例子炸渡。
我們應用了所有上面提及的單元用例設計方法,但是可能仍然不能發(fā)現例子中的除以0的問題丽已。因為我們之前的測試用例設計方法更多關注的是程序中的判斷表達式及表達式中的條件蚌堵,即是否所有代碼都執(zhí)行過,而不是所有代碼都正確的執(zhí)行沛婴。所以吼畏,我們通常說的代碼覆蓋度實際上也被稱為代碼的結構覆蓋度(Structural coverage),而不是需求邏輯的覆蓋嘁灯。
因此泻蚊,我們還需要考慮從需求/規(guī)格方面考慮的用例設計方法。對于單元測試來說丑婿,規(guī)格就是詳細設計性雄。
軟件設計說明導出的測試用例,就是通過根據相關的軟件設計說明文檔進行設計羹奉,每個測試用例測試設計說明中一項或多項陳述秒旋。
如例1中,設計說明中有2個陳述尘奏,可以用以下2個測試用例來對應滩褥。
Test Case 1:輸入4,返回4炫加。? // 對應第一個陳述
Test Case 2:輸入-10,返回10 // 對應第二個陳述
例1:計算數的絕對值的函數的設計說明如下:
6铺然、錯誤猜測 (Error Guessing)
錯誤猜測法就是根據經驗猜想可能的錯誤俗孝,并依此設計測試用例的方法。錯誤猜測法只能作為測試設計的補充而不能單獨用來設計測試用例魄健,否則可能會造成測試的不充分赋铝。
錯誤猜測法的基本思路:
列舉出程序中所有可能有的錯誤和容易發(fā)生錯誤的特殊情況,根據他們選擇測試用例,例如在單元測試時許多在模塊中常見的錯誤或以前產品測試中曾經發(fā)現的錯誤等沽瘦。
如之前的被除數為零的例子的情況革骨。測試人員會根據算法中有除法運算,那么就可以推測出析恋,至少需要考慮是否存在被除數為零的情況良哲。
雖然說了這么多的測試用例設計方法,但這并不是所有助隧。針對測試內容的不同筑凫,可能還會有一些測試用例設計方法,如狀態(tài)轉換測試(State-transition Testing)等,這些測試用例設計方法適用于不同的情況下的測試巍实,因此在這里不在介紹滓技。
我們給出了這么多的測試用例設計方法,實際使用時棚潦,需要根據自己項目的情況選用恰當的方法進行測試用例的開發(fā)令漂。實際上,組合使用各種測試用例設計方法時丸边,所設計出的測試用例是存在重復的情況叠必,因此我們在進行單元測試用例設計時,還要恰當的去重原环。那么挠唆,整個單元測試用例設計的過程到底是什么樣的呢?通常的流程如下嘱吗,供大家參考:
1) 確定單元測試的策略
2) 設計正面測試(Positive Testing)測試用例
3) 設計負面測試(Negative Testing)測試用例
4) 設計覆蓋率測試用例玄组,使測試用例滿足預定的覆蓋度要求
5) 設計需求中其他測試特性測試用例
6) 最后在測試執(zhí)行后,可能會需要對測試用例進行調整谒麦、補充俄讹,如測試覆蓋度沒有達到預期目標時