Why Unit Test a Database?
In the Java (OO) world, unit testing specifically avoids testing persistence. The persistence engine (database) is mocked so it doesn't interfere with the purity of the testing. Also, Java (OO) purists attempt to remove all logic from the database. However, we typically don't find such purity in practice.
What is a Thick Database?
A Thick Database is a database with lots of logic built-in. Dulcian.com does a great job of explaining what it is and why it's useful. In practice, we tend to see some logic implemented in the database for a variety of reasons.
What is a Unit in the Database?
Most references define a "unit" as something like the smallest bit of logic in a system. For this discussion, "unit" will refer to an interface. Interfaces in an Oracle database include the following:
- Packages
- Procedures (Public and Internal)
- Functions (Public and Internal)
- Procedures
- Functions
- Types with Methods
- Tables
- Check Constraints
- DML Triggers
- View Triggers
- Session Triggers
- Database Triggers
Is a Unit Test Framework Required?
create package simple_ut
is
begin
end ut_assert;
Where to start?
- Pick something to test, like a procedure in a package.
- Define a "No Data" Test Case for that procedure (nothing for the procedure to do).
- Create a Unit Test Package to contain you Unit Test code.
- Create a procedure in the Unit Test Package called "no_data_to_process".
- Write the "no_data_to_process" procedure to call the procedure (from step 1) with without any test data setup.
- Add "ut_assert" procedure calls from the "simple_ut" package to document results.
- Run the "no_data_to_process" procedure and check results in DBMS_OUTPUT.
- Add more tests.
Are there any Tips or Tricks?
- As part of the Test Case, test the data setup (if any) before the "actual" unit test.
- Run the "actual" unit test in a separate procedure with a dedicated Exception Handler.
- Create Unit Test Procedures/Functions to load Test Data into a single record variable.
- Use the single record variable to INSERT Test Data into a table.
- Setup Date/Time sensitive data for each run of a Unit Test.
- Create additional test customers/locations/actors as needed to re-run unit tests.
- Capture Sequence Generator values after the "actual" unit test.
- Include testing of logs after the "actual" unit test.
- Cleanup Test Data only when necessary to re-run unit tests.
- Develop a complete Test Data Set with a variety of Test Cases setup and ready for testing.
What is the downside?
What is the Upside?
- Testing code that serves no purpose results in removal of useless code.
- Fault insertion testing results in much better error messages and error recovery.
- Thinking through unit test cases results in simplification of overall implementation.
No comments:
Post a Comment