Making your cucumber step definitions more readable with RSpec binary matchers

When using RSpec expectations and matchers to assert something binary, it’s easy to write a step definition that looks something like this:

on EtsyTreasuryPage do |page|
  page.item_info_div.exists?.should be_true
end

There are other ways to make this step more readable. When ever you are checking a method with a question mark following its name, you can use the .should methods on its parent, and pass the name of the method you are expecting. For example, this is how you would write the above code.

on EtsyTreasuryPage do |page|
    page.item_info_div.should be_exists
end

This will execute exactly the same as the first example, although it’s not quite as nice to read. To make it easier to read, we can monkey patch the Watir-WebDriver class to have a method alias.

Putting this code in a file you load:

module Watir
  class Element
    alias_method :shown?, :exists?
  end
end

means that you are monkey patching the Element class, and can now use .shown? instead of, or in addittion to, .exists?.

This means your step definition is now highly readible:

on EtsyTreasuryPage do |page|
    page.item_info_div.should be_shown
end

Update: 10 August 2011

Make sure you have the rspec gem installed (either gem install, or via bundler) to ensure you have access to these methods.

6 thoughts on “Making your cucumber step definitions more readable with RSpec binary matchers

  1. A little-known feature of Cucumber that works really well with screenshots:
    embed(screenshot, ‘image/png’)

    The HTML formatter shows embedded screenshots in an expandable clicky thing.

  2. Yes, rspec rocks.
    Another example from our codebase. We have introduced has_user_logged_in? method for the base page class of our application, which determines whether user is logged in on current page or guest by some common visual means (signout link in the header, etc) or based on cookie.
    #just a dump code
    class BasePage
    def has_user_logged_in?

    end
    end

    #test
    login_page.should_not have_user_logged_in
    login_page.login_as “vasyapupkin”, “balalayka”
    home_page.should have_user_logged_in

Comments are closed.