單元測(cè)試要求:?jiǎn)卧獪y(cè)試方法并不真正去變更數(shù)據(jù)庫(kù),也是說(shuō)單元測(cè)試不依賴于數(shù)據(jù)庫(kù)中的數(shù)據(jù)。那我們?nèi)绾谓鉀Q執(zhí)行單元測(cè)試方法后,不變更數(shù)據(jù)庫(kù)中數(shù)據(jù)呢?
一般的解決方案有兩種:
1、 新建一個(gè)單元測(cè)試數(shù)據(jù)庫(kù),開(kāi)發(fā)數(shù)據(jù)庫(kù)與單元測(cè)試數(shù)據(jù)庫(kù)分離,單元測(cè)試方法完全基于單元測(cè)試數(shù)據(jù)庫(kù)。
此中方法的優(yōu)點(diǎn)是:,開(kāi)發(fā)人員在開(kāi)發(fā)期間不會(huì)對(duì)單元測(cè)試數(shù)據(jù)庫(kù)中數(shù)據(jù)進(jìn)行變更,也不會(huì)影響單元測(cè)試方法 在任何時(shí)間執(zhí)行。
缺點(diǎn):?jiǎn)卧獪y(cè)試數(shù)據(jù)庫(kù)和開(kāi)發(fā)數(shù)據(jù)庫(kù)同步問(wèn)題,特別是對(duì)迭代式開(kāi)發(fā)項(xiàng)目,數(shù)據(jù)庫(kù)是根據(jù)需求在不斷地跟進(jìn)或者變更,同步問(wèn)題成為了單元測(cè)試正常運(yùn)行的瓶頸。
2、 使用事務(wù)對(duì)單元測(cè)試方法的執(zhí)行進(jìn)行回滾。
此種方法的優(yōu)點(diǎn):解決了方法一中缺點(diǎn),不會(huì)出現(xiàn)數(shù)據(jù)庫(kù)結(jié)構(gòu)不同步的問(wèn)題。
缺點(diǎn):在進(jìn)行CRUD(Create/Read/Update/Delete)操作時(shí),需要在單元測(cè)試方法中進(jìn)行一些插入數(shù)據(jù)操作,從而保證單元測(cè)試與開(kāi)發(fā)數(shù)據(jù)庫(kù)的獨(dú)立,造成了單元測(cè)試工作量增加。
在實(shí)際的項(xiàng)目中,可以根據(jù)需要選擇符合自己的解決方案,如果數(shù)據(jù)庫(kù)結(jié)構(gòu)在項(xiàng)目進(jìn)入開(kāi)發(fā)階段已經(jīng)確定,并且以后不會(huì)有變動(dòng),建議采用第一種方案,否則建議第二種方案。目前我們項(xiàng)目采用第二中方案。
一、NUnit事務(wù)性單元測(cè)試
那使用Nunit框架如果保證數(shù)據(jù)的會(huì)滾呢?這里我們使用了COM+事務(wù)。
即System.EnterpriseServices;
具體如下:
/// <summary>
///單元測(cè)試基類,所有單元測(cè)試類都需要繼承此類
/// </summary>
[TestFixture]
[Transaction(TransactionOption.Required)]
public class DatabaseFixture:ServicedComponent
{
public DatabaseFixture()
{
//
// TODO: Add constructor logic here
//
}
[TearDown]
public void TransactionTearDown()
{
if (ContextUtil.IsInTransaction)
{
ContextUtil.SetAbort();
}
}
所有的單元測(cè)試方法都需要繼承與此類。比如:
public class AddressSqlDAOTest : DatabaseFixture
這樣,單元測(cè)試方法執(zhí)行完后,會(huì)繼續(xù)執(zhí)行DatabaseFixture類中的TransactionTearDown()方法。從而會(huì)滾之前的數(shù)據(jù)操作,單元測(cè)試方法也不會(huì)影響開(kāi)發(fā)數(shù)據(jù)庫(kù),同樣開(kāi)發(fā)數(shù)據(jù)庫(kù)也不會(huì)影響單元測(cè)試方法的執(zhí)行,從而保證了單元測(cè)試與數(shù)據(jù)庫(kù)數(shù)據(jù)的獨(dú)立。
二、如何CRUD單元測(cè)試
1、測(cè)試增加方法:判斷返回的主鍵是否>0,如果主鍵>0 說(shuō)明單元測(cè)試方法成功,否則失敗
2、測(cè)試查詢方法:首先在執(zhí)行單元測(cè)試類中的插入數(shù)據(jù)方法(不是被測(cè)試類中的插入方法,而是在單元測(cè)試類中寫(xiě)的插入方法,一定要區(qū)分開(kāi)),然后執(zhí)行查詢方法。
3、測(cè)試更新方法:首先在執(zhí)行單元測(cè)試類中的插入數(shù)據(jù)方法,然后執(zhí)行更新方法。
4、測(cè)試刪除方法:首先在執(zhí)行單元測(cè)試類中的插入數(shù)據(jù)方法,然后執(zhí)行刪除方法。
三、單元測(cè)試的命名規(guī)范
為了便于后期單元測(cè)試方法的維護(hù),建議如下命名單元測(cè)試類 和單元測(cè)試方法。
單元測(cè)試類名:被測(cè)試類名稱+Test
單元測(cè)試方法名:被測(cè)試方法名稱+Test
四、總結(jié)
至此,大家可以利用Nunit中如何進(jìn)行事務(wù)性單元測(cè)試已經(jīng)完畢,相信大家也已經(jīng)了解了如何讓單元測(cè)試獨(dú)立于數(shù)據(jù)庫(kù)數(shù)據(jù),從而更高效地進(jìn)行單元測(cè)試,也不影響開(kāi)發(fā)。