2013-03-24 73 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