Lots has been written about the merits of continuous integration and I am a firm believer in it. However, while our team at work uses test-driven development, we still don’t have a CI server. This week I went on a quest to change that.
In order to minimize maintenance, we decided to give tddium a try. It is a hosted CI service for Ruby (on Rails) projects.
Initial setup was quite painless and works as described on their webpage:
- sign up on the webpage
- install the tddium gem
- guided setup with the tddium tool, including github integration and email/campfire notification
For a regular rails app, this should have been it. In our case however, the tests wouldn’t even start as our sample app uses multiple databases. While initial install was a matter of minutes, at this point I began a multi-hour debug session, trying to figure out how to bend tddium to my will.
The first problem was the Rails logger. Tddium seems to overwrite the standard logger with their own implementation that is not fully compatible with the standard Rails logger. In our case it doesn’t provide auto_flushing=. This, however, was easy to fix:
Rails.logger.auto_flushing = true if Rails.logger.respond_to?(:auto_flushing)
The next problem was a much bigger beast, multi database support. While the documentation roughly explains database setup and the use of hooks to add custom configuration, it took me quite some time to figure out how everything really works and how I could change the setup to suite my needs.
At this point I have to mention the slow feedback cycle tddium has, from
tddium spec to push code changes, to running the suite and seeing an
error, it took 2 to 3 minutes. On the plus side I am happy
tddium spec exists
at all, this way you can easily run the suite on locally commited changes and
don’t have to push to github all the time. Great for testing stuff.
So, after many failures I was finally able to come up with this solution:
There are two things to notice:
- I was only able to setup a 2nd database connection. Unfortunately the user is not permitted to create arbitray databases. In our case this was enough to get the code to load and the test suite to run.
- The socket entry is necessary for us but is not mentioned in the documentation. I extracted it from tddium’s database.yml.
At this point our test suite would run with two failing specs. In one case we actually executed code accessing the 2nd database. This was easy to fix in our specific case by rewriting the spec. The other problem was completely unrelated und not reproducable locally, some text saved to the database was not retrieved identically. We disabled this spec for now.
So far I am happy with tddium, it is a very lightweight CI service and in the general case, much easier to setup than a custom CI server. If we hadn’t have this multi-database setup, tddium would have been up and running within minutes. Pricing seems fair, although it lacks many features if compared to Jenkins CI. I am looking forward to its evolution and hope integration of our other apps will be smoother. :-)