2012-04-30 153 views
1

研究EF & Code首先,前一段時間我問了一個問題(ref this thread),指導您如何防止測試互相重疊。我要種子數據庫,並在做它像這樣爲每個測試類(使用MSTest的):EF4.1 + Code First:交易測試

public class CustomerSmokeTests { 
    private const string CONNECTION_STRING = "server=localhost;database=CPT_CustomerDataSync_SmokeTests;uid=sa;pwd=Password1!;"; 

    private DatabaseFactory _dbfactory; 
    private CustomerCacheContext _customerContext; 

    [TestInitialize] 
    public void Setup() { 
     // set initializer to create new DB 
     Database.SetInitializer(new SmokeTestCreateDbWithDataIfNotExists()); 
     Database.SetInitializer(new SmokeTestDropCreateDbWithDataAlways()); 

     // create new DB connection to local SQL Server 
     _dbfactory = new DatabaseFactory(CONNECTION_STRING); 

     // connect to DB to auto generate it 
     _customerContext = _dbfactory.GetDataContext(); 
    } 

    [TestCleanup] 
    public void Cleanup() { 
     _customerContext.Dispose(); 
     _dbfactory.Dispose(); 
    } 

    // tests 
} 

但是這裏的問題是,每個測試創建/拆毀DB(因爲它們相互重疊不理想並失敗......如果你單獨運行測試,它們都會按照要求通過......這會大大減慢測試的速度)。

A good solution was to instead wrap them up in TransactionalScopes,但是我想確保在測試運行開始時,使用種子信息重新生成數據庫(因爲種子會在我的開發人員開發測試時發生變化)。

這樣做的蠻力方法是創建某種類型的處理程序,在測試init中,它將檢查數據庫是否最近創建,如果沒有,則使用種子信息創建它。如果沒有,它會忽略這一步。然後它會創建一個TransactionalScope(),它將在測試清理中回滾。

但是,有沒有更好的方法來處理這個問題?用這個蠻力appraoch得到了過度的工程感覺......想法?

+0

實體框架已經在savechanges後面使用幕後交易 –

回答

-1

通常,這些測試與持續集成服務器高度集成,並且每次檢查都是如此。所以我認爲如果您可以將dbCreation測試作爲測試設置中的第一個測試,會更好,因爲它會創建具有所有必需映射的數據庫。在第一次測試中創建它之後,其他測試可以在您的基本TestFixture類中使用Transactioncope,以便您現在可以使用它,並且集成測試可以高效地工作,因爲您不是使用TestInitialize和TestCleanup創建數據庫。

public class BaseTestFixture 
{ 

TransactionScope transactionScope; 

    [TestInitialize] 
    public void InitializeTests() 
    {    

     if (IsTransactionScopeNeeded) 
     { 
      transactionScope = new TransactionScope(); 
     } 
    } 

    [TestCleanup] 
    public void CleanUp() 
    { 
     if (transactionScope != null) 
      transactionScope.Dispose(); 

    } 

}

public class DbContextTests : BaseTestFixture 
{ 

    protected override bool IsTransactionScopeNeeded 
    { 
     get 
     { 
      return false; 
     } 
    } 

    //This test should run first 
    [TestMethod] 
    public void CreateDatabase_DatabaseNotExistedOrObselete_DatabaseCreated() 
    { 
    } 
} 
+1

這需要創建有序的測試...是的?我試圖避免有序的測試,因爲它們不被我們使用的測試運行者識別。 –

+0

我認爲在您的構建服務器中,您可以通過發出命令而不是使用有序測試列表來執行DbContext測試。可以通過使用有序測試列表來執行休息 – marvelTracker

+0

-1:_Ordered tests_是[反模式](http://stackoverflow.com/a/333814/11808)。 –