0

我的應用程序有一個與數據庫密切對話的業務層。這個層被實現爲包含Dapper的一堆ADO.NET調用。爲了初始化數據庫模式,我使用Code First,它具有可以將我的C#POCO作爲DDL和DAO使用的良好副作用。加速整合測試,擊中真正的SQL Server數據庫

我在Dapper中使用的原始SQL是普通的舊SQL,一些用戶定義的函數以及特定於SQL Server的事物的混合,例如,內置函數和全文索引。

在我的詹金斯CI身材,我有一個集成測試套件,將使用NUnit測試此層。爲確保測試彼此隔離,數據庫初始化應在[SetUp]方法上進行。

我通過幾個選項去實現集成測試:

  1. 使用內存數據庫。優點:測試設置速度快,運行測試邏輯速度快。 缺點:這是一個非選項,因爲我使用的SQL命令特定於SQL Server
  2. 使用SQLiteSQL Compact。優點:語法類似於SQL Server,設置和拆除僅僅是刪除文件的問題。缺點:在我開始使用用戶定義函數和全文索引時,也是非選項。
  3. 使用本地SQL Express服務器只服務測試。優點:行爲幾乎可以保證與生產設置相匹配,包括內置函數和全文索引。缺點:設置更慢,更復雜。

我去選項3,用以下方法:

  1. [SetUpFixture][SetUp],初始化種子數據庫。一旦初始化,創建該數據庫的備份,並將其保存爲文件。這隻會在測試的整個名稱空間中發生一次。
  2. 在每個[TestFixture][SetUp],恢復備份。由於每次測試運行前都會發生這種情況,因此每項測試都與其他測試分開。

缺點是運行測試套件現在變得很慢。步驟編號以上2每個測試需要2-5秒。最重要的是,每個測試也需要一些時間來執行測試夾具本身,這比典型的單元測試慢得多,因爲它碰到了真實的數據庫。

在我目前的狀態下,一個143個測試的中等大小的測試套件在我的構建機器上運行13分鐘,這是Azure上的一個VM,運行Windows Server 2008 R2的A3(4核7 GB)。

反正是有,我可以加快不如抽更多的硬件給其他機器這個過程?

回答

2

你可以在設置使用事務範圍,在拆卸方法處理此:

[MyFixture] 
public class MyTests 
{ 
    private string connString= "..."; 
    private TransactionScope ts= null; 
    [SetUp] 
    public void SetUp() 
    { 
     ts = new TransactionScope(TransactionScopeOption.Required); 
    } 
    [TearDown] 
    public void TearDown() 
    { 
     ts.Dispose(); 
    } 

    [Test] 
    public void MyTest() 
    { 
     // do my tests etc. 
     using (SqlConnection conn = new SqlConnection(connString)) 
     { 
      using (SqlCommand cmd = new SqlCommand("exec MyProcecure")) 
      { 
       cmd.Connection = conn; 
       conn.Open(); 
       int retval = cmd.ExecuteNonQuery(); 
       Assert.Greater(retval, 0); 
      } 
     } 
    } 
} 

編輯 這會工作,即使被測單元有它自己的事務範圍。

MSDN

投票嵌套範圍

內雖然嵌套的範圍可以加入根範圍內的 環境事務,要求完成該嵌套 範圍上有沒有影響根範圍。只有當所有範圍從 根範圍到最後一個嵌套範圍投票承諾 事務,都將承諾交易。

+0

如果被測單元有它自己的事務範圍並且提交了數據庫,會發生什麼?外部事務範圍是否會回滾內部範圍提交的內容? –

+0

@AdityaSantoso是一個嵌套事務將被回滾。查看更新以回答。 –

+0

看來我不能使用這種方法讀取未提交的數據。我是否需要更改連接或事務範圍或SQL命令本身中的任何內容? –