Browser-less testing

testing should be iterative, not linear

For me, Ruby on Rails has made development fun again. Why? Simple, because I'm better at my job when I use it. So, why am I better? Also simple: because I can test all of the code I write, and even better, I absolutely enjoy writing tests.

During the first few months of using Rails, I debated the merit of the testing framework for this reason: it seemed that writing and maintaining test cases approximately doubled development time. Also, it felt like a chore; something I had to do after all the fun stuff was done. I forget now where I read that famous line, but somebody, somewhere said, quite plainly, if writing test cases feels like a chore, you're going about it all wrong.

So, for me, the question was: how do I prevent testing from feeling like it's a chore? The answer came quickly, because above all else, the one routine I've always disliked is browser-centric testing. By that, I mean the mind-numbing exercise of refreshing your browser, going through a login process, followed by several clicks and a form submission to ensure that changing a variable name from 'monkee' to 'monkey' didn't break anything. If I could take the browser out of the equation, life would be better.

What follows is a step-by-step guide for testing a screen without using your browser. Give it a shot and see if you like it, and if so, consider adopting my mantra: "Loathe F5".

Functional test

  1. Let's assume we're functional-testing a typically Rails controller action.
  2. Create your new method, let's call it 'list' and it lives in the doggie_doors controller. It's just a stub for now.
  3. Create the corresponding test case stub in doggie_doors_controller_test.rb.
  4. If needed, add fixtures data.
  5. Run the test to make sure files are in the right place, etc.
  6. Invoke the action as usual and add the common functional assertions 'assert_template' and 'assert_response' to the test case and run it again.
  7. Your test should fail, that's good.
  8. At this point, you're in that warm fuzzy place of iteratively testing code and adding assertions while simultaneously maturing the codebase. I love this place. This place loves me. When complete, you've got a fully-functional code unit complete with a regression test of your business logic.

The console


  ruby script/console
  # pass the --sandbox flag to rollback
  #   db commands. especially useful if
  #   if you need to run in production.

From Rails Recipes: the console is your friend. Use it at all times. For the love of Sela Ward, don't use the browser to test whether or not a controller instance responds_to?:am_i_a_sheep?

Integration

This is actually a new tool for me, thanks to the Rails Cookbook. Here's what you can do, after firing up the landlord.

  # send a message to app global var
  # returns HTTP response code
  app.get '/doggie_doors/list' # app.class = ActionController::Session::Integration
  # returns 200, 404, 500, 302, etc.
  # call the response obj
  app.response.body

Basically, you can do anything you'd normally do in an integration test, so you have lots of options. For now, just know that you can mimic GETs and POSTs as if you'd fired up that dirty little browser of yours.

Selenium is elemental

The Selenium UI testing tools, if you haven't seen them, are a thing of beauty. Get the Rails plugin and the Firefox IDE add-on. Granted, it takes awhile to get the hang of the tools, but once you do, they are terrific. I also have one other concession: you have to fire up the browser for Selenium tests... but but but... once you create the first version of a test, subsequent changes take very little in-browser time. After that, even though the browser is open while you're running Selenium tests, you're letting someone else be the mouse-click monkey.

The End

Using the above tools and techniques, my time spent in-browser has dropped probably 70%, and that might be low. Give it a shot, I'd like to hear what you think.

...Update

I finally found time to try out 3 popular Rails testing gems/plugins: Mocha, Autotest, and Continuous Builder. Mocha and Autotest look especially promising, as would CB if I were hosting the svn repo internally (but Google Code it is). More to come ...

Posted by Luke on Sunday, June 10, 2007

Comments (0)


No comments.