2013-03-24 71 views
2

我正在對數據庫運行一些集成測試。我想用種子數據設置數據庫,運行我的測試,然後刪除每個測試的數據庫(因此每個測試都有一個新的標準)。我目前使用這些安裝/拆卸方法做到這一點:集成測試數據庫重建性能

private ProjectDbContext db; 

[TestInitialize] 
public void SetUp() 
{ 
    db = new ProjectDbContext("TestConnection"); 
    (new SeedData()).Run(db); //Seed Data 
} 

[TestCleanup] 
public void Teardown() 
{ 
    db.Database.Delete(); 
    db.Dispose(); 
} 

我的問題是,它需要多一點的每個測試半秒,我想看到更好的性能。有什麼想法嗎?任何人都有更好的策略?

回答

0

根據你的代碼,我知道你想刪除您插入數據庫的測試數據。我用稍微不同的方式完成了它,但它可能對您有所幫助。我們可以使用TransactionScope而不是手動刪除數據。代碼Using TransactionScope in TestMethod 的圖片您也可以visit here瞭解該方法的詳細信息。

0

你可以這樣做:

public static void ClearDatabase(DbContext context) 
{ 
    var objectContext = ((IObjectContextAdapter)context).ObjectContext; 
    var entities = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace).BaseEntitySets; 
    var method = objectContext.GetType().GetMethods().First(x => x.Name == "CreateObjectSet"); 
    var objectSets = entities.Select(x => method.MakeGenericMethod(Type.GetType(x.ElementType.FullName))).Select(x => x.Invoke(objectContext, null)); 
    var tableNames = objectSets.Select(objectSet => (objectSet.GetType().GetProperty("EntitySet").GetValue(objectSet, null) as EntitySet).Name).ToList(); 

    foreach (var tableName in tableNames) 
    { 
     context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableName)); 
    } 

    context.SaveChanges(); 
} 

如果沒有約束,它是重要的身份列於你的測試(這我會建議反對)設定一定的方式,你可以使用TRUNCATE而不是的DELETE FROM。

(刪除從here代碼。)

+0

對不起,我的筆記本電腦在我輸入的時候正在死亡,我想確保我事先得到了它。您必須確保數據庫在測試之間持續存在,並且只有在不存在的情況下才創建(以確保測試可以以原子方式運行,但也可以按順序運行)。我們這樣做的方式是從具有DB屬性的抽象類繼承Fixtures。因此,您檢查數據庫是否爲空 - 如果是,則創建它,如果不是,則只需填寫數據。 – antinescience 2013-03-24 03:27:05

+0

地獄,如果你想加快速度,你可以讓tableNames成爲抽象的一個屬性 - 設置一次,所以你不必每次拆卸都要經過反射。 – antinescience 2013-03-24 03:29:41

+0

謝謝!我正在考慮更多這方面的內容。我將不得不確保他們正確訂購。 – orourkedd 2013-03-24 03:31:40