問題:
int IsLeap(int year)
{
if (year % 4 == 0)
{
if (year % 100 == 0)
{
if (year % 400 ==0)
leap = 1;
else
leap = 0;
}
else
leap = 1;
}
else
leap = 0;
return leap;
}
回答:
純粹從白盒角度來設計用例,是方向性的錯誤,這是缺少實踐的書本和專家的誤導。這叫跟著代碼走,費力不討好。
程序中的錯誤,根據產生原因可分為兩類:代碼錯誤和代碼缺失。代碼缺失是程序員未考慮到某些輸入,未編寫對應代碼形成的。白盒覆蓋基于現有代碼,無法發現這種錯誤。那么,白盒覆蓋是否能發現前一種錯誤?未必!用例必須根據程序功能設定正確的預期輸出,否則再高的白盒覆蓋也沒有意義。也就是說,程序的設計功能是用例設計工作中繞不過去的,是一切的基礎。既然如此,為什么要純粹從白盒角度來設計用例?我認為,類似基路徑法之類的純白盒方法都是應該拋棄的,效率低下不說,既不能發現代碼缺失錯誤,也容易造成忽略程序設計功能這個測試的根本依據。
白盒方法的價值在于衡量對既有代碼的測試完整性,也可以根據白盒覆蓋找出遺漏的用例,這些價值也是建立在用例是基于功能來設計、設定了必要的預期輸出的基礎上的。
所以,正確的方法應該是:首先根據功能來設計用例,并將數據集中起來,從“有哪些正常輸入?有哪些邊界輸入?有哪些非法輸入”三個角度檢查完整性,這樣可以有效發現代碼缺失錯誤。然后,再統計白盒覆蓋,根據未覆蓋的邏輯單位,找出遺漏用例,實現高覆蓋,新加的用例也要根據設計功能設定必要的預期輸出。這樣做,即避免了掉入“跟著代碼走”的陷阱,白盒方法也不用起頭做起,效率高得多。
下面我就樓主提供的代碼演示一下:
首先根據設計功能:計算某一年是否為潤年,設計了幾個用例:
這里輸入只有一個參數,表格中容易檢查,對于多個輸入的代碼來說,應該把數據進一步集中檢查,除了檢查每個參數或其他輸入的取值,必要時還要檢查這些值的組合:
接下來,再查看白盒覆蓋率,代碼中,紅色帶背景的語句未覆蓋,[F]表示條件的取假值未覆蓋,[T]表示取真值未覆蓋,[M]表示MC/DC未覆蓋;邏輯結構圖中,紅色的分支未覆蓋,未覆蓋路徑用紅色畫出。
然后,選中未覆蓋的語句,使用用例設計器,找出對應的遺漏用例,根據提示,year%4==0,這是不能破壞的,year%100!=0,這是我們要滿足的,那么,把year的值改為1996(當然也可以是滿足條件的其他值)就OK了:
執行測試后,所有覆蓋都已完成,包括:語句覆蓋、分支覆蓋、路徑覆蓋、條件覆蓋、判定條件覆蓋(C/DC)、修正判定條件覆蓋(MC/DC)。
這比純粹從白盒角度來設計用例效率高多了吧?最重要的是,避免了“跟著代碼走”陷阱。以上用的是Visual Unit 2.6,用別的工具,或者不用工具,道理也是一樣的。