研究EF& Code First,我刚才问了一个问题(ref this thread),说明你如何防止测试相互重叠。我想为数据库播种并为每个测试类做这样的事情(使用MSTest):
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
}
然而,这里的问题是每个测试创建/拆除数据库(不理想,因为它们相互重叠并失败...如果你单独运行测试,它们都按需要通过......加上这会大大减慢测试)。
A good solution was to instead wrap them up in TransactionalScopes,但我想确保在测试运行开始时,使用种子信息重新生成数据库(因为种子会随着我的开发人员开发测试而更改)。
执行此操作的强制方法是创建某种处理程序,在测试初始化中,它将检查数据库是否最近创建,如果没有,则使用种子信息创建它。如果没有,它将忽略该步骤。然后它将创建一个TransactionalScope(),它将在测试清理中回滚。
但是有更好的方法来解决这个问题吗?这个蛮力的appraoch ...想法得到了过度工程化的感觉?
答案 0 :(得分:2)
Marvel的回应让我思考正确的方向......让它运转起来,在这里解释有点长,所以我在这里写博客:http://www.andrewconnell.com/blog/archive/2012/05/02/isolating-integration-tests-with-ef4-x-code-first-amp-mstest.aspx
答案 1 :(得分:-1)
通常,这些测试与Continuous Integration服务器高度集成,每次检查都是如此。所以我认为如果您可以将dbCreation测试作为测试设置中的第一个测试进行排序会更好,因为它会创建具有所有必要映射的数据库。之后,在第一次测试时创建它,其他测试可以在您的基本TestFixture类中使用Transactionscope,以便您现在使用它,并且您的集成测试可以有效地工作,因为您没有使用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()
{
}
}