2010-05-10

Replace Cucumber With Webrat

I was very happy with Cucumber...until a couple of things happened.

First, there was a pairing session three months ago. I pair programmed with a really smart Ruby developer that was not familiar with testing. After a day with Cucumber, he said "Testing really slows me down." I was surprised. On reflection, I think learning Gherkin was a significant barrier to adopting Cucumber. This developer had questions like "How do you know how to phrase the sentences?"

Second, I read How to implement UI testing without shooting yourself in the foot. This article talks about the importance of creating layers of abstraction to protect your UI tests from change. After reading this, I understood a frustration I had with Cucumber that I couldn't previously explain. Gherkin is not Ruby. Doing an extract method on a Cucumber test is painful, because you have to translate Gherkin to Ruby.

After reading that article, I did an experiment. I rewrote some Cucumber tests using Webrat. You can see how my Cucumber tests used to look. Here's how my integration tests look using Webrat:
require "test_helper"

class IntegrationTest < BaseTest
  context "Application" do
    setup do
      standard_setup
    end

    should "Display correct start time when a new class is created (i.e. test chronic)" do  
      ACTING_CLASS = {
        :start_time => "04:00 pm", 
        :end_time => "05:00 pm", 
        :description => "Acting for Beginners"
      }
      log_in_as JERRY
      create_a_class ACTING_CLASS
      visit edit_class_page(ACTING_CLASS)
      should_see "4:00 PM"
      should_see "5:00 PM"
    end

    should "Navigate to second page of users (i.e. test will_paginate)" do  
      create_users :with_first_name => "Elaine", :count => User::USERS_PER_PAGE
      create_users :with_first_name => "Newman"
      log_in_as JERRY
      visit admin_users_path(:subdomain => SUBDOMAIN)
      should_not_see "Newman"
      should_see "Elaine"
      click_link "Next"
      should_see "Newman"
    end  

    should "Signup and login (i.e. test authlogic)" do  
      sign_up_as KRAMER
      should_see "Registration successful."
      should_see "Logout"
      click_link "Logout"
      should_not_see "Logout"
      log_in_as KRAMER
      should_see "Logout"
    end  
  end
end

Here's the BaseTest class, which the above class extends.

I'm happy with the result. Since I'm no longer using Cucumber or RSpec, I've switched to Watchr for continuous testing. I chose Watchr over Autotest, because Autotest conventions are not transparent, and because Autotest is too much trouble to get working when it fails.

Here's my Watchr script for Rails.

Here's my Watchr script for non-Rails Ruby projects.

If you want color highlighting with Watchr, use the 'redgreen' gem (not the 'mynyml-redgreen' gem).

Here's my current Rails testing stack: