Gentlemen, Test Your Engines

9 Feb 2009

In my rails application, I’ve got an engine. I built it myself. It’s more than just a regular plugin, some external library that I trust will plug along by itself: it’s an integral part of my app. It’s got controllers and models, and even routes. It’s a first-class citizen.

When I develop my rails app, I run autotest. It runs my tests automatically when I change code, beeps at me angrily when I break something, and plays a soothing noise when all my tests pass.

So that’s all great. Except autotest wouldn’t run the tests I’ve included in my engine plugin. I had to do all that separately, even though I often work on the app and plugin together, as a unit. So I spent a couple hours and fixed that.

Briefly, to get autotest to test your Engines too:

  1. Update autotest and the Engines plugin
  2. Put an updated .autotest file in your Rails root
  3. Run autotest in your Rails root

I made minor modifications to autotest, so until (unless?) those changes get pulled into the main streams, you’ll have to use my autotest fork (or pull in my last commits to your own forks). You also may need an updated version of the Engines plugin (see below).

After you’ve got those libraries in place, you just need this custom .autotest. Put it in your rails root.

Ok, that’s it: just run autotest in your rails root, and your engines tests should be first class citizens. Depending on your project, you might need to tweak the autotest hooks. Adding more .autotest exceptions will make autotest faster (and not eat up your CPU) — I’ve included enough examples that it should be easy to figure out what’s going on.

Please contact me with changes or comments — just ping me with github magic, or contact me through one of the sites in my footer.

Addendum: Engine plugin testing general hints

There are a couple things that tripped me up when setting up my Engines tests.

test_helpers

I’ve got a test_helper.rb under vendor/plugins/my_engine/test/test_helper.rb , where I can add helper methods specific to testing my Engine. From there, I require my main test_helper: require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper'), so I get all the other setup (user login methods, fixtures, etc) I need for my tests.

This way, both your Engine and your main Rails tests have the same require line: require File.dirname(__FILE__) + '/../test_helper'. I find myself generating scaffolds/models and their associated tests in my main Rails application, and then moving controllers and tests between the main app and the Engine.

Fixtures

You can put fixtures under yourplugin/test/fixtures/. Unfortunately, they’ll just sit there and look pretty until you:

  1. Add Engines::Testing.set_fixture_path to your test_helper.rb, and
  2. Run rake test:plugins:setup_plugin_fixtures when you create or update your fixtures.

This way, fixtures from your main application, together with all your Engine plugin fixtures, are copied to a temporary folder and used for your tests.