這里提出用“三步法”盡可能實現完整測試:
第一步:基本功能測試
程序的功能是人為的規定,工具不可能自動了解,因此,針對基本功能的測試用例需要人工來建立,這是無可躲避的。根據程序的設計要求,基本功能用例通常不難設計,把程序功能細化、明確化,列成“什么輸入,應產生什么輸出”的形式,就是測試用例。程序員準備編碼時和編碼過程中,是建立基本功能用例的最佳時機,為什么呢?因為程序員編碼之前和編碼過程中,一定要弄明白程序的功能,也就是要想清楚“會有哪些輸入?某種輸入時程序應該做什么?產生什么結果?”,這里,“哪些輸入”就是指有哪些等價類,產生的“結果”就是輸出,從編碼的角度來看,這些就是程序的功能點,從測試的角度來看,這些就是現成的用例。如果有詳細設計文檔,那么測試人員可以根據文檔來設計用例,否則最好由程序員建立基本功能用例。這一步可視為“黑盒方法”。
第二步:用白盒方法找出遺漏用例
正因為程序功能是人為的規定,“黑盒方法”很難衡量完整性,而“白盒方法”恰恰具有易于衡量測試完整性的優點,兩者可以很好互補,請看下面的示例代碼:
void Func(int* p)
{
if(p)
{
*p = 0;
}
else
{
return;
}
}
參數p是一個指針,測試時當然要將空指針作為一個等價類,如果漏了這個等價類,會怎么樣呢?分支覆蓋會不完整:else分支未覆蓋。從這個例子可以看出,未覆蓋的邏輯單位通常對應未測試的等價類,因此,白盒覆蓋可以衡量等價類是否完整并可幫助找出遺漏的用例。
“白盒方法”用邏輯覆蓋率來衡量測試的完整性。邏輯單位主要有:語句、分支、條件、條件值、條件值組合,路徑。語句覆蓋就是覆蓋所有的語句,其他類推。還有一種判定條件覆蓋,其實是分支覆蓋與條件覆蓋的組合。跟條件有關的覆蓋就有三種:條件覆蓋是指覆蓋所有的條件表達式,即所有的條件表達式都至少計算一次,不考慮計算結果;條件值覆蓋是指覆蓋條件的所有可能取值,即每個條件的取真值和取假值都要至少計算一次;條件值組合覆蓋是指覆蓋所有條件取值的所有可能組合。與條件直接有關的錯誤主要是邏輯操作符錯誤,例如:||寫成&&,漏了寫!什么的,采用分支覆蓋與條件覆蓋的組合,基本上可以發現這些錯誤,另一方面,條件值覆蓋與條件值組合覆蓋往往需要大量的測試用例,因此,這兩種覆蓋的效費比偏低。基于以上理由,這里提出采用語句、條件、分支、路徑覆蓋的組合來衡量測試完整性和找出遺漏用例。
第三步:用自動用例捕捉漏網之魚
還是上面的例子,假如程序員完全忘了有空指針這回事,把代碼寫成這樣:
void Func(int* p)
{
*p = 0;
}
由于判斷p是否為空指針的代碼不存在,白盒覆蓋當然不會提示“某某代碼或某某分支未覆蓋”,因此,白盒覆蓋不能發現“程序員未處理某些特殊輸入”形成的錯誤,即使達到了無與倫比的白盒覆蓋率,仍然不能保證找出所有等價類。
程序員會忘記處理哪些輸入呢?常見的輸入一般是不會記的,否則程序的起碼功能都未實現,容易忘記的是一些"偏僻"的輸入,例如,空指針、空字符串、很大的數、很小的數、合法取值邊界附近的值等等,從輸入的角度來看,這些特殊值通常跟數據類型有關,從程序的行為來看,這些特殊輸入常常會導致崩潰、產生異常,或超時,即具有行為特征,正好是自動用例可以發現的,因此,可以利用自動用例來捕捉“程序員未處理某些特殊輸入”形成的錯誤。這就是“三步法”中的第三步。
新聞熱點
疑難解答