//調用compare
int Func(int r, int x)
{
int a1 = GetArea(r);
int result = Compare(a1, x);
printf("result %d\n", result);
return result;
}
兩組代碼的差別在對GetArea()的調用是在Compare()之內還是之外。假如我們的測試目標是Comapre(),圓的外接正方形的面積a1在代碼一中通過調用Compare()取得,在代碼二中通過參數傳遞,顯然,兩者之間并無本質區別。Compare()的功能是,計算指定正方形的面積后并與外接正方形面積比較,GetArea()只是一個取得數據的調用,GetArea()本身是否正確,不是我們的測試目標,測試目標在于:對參數輸入和GetArea()的各種輸出是否做了合適的計算,只要這些計算正確,Comapre()就沒有錯誤。因此,從測試角度來看,被測函數調用其他函數(稱為底層函數)所取得的數據,完全可以和通過參數傳遞的數據同等對待,都是一種輸入,稱為內部輸入。
只有深刻理解內部輸入,才能真正理解單元測試。單元測試是針對代碼單元的獨立測試,一個函數,在調用了其他函數的情況下,如何能夠獨立測試?只有把底層函數的輸出,視作被測函數的一種輸入,才能真正進行獨立測試。
把底層函數的輸出視為被測函數的輸入,會不會影響測試效果?當然不會,因為單元測試主要目的就是檢查被測函數的功能邏輯,檢查是否針對各種輸入包括內部輸入做了合適的處理。無論底層函數是否正確或者是否存在,只要被測函數對輸入包括內部輸入的各種可能做了正確的處理,被測函數本身就不會有功能錯誤。
內部輸入是單元測試的關鍵難題。代碼耦合有兩種,虛耦合和實耦合。虛耦合是指沒有調用關系的耦合,例如我們要測試Compare(),這個函數位于一個文件A中,文件A中可能還有很多其他代碼,也可能包含了很多頭文件,雖然這些代碼并沒有被Compare()調用,但是,這些代碼仍然可能造成文件A難于單獨編譯和鏈接,這就是虛耦合,虛耦合一般可以靠簡單打樁解決。實耦合就是調用關系形成的耦合,例如在代碼一中,Comapre()和GetArea()就是實耦合,實耦合又有兩種情況:一是底層函數沒產生被測函數需要使用的輸出,這種情形可以不處置;二是底層函數產生了被測函數需要使用的輸出,成了內部輸入。
內部輸入有以下幾種情形:
自然內部輸入
這是指對底層函數的正常調用即可獲得的內部輸入,前面的示例就屬于自然輸入。代碼一中Compare()函數,int a1 = GetArea(r);可以自然取得外接正方形的面積。如果外接矩形面積a1要得到某個預期的值,要傳遞合適的半徑r。自然輸入有兩個條件:一是底層函數存在,二是底層函數正確。
不可控的內部輸入
是指調用實際代碼,但實際代碼的輸出難于控制,難于把各種可能輸出都測試到。例如,底層函數返回一個隨機數,就是不可控。在實際項目中,不可控是很常見的,下面的代碼是空調控制程序中的一個函數(代碼清單4.3.cpp):
/*
函數說明:
文章來源于領測軟件測試網 http://www.kjueaiud.com/