測試為先/測試驅動得好處
傳統的瀑布型軟件開發是先從客戶那里獲得需求,然后進行紙上談兵的設計,接著是程序源碼寫作構建,最后才是測試者對質量進行檢評。從需求的分析到最后的測試,兩者的相隔往往有好幾個月。等到測試發現結構性問題時,重新設計已經成為一個無法完成的任務。設計者程序員已經無法回到幾個月前推翻紙上談兵的錯誤設計,重新用新的方式進行代碼編寫組合。測試為先/測試驅動和瀑布型軟件開發不同是:
以上這些都是我以前重復過的。這些說的容易但是想像起來是比較難一點。我下面所要談到的案例并不是教科書里的完美案例,所謂的完美案例是完全可以自動化,完全可以進行單元測試的程序組件。舉個例子說,想像你要設計一個類來代表“復數”(imaginary number),這樣一個類是可以完全進行自動化單元測試。這種情況只能算得上百分之五十的現實情況,在其他百分之五十的狀況下,一些手動測試和一些自動化測試都是必要的。還有很多情況下,手動測試是唯一的選擇。半自動和手動測試并不代表整個開發不算作測試驅動開發。測試驅動的多數人都會說手動測試和半自動化測試并不能代表團隊在進行測試驅動的開法。我覺得這種說法是偏見,只要測試組和開發組能夠配合,盡可能地在最早時間將用戶需求確定后,讓測試組開始針對用戶需求,設計思路進行測試用例設計,開發和測試能同時進行,開發出的部件能夠迅速進行測試,測試用例能夠經常地運行確保開發的質量不受變化的影響。這就是測試為先/測試驅動的開發。
本文的案例簡介
用來演示測試為先/測試驅動的開發,我將使用我最近設計的一個將應用程序圖標加入System Tray里的類。然后在應用程序退出后,自動將圖標從System Tray里刪除。這樣的類,你如果知道Windows系統對System Tray里的圖標管理,就知道設計這么一個類的自動化測試并不簡單。我覺得這種和圖形界面打交道的類,也沒有必要100%地進行自動化測試。所以我對這個類的測試驅動采取手工測試為主的測試,以測試者甚至開法者本身用用戶的需求,先用例程作為基礎,來設計圖標管理類的單元測試。
案例的用戶需求
我是這個類的唯一用戶,對于我要設計的程序,我的使用是很簡單的。下面的列表就是我的需求:
為了調試圖標的加入和刪除都能正確運行,我決定使用一個簡單的Win32視窗程序來作為我的單元測試溫床,我的測試是手動測試。我的目標是用單元測試來盡可能地覆蓋我設計的代碼面積。第一步我設計了以下的單元測試:
void UnitTestCase0(HWND hWnd, HICON handleIcon)
{
// a normal core functionality test.
gSysTrayIcon.SetTrayIconID(11200);
gSysTrayIcon.SetNotifyWindow(hWnd);
gSysTrayIcon.SetTrayIcon(handleIcon);
gSysTrayIcon.SetTrayIconTip(_T("SysTrayIcon"));
gSysTrayIcon.SetTrayIconWmMsg(WM_TRAYICON_MSGS);
if (!gSysTrayIcon.AddIconToSysTray())
{
::MessageBox(hWnd, _T("Unable to add Icon to System Tray."), _T("Error:"), MB_OK);
return;
}
} 這是一個很簡單的函數,我假設我有一個全局變量叫gSysTrayIcon。它是一個類對象;它有至少六個函數;它的五個函數是數據設定函數;它的最后一個函數是讓調用者告訴它把圖像加入System Tray。根據我自己設計的單元測試案例,我設計了以下的類: #ifndef SYS_TRAY_ICON_H_
#define SYS_TRAY_ICON_H_
#include "shellapi.h"
class SysTrayIcon
{
private:
NOTIFYICONDATA niData;
public:
SysTrayIcon();
~SysTrayIcon();
void SetTrayIconID(UINT iconID);
void SetNotifyWindow(HWND hWnd);
void SetTrayIcon(HICON iconHandle);
void SetTrayIconTip(LPCTSTR szMsg);
void SetTrayIconWmMsg(UINT wmMsg);
BOOL AddIconToSysTray();
BOOL DeleteIconFromSysTray();
};
#endif