Speeding up your DBUnit tests with JavaDB
Introduction to DBUnit
With the developed use of JUnit, many additions were made to it. These additions take advantage of the pluggable nature of JUnit. One of these contribution is DBUnit. DBUnit enables your unit tests to:
- preload the database with datas pertaining to your current test only,
- run your unit test (as usual),
- remove the data you preloaded in order to put the database in the same it was before your additions.
In effect, you can now test your DAO classes. Let’s take a (very) simple example: a
PersonDao class that manipulates
You create a test case that extends
org.dbunit.JdbcBasedDBTestCase. It forces you to implement the following methods:
IDataSet getDataSet() throws Exceptionwhere
IDataSetrepresents a collection of tables,
getConnectionUrl()that returns the connection url of the database,
getDriverClass()that returns the class name of the driver used for database access.
This process enables you to test your DAO classes with various data sets. Moreover, these data sets can be initialized from various sources: I recently discovered one of these sources could be an Excel file ! Not very open-source, I agree, but very much more manageable than those cumbersome XML files.
Yet, these tests are usually made on remote and shared databases. Drawbacks include:
- a sheer performance cost: remote databases use networks and, as such, increase the time to get the result, even if the databases themselves are very performant on their own,
- a risk of using the wrong datas: if using a shared database, you are taking chances that the data you want to use for your test has just been modified by another developer. If your DB uses a schema for each developer, well, that’s just configuration overhead…
The first point is a good way for developers not to write DB tests, since they can’t complete the build fast enough. The second point paves the road for correct tests to fail or more importantly, for incorrect tests to succeed. Both are bad.
Using an alternate local DB
The answer to these problems are the use of an alternate local DB. Yet, this solution has its own disadvantages including: license costs, configuration overhead for each developer’s machine and the ever-popular “It doesn’t work on my computer”. Well, let’s get back to the shared BD ? Clearly no: there’s a often overlloked option.
Since version 6 of the JVM, Sun ships an embedded database with its JDK. This DB, called oh-so-originally JavaDB, is a reuse of the not-so-old Apache Derby database project. Apache Derby, is an open source relational database implemented entirely in Java.
Main advantages are:
- a small memory footprint,
- the main SQL-99 Core / SQL-2003 mandatory features (see table for unsupported features),
- an embedded driver.
First of all, you should provide a mechanism to provide a connection in different ways, for example with dependency injection, probably the method you will choose for a real-world project (be it with Spring or Guice). For my proof-of-concept, I chose the method-overloading mechanism to keep it simple (KISS without the trailing S).
Then, it’s all very simple:
getDataSet()should return very simply
Et voilà !
The use of JavaDB is not the golden hammer to your DB tests problems. According to me, there’s much to be done in order for it to be really full-SQL compliant. Yet, 90% of the common SQL requests used troughout prjects can be parsed by it. There’s even an Hibernate dialect available. In conclusion, it can save much anguish and much time for developers. So, why don’t use it ?