發(fā)布: 2010-9-10 08:28 |
作者: 網(wǎng)絡(luò )轉載 |
來(lái)源:
領(lǐng)測軟件測試網(wǎng)采編 |
查看: 339次 | 進(jìn)入軟件測試論壇討論
領(lǐng)測軟件測試網(wǎng)
軟件單元測試的測試用例編寫(xiě)方法
MILY: 宋體; mso-ascii-font-family: " Times Roman?; mso-hansi-font-family: ?Times New Roman??>我在這里用最常用的方法:基本路徑測試法來(lái)進(jìn)行單元測試,因為我要用一個(gè)實(shí)際的例子來(lái)進(jìn)行說(shuō)明,所以就編寫(xiě)了下面一個(gè)程序模塊,就暫且命名為“詳細查詢(xún)模塊”吧。
我先寫(xiě)一下基本過(guò)程:
1 分析模塊函數;
2 在模塊中找到相應的關(guān)鍵點(diǎn)(函數);
3 根據第二點(diǎn),畫(huà)出模塊程序流程圖;
4 計算圈復雜度;
5 根據圈復雜度算出測試用例的最優(yōu)個(gè)數;
6 根據路徑測試法和圈復雜度寫(xiě)出具體測試用例;
7 進(jìn)行測試。
void CXIANGXIDLG::OnOK()
{
CoInitialize(NULL);//初始化COM環(huán)境
_ConnectionPtr m_pConnection;//連接對象
HRESULT hr;
try
{
hr = m_pConnection.CreateInstance("ADODB.Connection");//創(chuàng )建Connection對象
if(SUCCEEDED(hr))
{
hr=m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=shouji.mdb","","",adModeUnknown);//連庫
}
}
catch(_com_error e)
{
AfxMessageBox("數據庫連接失敗,確認數據庫連接字符串是否正確");
}
//操縱表
_RecordsetPtr m_pRecordset; //記錄集對象
UpdateData(TRUE);
CString strSQL;
if (m_name=="") //路徑1
{
MessageBox("用戶(hù)名不能為空!"); //函數A
}
else {UpdateData(TRUE); //函數B
int lenth=0;
lenth=m_name.GetLength();
if (lenth>12 || length<2) //路徑2
{MessageBox("輸入的用戶(hù)名不正確或沒(méi)有該用戶(hù)!請重新輸入!"); //函數C
}
Else
{
if(m_pipei) //路徑3
{
strSQL="SELECT * FROM sj_T_ShouJiKa where 用戶(hù)姓名 = '"+m_name+"'"; //函數D
}
Else
{
strSQL="SELECT * FROM sj_T_ShouJiKa where 用戶(hù)姓名 like '%"+m_name+"%'";//函數E
}
try
{
hr=m_pRecordset.CreateInstance("ADODB.Recordset");
if(SUCCEEDED(hr))
{ //從數據庫中打開(kāi)表
m_pRecordset->Open(_bstr_t(strSQL),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
else
{
AfxMessageBox("查詢(xún)不成功!");
}
}
catch (_com_error e)
{
CString strError;
strError.Format("警告:打開(kāi)數據表時(shí)發(fā)生異常。 錯誤信息: %s",e.ErrorMessage());
AfxMessageBox(strError);
return;
}
while(!m_pRecordset->adoEOF) //路徑4
{ //函數F
_bstr_t name="";
_bstr_t shoujikahao="";
_bstr_t tongxinzhishi="";
_bstr_t fuwushang="";
int i=0;
m_list5.DeleteAllItems();
while(!m_pRecordset->adoEOF)
{
name=(_bstr_t)m_pRecordset->GetCollect("用戶(hù)姓名");
shoujikahao=(_bstr_t)m_pRecordset->GetCollect("手機卡號");
tongxinzhishi=(_bstr_t)m_pRecordset->GetCollect("通信制式");
fuwushang=(_bstr_t)m_pRecordset->GetCollect("服務(wù)商");
m_list5.InsertItem(i,name);
m_list5.SetItemText(i,1,shoujikahao);//設置該行的不同列的顯示字符
m_list5.SetItemText(i,2,tongxinzhishi);
m_list5.SetItemText(i,3,fuwushang);
m_pRecordset->MoveNext();
i=i+1;
}
}
//關(guān)閉連接、釋放com資源m_pRecordset->Close(); //路徑5
m_pRecordset.Release();
m_pConnection->Close();
m_pConnection.Release();
CoUninitialize();
}
}
}
我們根據這個(gè)程序來(lái)畫(huà)出它的程序流程圖,如下,是我畫(huà)好的:
有了圖以后我們就要知道到底我們要寫(xiě)多少個(gè)測試用例,才能滿(mǎn)足基本路徑測試。
這里有有了一個(gè)新概念——圈復雜度。
圈復雜度是一種為程序邏輯復雜性提供定量測試的軟件度量。將該度量用于計算程序的基本獨立路徑數目。為確保所有語(yǔ)句至少執行一次的測試數量的下界。
公式圈復雜度 V(G)=E-N+2,E是流圖中邊的數量,N是流圖中結點(diǎn)的數量。
從圖中我們可以看到,
V(G)=8條邊-6結點(diǎn)+2=4
上圖的圈復雜圖是4。這個(gè)結果對我們來(lái)說(shuō)有什么意義呢?它表示我們只要最多4個(gè)測試用例就可以達到基本路徑覆蓋。
下一步我們就要導出程序基本路徑。
程序基本路徑:基本獨立路徑就是從程序的開(kāi)始結點(diǎn)到結束可以選擇任何的路徑遍歷,但是每條路徑至少應該包含一條已定義路徑不曾用到的邊。
我們可以得到基本路徑是:
1: A
2: B->C
3: B->D->F
4: B->E->F
下面我們開(kāi)始寫(xiě)測試用例。
“詳細查詢(xún)測試”做完了嗎?沒(méi)有,因為對于上表的每一個(gè)路徑,如果結果有不同的,即:結果有對的,也有不對的。那么,我們就還需要進(jìn)行進(jìn)一步的測試,下面的工作我就不做了,照搬就是。
單元測試是編寫(xiě)高質(zhì)量代碼的前提,通過(guò)編寫(xiě)有效的單元測試即可以保證代碼的質(zhì)量又可以提高開(kāi)發(fā)速度,因為大多數問(wèn)題都可以通過(guò)單元測試發(fā)現并解決而不需要部署到應用服務(wù)器?v覽網(wǎng)上流行的優(yōu)秀開(kāi)源框架,無(wú)一不提供完整的單元測試用例。Spring框架便是其中的代表和佼佼者,因為Spring所遵循的控制反轉(IoC)和依賴(lài)注入(DI)原則使編寫(xiě)有效、干凈的單元測試用例變得更加方便、快捷。
編寫(xiě)單元測試用例
本文所采用的案例非常簡(jiǎn)單,就是對數據庫表的增、刪、改、查操作進(jìn)行測試。假設我們有這樣一個(gè)表url(MySql數據庫):
正如你所見(jiàn),該表只有幾個(gè)字段,但對于我們的案例來(lái)說(shuō)完全夠用。
看到此處,你應該清楚我們是要對數據庫操作進(jìn)行單元測試。如果你是一位經(jīng)驗豐富的開(kāi)發(fā)人員,此時(shí)已經(jīng)會(huì )有許多疑問(wèn),甚至已經(jīng)失去繼續閱讀本文的興趣:
單元測試不應該直接操作數據庫?
對數據庫操作的單元測試可以采用DAO模式,Mock一個(gè)實(shí)現類(lèi)?
使用內存數據庫?
其他?