類所實現的功能,都是通過類的成員函數執行。在測試類的功能實現時,應該首先保證類成員函數的正確性。單獨的看待類的成員函數,與面向過程程序中的函數或過程沒有本質的區別,幾乎所有傳統的單元測試中所使用的方法,都可在面向對象的單元測試中使用。具體的測試方法在面向對象的單元測試中介紹。類函數成員的正確行為只是類能夠實現要求的功能的基礎,類成員函數間的作用和類之間的服務調用是單元測試無法確定的。因此,需要進行面向對象的集成測試。具體的測試方法在面向對象的集成測試中介紹。需要著重聲明,測試類的功能,不能僅滿足于代碼能無錯運行或被測試類能提供的功能無錯,應該以所做的OOD結果為依據,檢測類提供的功能是否滿足設計的要求,是否有缺陷。必要時(如通過OOD結仍不清楚明確的地方)還應該參照OOA的結果,以之為最終標準。
六 面向對象的單元測試(OO Unit Test)
傳統的單元測試是針對程序的函數、過程或完成某一定功能的程序塊。沿用單元測試的概念,實際測試類成員函數。一些傳統的測試方法在面向對象的單元測試中都可以使用。如等價類劃分法,因果圖法,邊值分析法,邏輯覆蓋法,路徑分析法,程序插裝法等等,方法的具體實現參見[6]。單元測試一般建議由程序員完成。
用于單元級測試進行的測試分析(提出相應的測試要求)和測試用例(選擇適當的輸入,達到測試要求),規模和難度等均遠小于后面將介紹的對整個系統的測試分析和測試用例,而且強調對語句應該有100%的執行代碼覆蓋率。在設計測試用例選擇輸入數據時,可以基于以下兩個假設:
1. 如果函數(程序)對某一類輸入中的一個數據正確執行,對同類中的其他輸入也能正確執行。
2. 如果函數(程序)對某一復雜度的輸入正確執行,對更高復雜度的輸入也能正確執行。例如需要選擇字符串作為輸入時,基于本假設,就無須計較于字符串的長度。除非字符串的長度是要求固定的,如IP地址字符串。在面向對象程序中,類成員函數通常都很小,功能單一,函數的間調用頻繁,容易出現一些不宜發現的錯誤。例如: · if (-1==write (fid, buffer, amount)) error_out();
該語句沒有全面檢查write()的返回值,無意中斷然假設了只有數據被完全寫入和沒有寫入兩種情況。當測試也忽略了數據部分寫入的情況,就給程序遺留了隱患。
· 按程序的設計,使用函數strrchr()查找最后的匹配字符,但誤程序中寫成了函數strchr(),使程序功能實現時查找的是第一個匹配字符。
· 程序中將if (strncmp(str1,str2,strlen(str1)))誤寫成了if (strncmp(str1,str2,strlen(str2)))。如果測試用例中使用的數據str1和str2長度一樣,就無法檢測出。 因此,在做測試分析和設計測試用例時,應該注意面向對象程序的這個特點,仔細的進行測試分析和設計測試用例,尤其是針對以函數返回值作為條件判斷選擇,字符串操作等情況。
面向對象編程的特性使得對成員函數的測試,又不完全等同于傳統的函數或過程測試。尤其是繼承特性和多態特性,使子類繼承或過載的父類成員函數出現了傳統測試中未遇見的問題。在[7]中,Brian Marick 給出了二方面的考慮:
1. 繼承的成員函數是否都不需要測試?
根據[7]中的論述,對父類中已經測試過的成員函數,兩種情況需要在子類中重新測試:a)繼承的成員函數在子類中做了改動;b)成員函數調用了改動過的成員函數的部分。例如:
假設父類Bass有兩個成員函數:Inherited()和Redefined(),子類Derived只對Redefined()做了改動! erived::Redefined()顯然需要重新測試。對于Derived::Inherited(),如果它有調用Redefined()的語句(如:x=x/Redefined()),就需要重新測試,反之,無此必要。
文章來源于領測軟件測試網 http://www.kjueaiud.com/