Slashdot Mirror


Strategies for Test Databases?

youngcfan asks: "I've been tasked with finding strategies for a test database that can be used effectively by both software developers and the QA team. We're a J2EE shop with most of the interesting pieces of the application interacting heavily with the database -- so we need to test it. We're ramping up on JUnit, but are looking for ways to test the database-driven pieces of code. Since QA needs the same database for functional testing separate from developers' unit tests, DBUnit doesn't seem to suffice. We also have the challenge of working on multiple releases at the same time, which only complicates how and when to add new data to the test database in a way that's useful and valid for everyone. We're looking for strategies for using a test database in a way that meets both the QA's and the developers' needs, works for multiple releases, and isn't a heavy burden to maintain given that the schema and code can change anytime before any of the multiple upcoming releases. Any suggestions?"

1 of 66 comments (clear)

  1. DBUnit can be very useful by mikeburke · · Score: 3, Interesting

    I work with a large, legacy codebase - about 2 million lines of code, 600 tables. Some bits are nicely written, some aren't. Concepts such as dependency injection, seperation via interfaces etc are not prevasive, so traditional unit testing approaches of mocks or HSQL are not useful (in fact I find they do not scale for 'meaningful' tests anyway).

    So you have this legacy code base - you want to make changes, but how can you validate the result? One approach is to compare database states - one from a known good codebase, one from a modified codebase. DBUnit can be tremendously useful here - this is what I've done (perhaps too complex for explaining on Slashdot):

    Create a common Unit Test base class that extends DBUnit's DatabaseTestCase. It will:

        a) receive a list of modified table names from the concrete test class
        b) if a system property is set, export a pristine copy of these tables prior to running the test - 'reference data'.
        c) execute the use case (register a user, perform a transaction, whatever) - this just makes a 'blind' call into the
              code proper.
        d) if a system property is set, export the modified table data ('known good results')

    The idea is you run this test twice:

    1) With the original codebase, with result exporting enabled to generate known good results.

    2) With the codebase under test - the results generated will be compared against known good results and DBUnit will flag any differences. You can get it to ignore stuff like sequnces,dates that will differ between runs.

    The reference data generated in (b) is reloaded prior to running the test second test, so you start from the same point. Each concrete test class just has to:

    * figure out what tables change within the test
    * provide the test code itself

    Everything else is managed by DBUnit - exporting/importing datasets, comparing datasets, etc.