if(map->Search(&pData->name))
return 0;
map->Add(pData);
return 1;
}
參數PERSON* pData是結構指針,記錄一個“人”的資料,結構PERSON含有一個字符串成員name,記錄“人”的名字。參數CPersonMap2* map是一個映射表,以名字為key保存PERSON的對象指針。代碼很簡單,當名字已在表中存在時,直接返回0,否則保存到映射表。測試時要使map->Search(&pData->name)返回true,一般的方法是在表中預先加入相應的數據,這可能很麻煩,如果能直接讓map->Search(&pData->name)返回true,既簡單又直接。
難于設定的內部輸入非常常見,尤其是測試比較高層的函數,很多輸入都是比較復雜但其目的只是傳遞給底層函數以獲得一個簡單的內部輸入,如果我們轉換思路,想辦法直接設定內部輸入,工作將會大量減少。
靜態變量形成的內部輸入
除調用底層函數形成內部輸入外,局部靜態變量也會形成內部輸入。請看下面的代碼(代碼清單4.6.cpp):
/*
函數說明:
功能: 游戲程序中用于計算打擊效果的代碼片斷,連續打擊時
效果隨次數遞減
參數: reset, 輸入參數,為true時重置打擊次數
返回: int類型,打擊效果
*/
int PowerEffect(bool reset)
{
//打擊次數,由于是局部變量,用例中無法訪問,難于測試
static int times = 0;
if(reset) times = 0;
times++;
int effect[] = {9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
if(times >= sizeof(effect) / sizeof(effect[0]))
return 0;
return effect[times];
}
打擊次數times是一個局部靜態變量,局部變量無法外部訪問,這給測試造成了困難。這個示例中,打擊次數只是簡單遞加,還有可能通過適當排列用例,或插入若干前置調用來控制它的值,但在實際項目中,未必那么簡單,因此,局部靜態變量也是一種必須解決的內部輸入。
前面列出了內部輸入的五種情形,后四種是影響單元測試能否順利實施的關鍵難點。有問題并不可怕,可怕的是不知道問題的存在。只有發現和正視問題,才有可能解決問題。有趣的是,有些朋友將內部輸入的問題被歸結為“代碼可測性差”,解決辦法是改良代碼提高可測性,這是典型的“站著說話不腰疼”,有經驗的程序員用腳趾頭想一下,就知道這些問題是大量存在并且多數是不可能消除的。單元測試方法或工具,如果無法解決內部輸入的問題,就無法適應實際項目的測試,這不是代碼的可測性問題,而是方法或工具的可用性問題。
文章來源于領測軟件測試網 http://www.kjueaiud.com/