Unit testing a database methodology
I am about to write unit tests for a new web application.
My preferred method is to test against the live database structure rather than an in-memory database.
I understand that I can wrap my unit test database calls inside transactions that are not com开发者_JS百科mitted.
What I think is a better approach is to copy the live database before initialising the tests, and allow the transactions to commit to the test database. If the tests are run in the correct order this will allow me to create a complete test story from registering the first account, through their various interactions, ending with an account closure. i.e. a real world lifecycle. I am convinced this should be an excellent approach, but having never put this into practice yet I was wondering if people had attempted a similar approach and what the feedback is before I proceed. Thanks in advance.
I know I am going to be that guy by doing this, but lets establish our terms here before moving forward. Skip this part if you only care about the answer.
A Unit Test should test just that, a single unit. It should not rely on external dependencies such as databases, web services, or file systems. Instead, those dependencies should be mocked so that the state of each individual test can be precisely controlled.
A Unit Test should be atomic, consistent and repeatable. As John points out, the test should be able to be run by itself, or in a suite with the exact same behavior every time.
An Integration Test should test the interaction between the various units that compose your system. Thus, they should never seek to stub or mock any dependencies. These tests should be as close to testing what will be deployed to production as can be achieved.
Let me be the first to tell you that while it is quite common for Integration Tests to be dependent on setup and tear down, tread lightly in this arena.
Sure it seems like a really good idea to begin with, but for the same reason that procedural code usually ends up as a nightmare to maintain, procedural tests are even worse. Since they are so tightly coupled to the implementation details of the underlying code, you will end up having to change massive sets of tests if you ever change those details.
In the best case scenario you will throw away large sets of tests and start over. In the worst scenarios you will hesitate to refactor your system because you don't want to break your tests... and thus rob you of the very advantage they are supposed to bring.
The best advice I can give you is to start reading up on Acceptance Testing, and Behavior Driven Development.
Some People who can help:
Gojko Adzic, Bob Martin
Some Tools that can help:
FitNesse, SpecFlow, Cucumber
Please! Please! Please! read and learn from those guys, and those communities. They will steer you in the right direction and help you avoid long term problems with automated testing.
Unit tests should not depend on their order, and should not depend on the state of what is being tested. They should set up all necessary state.
What you've described may be a useful test, but it's not a set of unit tests.
精彩评论