2

I am working with EntityFramework 6 code first approach and SQL Server 2014 Express. However, the DBMS may change in future.

That setup allows easily to create a database and add some dummy data for unit tests. Currently, I am creating one database per unit test and drop it after the unit test finished.

I am not sure if creating / dropping a database is such a lightweight operation as creating / deleting a file... So are there any disadvantages with that approach?

5
  • 4
    If possible, I'd use an in-memory database. Sep 13, 2016 at 7:30
  • Good Point. As far as I know there is no in-memory provider for EF6. Mocking the DbContext is another option...
    – JanDotNet
    Sep 13, 2016 at 7:39
  • 2
    Since a database is a pretty leaky abstraction, I prefer not mocking it. Sep 13, 2016 at 7:42
  • @JanDotNet: Check Effort Sep 13, 2016 at 12:10
  • If a test talks to a real database it is not a "unit" test any more. Feb 28, 2020 at 14:20

3 Answers 3

8

The first thing to note is that, if you are creating and dropping DBs as part of your tests, then they aren't unit tests; they're better described as integration tests.

Pedantic point aside, then the key question is, does each test create a different DB, thus can the tests be run in parallel? Or could two tests running at the same time interfere with each other (eg by one dropping the DB half-way through the other's test)?

If they can't run in parallel, then you aren't getting a good return on the time investment of having each test do its own setup and teardown. If you moved this to the test suit setup and teardown functionality, then you'd suffer no new conflict issues between tests and you'd speed up the individual tests.

If they can be run in parallel, then it comes down to a choice. Having each test create and destroy its own DB is cleaner, but it's slower. So take your pick between the two.

5
  • 1
    Not sure about SQL Server, but some kind of database snapshotting feature might be useful here to speed up the setup. Sep 13, 2016 at 7:37
  • Each test creates it's own database, so the tests may run in parallel.
    – JanDotNet
    Sep 13, 2016 at 7:42
  • 1
    @CodesInChaos: "snapshotting" may be an option in case of bad performance. However, it requires to save state that should be avoided if possible because it increases the effort if anything changed.
    – JanDotNet
    Sep 13, 2016 at 7:47
  • @JanDotNet Many unit testing frameworks have a setup function that only runs once per session. I'd setup the application and create the snapshot there, so the snapshot doesn't live longer than a single testing session. The idea is that you shouldn't pay the full setup cost for each unit test. Sep 13, 2016 at 7:53
  • 1
    Right... that is possible for unit tests that work on the same data set. I'll consider it if test become to slow ;).
    – JanDotNet
    Sep 13, 2016 at 7:58
4

It is going to be slow, this is the major disadvantage. It might not be a problem if you have a dozen tests, but when you have hundreds it might be a real problem.

2

I am not sure if creating / dropping a database is such a lightweight operation as creating / deleting a file...

It's certainly not. A file creation/deletion (whether local or remote) would normally be much faster.

I think speed of unit test execution is your issue here (and it may be fast enough that it doesn't worry you). Normally you want your tests to be fast enough to run repeatedly and not form a bottleneck to your development/deployment. If you're able to turn these databases around quickly enough then it's not a a problem. However if you're going to continue to add such cases, then scalability will become an issue, and I would look at (say) initialising a database per test suite or similar.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.