- #1: Build Classes, Not Individual Databases
- #2: Don't Ignore History
- #3: Automate All Changes to Every Database Instance
- #4: Test Every Change to Database Design
- #5: Force Clients to Break Fast When Interfaces Change
- #6: Encapsulate Database Behavior
- #7: Drive Behavior from Information
- #8: Keep a Complete Unit Test Suite
- #9: Build Only What You Need
- #10: DON'T PANIC
#4: Test Every Change to Database Design
Having an automated tool that builds every database the exact same way starts out as a real boon to any test-driven database initiative and, consequently, does a lot to keep databases from being the roadblock in an otherwise agile process. It also has a terrific side effect.
In addition to being nearly perfectly predictable, automated things can also be test-driven. With just a little extra work, you can make your database build tool be able to stop at any version, rather than just the latest. Once you have that, you can introduce a technique called transition testing.
Transition testing allows you to test-drive not only what an instance of your database class does, but also how it is built. When programming middle-tier classes, that’s not very important but, because databases are reservoirs of vital knowledge, how they arrive at a new design is at least as important as what that new design is.
In a nutshell, a transition test has the following properties (also shown in Figure 7):
- The setup phase builds a database to some version and populates it with representative data
- The trigger phase upgrades that database to another version, usually the very next one
- The assertion phase ensures that the knowledge populated in the setup has been properly transformed to fit in its new container
A transition test is fundamentally a data- or knowledge-protecting thing. Its job is to test your class of databases itself, rather than individual databases. Having those protections will greatly reduce resistance to a fast-pace of change.