Rails: Building Apps with Cucumber and Pickle

I'd often read about Cucumber, but had always been put off by the task of learning another abstract domain language to distract me from actually writing code. But as I kept reading more and more about it, curiosity got the better of me and I had to give it a try.

After a couple of weeks of learning to use Cucumber, I'm completely hooked.

What is Cucumber?

Cucumber grew out of RSpec as a language for describing user stories in behaviour driven design (BDD). Cucumber avoids the abstract and often incorrect, functional and technical documenting of the software process, instead encouraging you to write short, specific stories about an should do.

In Cucumber, these stories are described through number of individual steps that describe a situation, set of actions, and conditions to be met. For example, a Cucumber story to test logging out of an application might look something like:

Scenario: A logged in user wants to log out

  Given I am logged in

  And I click the "Log out" link

  Then I should not be logged in

  And I should be on the home page

  And I should see "You have been logged out"```

Stories are designed to be written and read by people, not machines. When you run your story through Cucumber, it applies some funky logic and regular expression matching to run your application code against the story's steps. Each step creates or checks the situation being described.

For example, the steps for the logging out feature above might be:

ruby# features/stepdefinitions/authenticationsteps.rb

Given /^I am logged in$/ do

controller.current_user = Factory(:user) # I've used FactoryGirl to create fixtures here


Then /^I should not be logged in$/ do

controller.currentuser.should benil

session[:userid].should benil


Thankfully, Cucumber comes with a collection of pre-defined steps that cover common situations, such as the Then I should see "{something}" and When I click "{some link}" steps in the previous example.

Cucumber with Pickle

Cucumber works well with a number of other gems, but one that you'll definitely want to use is pickle. Once installed, pickle gives you a collection of handy step definitions for creating a referring to new models in your stories.

In the example below, a new Post model is created and assigned the label "the post". The remaining steps can then refer to "the post" directly:

```ruby# features/publishing_posts.rb

Given a post "the post" exists with published: false

And "the post" belongs to me

When I am editing "the post"

And I click "Publish Post"

Then "the post" should be published

And I should see "Post Published"```

Why You Should Be Using Cucumber


The greatest benefit of Cucumber (and most test-driven methodologies) is that you gain an incredible amount of confidence in your code. Before any release, you can quickly and automatically check that your whole application is doing what you'd expect it to do. This makes releases a far less daunting experience.

It tests your entire application, from top to bottom

I'd always found testing the high-level functionality of a web app tricky with other test tools, including RSpec. Although they were great at checking very specific, model conditions, when it came to testing the working app as a whole, they never seemed to quite cut it.

Cucumber lets you write tests that drive through every layer of your application: views, controllers, models and other utility classes (such as email handling, see this great post on email_spec) can all be tested in a much more natural manner.

Stories are reusable

As you write more stories, you'll quickly build up a library of handy step definitions. You can use more advanced regular expressions to DRY those step definitions, and then re-use them in other parts of your project, or in other projects.

Your code is self documenting

One of the greatest benefits of Cucumber stories is that they act as effective documentation for your app. Cucumber can output its running descriptions in a number of formats, including HTML. Having this documentation automatically generated can give you even more assurance that your code is doing what you'd expect, and lets you answer those "what's supposed to happen if...?" questions with certainty.

Get Started

If you haven't tried Cucumber yet, I really recommend you take an hour to follow some of the tutorials. You definitely won't regret it. There's loads more tips and information available on the Cucumber website, as well as the official RSpec Book from The Pragmatic Bookshelf.

In the next post, I'll introduce Molehill, my first attempt at building an app the BDD way. In the meantime, if you'd like to check out the code and take a look at the Cucumber stories, you can find Molehill on github.