由於時間和成本的約束,軟件測試的最關鍵問題是:
在所有可能的測試用例中,哪個子集最有可能發現最多的錯誤
測試方法:
黑盒測試
- 等價類划分(Equivalence Partitioning)
1. 嚴格控制測試用例的增加,減少為達到“合理測試”的某些既定目標而必須設計的其他測試用例的數量
2. 它覆蓋了大部分其他可能的測試用例。
划分了等價類后,就可以說,如果對該集合中某個元素所進行的測試沒有發現錯誤的話,那么對該集合中其他元素所進行的測試也不大可能會發現錯誤。
使用等價類划分方法設計測試用例主要有兩個步驟:(1)確定等價類; (2)生成測試用例
(1)確定等價類
外部條件,有效等價類(代表對程序的有效輸入),無效等價類(其他任何可能的輸入條件-即不正確的輸入值)
確定等價類大體上是一個啟發式的過程,一些指導原則:
- 如果輸入條件規定了一個取值范圍(eg. “數量可以是從1到99”),那么就應確定出一個有效等價類(1<數量<99),以及兩個無效等價類(數量<1, 數量>99)
- 如果輸入條件規定了取值個數(eg. “汽車可登記一至六名車主”),那么就應確定出一個有效等價類和兩個無效等價類(沒有車主,或車主對於六個)
- 如果輸入條件規定了一個輸入值的集合,而且有理由認為程序會對每個值進行不同的處理(eg. “交通工具的類型必須是公共汽車、卡車、出租車、火車或摩托車”),那么就應為每個輸入值確定一個有效等價類和一個無效等價類(eg. 拖車)
- 如果存在輸入條件規定了“必須是”的情況(eg. “標識符的第一個字符必須是字母”), 那么就應確定一個有效等價類(首字符是字母)和一個無效等價類(首字符不是字母)
(2)生成測試用例
使用等價類來生成測試用例的過程:
- 為每個等價類設置一個不同的編號
- 編寫新的測試用例,盡可能多地覆蓋那些尚未被涵蓋的有效等價類,知道所有的有效等價類都被測試用例所覆蓋
- 編寫新的用例,覆蓋一個且僅一個尚未被覆蓋的無效等價類,直到所有的無效等價類都被測試用例覆蓋: 用單個測試用例覆蓋無效等價類,是因為某些特定的輸入錯誤檢查可能會屏蔽或取代其他輸入錯誤檢查。
- 邊界值分析(Bondary-Value Analysis)
所謂邊界條件,是指輸入和輸出等價類中那些恰好處於邊界、或超過邊界、或在邊界以下的狀態。
- 因果圖分析(Cause-Effect Graphing)
生成測試用例時采用的過程:
-
- 將規格說明分解為可執行的片段
- 確定規格說明中的因果關系。所謂因,是指一個明確的輸入條件或輸入條件的等價類。所謂果,是指一個輸出條件或系統轉換。
- 分析規格說明的語義內容,並將其轉換為連接因果關系的布爾圖。這就是所謂的因果圖
- 給圖加上注解符號,說明由於語法或環境的限制而不能聯系起來的因和果
- 通過仔細地跟蹤圖中的狀態變化情況,將因果圖轉換成一個有限項的判定表。表中的每一列代表一個測試用例
- 將判定表中的列轉換成測試用例
因果圖中的基本符號:
設想一下,每個結點的值為0或為1,0表示“不存在”狀態, 1 表示“存在” 狀態。identity函數表示,如果a等於1,則b也是1,否則b為0. not函數表示如果a等於1,則b為0,否則b為1.Or函數表示如果a或b或c等於1,則d為1,否則d為0。 and函數表示如果a和b都等於1,則c為1,否則c為0.
- 錯誤猜測(Error Guessing)
白盒測試(White-Box Testing)
- 語句覆蓋
- 度量被測代碼中每個可執行語句是否被執行到了。
-
int foo(int x, int y) { return x / y; }
測試用例,x=10, y=5.
- 測試人員的測試結果會告訴你,代碼覆蓋率達到了100%,並且所有測試案例都通過了。然而遺憾的是,卻沒有發現最簡單的bug,比如,讓y=0時,會拋出一個除零異常。
- 判定覆蓋
- 該准則要求必須編寫足夠的測試用例,使得每一個判斷都至少有一個為“真”和為“假”的輸出結果, 並且每條語句都至少被執行一次。換句話說,即每個判斷都必須有“是”和“否”的結果,且每個入口點都必須至少被調用一次。
- 條件覆蓋
- 在條件覆蓋情況下,要編寫足夠的測試用例以確保將一個判斷中的每個條件的所有可能的結果至少執行一次,且每個入口點都必須至少被調用一次。
- 判定/條件覆蓋
- 將一個判斷中的每個條件的所有可能的結果至少執行一次,將每個判斷的每個條件的所有可能的結果至少執行一次,將每個判斷的所有可能的結果至少執行一次,將每個入口點都至少調用一次。
- 多重條件覆蓋
- 該准則要求編寫足夠多的測試用例,將每個判定中的所有可能的條件結果的組合,以及所有入口點都至少執行一次。
- 其中的原因是“與”和“或”表達式中某些條件的結果可能會屏蔽或阻礙其他條件的判讀。舉例來說,如果“與”表達式中有個條件為“假”,那么就無須計算該表達式中的后續條件。
public void foo(int a, int b, int x) { if (a > 1 && b == 0) { x = x / a; } if (a == 2 || x > 1) { x = x + 1; } }
- 語句覆蓋: ace - A=2, B=0, X=3
- 判定覆蓋:acd, abe - A=3, B=0, X=3; A=2, B=1, X=1
- 條件覆蓋:abe - A=2, B=0, X=3; A=1, B=1, X=1
- 多重條件覆蓋:測試用例必須覆蓋一下8中組合
- A>1, B=0
- A>1, B<>0
- A<=1, B=0
- A<=1, B<>0
- A=2, X>1
- A=2, X<=1
- A<>2, X>1
- A<>2, X<=1
- A=3, B=0, X=4
- A=2, B=1, X=1
- A=1, B=0, X=2
- A=1, B=1, X=1
測試策略:
1. 如果規格說明中包含輸入條件組合的情況,應首先使用因果圖分析方法
2. 在任何情況下都應使用邊界值分析方法。對輸入和輸出邊界進行的分析
3. 應為輸入和輸出確定有效和無效等價類,在必要情況下對上面確認的測試用例進行補充
4. 使用錯誤猜測技術增加更多的測試用例
5. 針對上述測試用例集檢查程序的邏輯結構。應使用判定覆蓋、條件覆蓋、判定/條件覆蓋或多重條件覆蓋准則。