I am writing integration tests for an application and have not been able to find any best practices on how to set up a test database for my integration suite. I am working on an ASP.NET MVC4 application using Entity Framework code-first.
I can confirm that the tests in my test project talk to the local development database on my machine by default. This is not ideal, as I want to have a fresh database every time I run the tests.
How can I set up my test project so that my tests talk to a separate instance? I'm assuming that it is possible to set up an SQL Server Compact Edition instance, but I'm not sure how to configure this.
Integration tests focus on testing how separate parts of the program work together. In the context of applications using a database, integration tests usually require a database to be available and contain data that is convenient to the scenarios intended to be tested.
Four key strategies to execute integration testing are big-bang, top-down, bottom-up and sandwich/hybrid testing. Each approach has benefits and drawbacks. Big-bang testing: The big-bang approach involves integrating all modules at once and testing them all as one unit.
Thanks so much to @Justin and @Petro for your answers, which have helped me immensely. The solution I have come up with is a combination of the techniques you suggested. The solution described below provides a new database for each run of the tests, and a separate transaction for each test.
I added a connection string for my test database in the App.config of my Test project:
<connectionStrings> <add name ="TestDatabase" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Database=TestDatabase;Integrated Security=True"/> </connectionStrings>
I created a base class for my integration tests, to provide setup and teardown. Setup instantiates the context, creates the DB if it doesn't exist yet and starts a transaction. Teardown rolls back the transaction.
public class EntityFrameworkIntegrationTest { protected MyDbContext DbContext; protected TransactionScope TransactionScope; [TestInitialize] public void TestSetup() { DbContext = new MyDbContext(TestInit.TestDatabaseName); DbContext.Database.CreateIfNotExists(); TransactionScope = new TransactionScope(TransactionScopeOption.RequiresNew); } [TestCleanup] public void TestCleanup() { TransactionScope.Dispose(); } }
Finally, I have a class that takes care of deleting the database after all the tests have run:
[TestClass] public static class TestInit { // Maps to connection string in App.config public const string TestDatabaseName = "TestDatabase"; [AssemblyCleanup] public static void AssemblyCleanup() { Database.Delete(TestDatabaseName); } }
I should add that I found this blog post about Entity Framework useful for a deeper understanding of what Entity Framework is doing under the hood / by convention.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With