Unit testing: Don't use HSQLDB
As previously mentioned, I recently changed jobs, and that meant going from Perl/Python and back to Java. Things certainly have changed in four years, and it seems that most of it is for the better. I’ve been putting a lot of effort into unit testing lately, and it’s working out great. There’s multiple people working on the project I’m on at the moment, and unit tests make sure things are working properly before others start using my code, which is a persistence layer written using Hibernate annotations (which are great, by the way). Or so I thought…
To make it easier to run the unit tests, it was quite convenient to use HSQLDB, a relational database engine written in Java. The benefit of using it with unit tests, is that it can exist entirely in memory, and there is basically no need for configuration. Quite handy, since this means that we don’t need to set up a database for our continuous integration server, which runs the tests automatically on every commit.
I was coding along minding my own business, when I suddenly got a complaint that this or that didn’t work properly. That was pretty strange, since the tests were green across the board, so I changed to another database, and guess what? FAIL! Not all of the tests failed, of course. The failed tests seemed to be related to constraints that were ignored, and data types that were handled a bit differently. Mainly it seemed to be because HSQLDB was too lightweight. The other database I tested with was MySQL, by the way (which is not what we’re deploying on, I’ll have to test with that later on).
If you search for unit testing and hsqldb on Google, you’ll find several articles recommending this combination. Personally, I don’t see the point if it doesn’t give you an environment closer to the real world. I honestly don’t know why anyone would use HSQLDB for this purpose, unless they’re writing a really simple application, or actually deploying to HSQLDB.
You may wonder why I’m not testing with the database server we’re deploying on… Well, I’m not too familiar with it, and at Enonic we have a history of making our applications work across multiple application servers and databases. That, by the way, still takes effort despite the fact that we’re using database abstraction layers.
Unit testing with DbUnit is great, I use iBatis in my project (JOGRE) and all the SQL queries are unit tested with HSQLDB. We also use MySQL and to test it works we simply change the db connection parameters. The first time I did this the MySQL wasnt working at all but we fixed the SQL so that it worked on both HSQLDB and MySQL. Unit testing these gives me great confidence that all the data access is robust and well tested.