Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rollback database after integration (Selenium) tests

Does anyone have any suggestions for a best practice or preferred way of rolling back database transactions made from an integration test framework such as Selenium?

Here is our current situation: We have a .net web project with a number of unit tests which work fine in our unit test environment - each test inherits a parent class which opens a transaction in the [SetUp], and rolls back the transaction in the [TearDown]. After each test, our unit test database is restored back to the original state.

However, things change once we get to our integration environment. Our continuous integration server automatically compiles our commits and pushes them out to a test server, so that the server always runs on the most up to date code. We've also setup a Selenium instance to automate user interaction with the site. The selenium tests basically communicate with an existing Selenium server, and tell the server things like, "Launch a browser and go to http://testsite/TestPage.aspx - enter text 'abc' into form field with id 'def' - assert new page contains text 'xyz'"

Each test is run in a similar manner to our vanilla unit tests, but with an important exception: any changes made by Selenium are done in a completely different thread/application, and therefore we can't (I *think we can't, at least) roll them back in the test teardown.

We've yet to come to a good solution for this. Right now we're at a point where we're using a SqlCommand to execute a sql statement to backup the database, then at the end of the test, we're setting the database to single user, dropping the current db, and restoring the old copy - this is less than ideal, because that effectively kills the application that was attached to the DB, and requires us to yet again re-initialize the app.

Is this a problem that has been solved before? Any advice would be awesome.

Thanks!

like image 375
matt Avatar asked Apr 20 '09 16:04

matt


3 Answers

We are running a drop/create-table script before every test. This is quite fast and ensures that nothing is left from previous tests.

PS: We are using NHibernate, which creates this script on the fly and run the test on Sqlite in memory, it's lightspeed. But if we switch to SqlServer it's still quite fast.

like image 131
Stefan Steinegger Avatar answered Oct 24 '22 10:10

Stefan Steinegger


It's a tough problem and the solution is typically unique for every app. Until the major frameworks adopt a "recommended approach", this will continue to be a pain.

My best recommendation: plan for this usage at the start of your app. Include APIs that clean up after the DB is reset from underneath the app (ie: reset caches).

like image 23
Patrick Lightbody Avatar answered Oct 24 '22 09:10

Patrick Lightbody


There is a project called Amnesia (more docs, recent code) that is designed specifically for this scenario. It simplifies the process of using the MSDTC TransactionScope to rollback test changes. (Usage will require moderately invasive changes to data access in most applications, especially those not already using MSDTC.)

like image 28
user423430 Avatar answered Oct 24 '22 10:10

user423430