---
title: Five Ridiculously Awesome Cucumber (and Webrat) Features
teaser:
tags: web,rails,testing
author: Josh Clayton
published_on: 2009-09-16
---

[Cucumber](http://cukes.info), if you haven't heard, is the Next Big
Thing&trade;.  It affords developers the ability to write human-readable
integration tests.  Even though it's only at version 0.3.101, it's
full-featured with a handful of hidden gems.  Here are five of my favorites.

## Running Targeted Features with Cucumber Profiles

In a Rails application, if a `RAILS_ROOT/cucumber.yml` file is present, you can
store named
[Cucumber](http://wiki.github.com/aslakhellesoy/cucumber/using-rake)
[profiles](http://wiki.github.com/aslakhellesoy/cucumber/cucumberyml).  This
becomes handy if you're running your features in different environments (e.g.
Selenium or a simulated browser).

Here's an example `cucumber.yml` file:

```yaml
default: >
  --format pretty -r features/support/env.rb -r features/support/plain.rb
  -r features/step_definitions features
selenium: >
  -r features/support/env.rb -r features/support/selenium.rb
  -r features/step_definitions features
html_output: >
  --format html -r features/support/env.rb -r features/support/plain.rb
  -r features/step_definitions features
```

Within your terminal, you can run:

```sh
cucumber -p html_output
```

## Tagging Scenarios

Another handy Cucumber feature is the ability to tag scenarios.  Tagging a
scenario is achieved by simply adding `@tagname` above the scenario definition,
as such:

```cucumber
@tagname
Scenario: User is not signed up
  Given no user exists with an email of "email@person.com"
  When I go to the sign in page
  And I sign in as "email@person.com/password"
  Then I should see "Bad email or password"
  And I should not be signed in
```

To run scenarios with a specific tag:

```sh
cucumber --tags @tagname
```

To exclude scenarios with a certain tag, prefix the tag with a tilde:

```sh
cucumber --tags ~@wip
```

A common tag name that Cucumber supports out of the box is `@wip` (work in
progress) and provides rake tasks to accommodate using this pattern:

```sh
rake cucumber:wip # runs only scenarios with a wip tag
rake cucumber:ok # runs all scenarios without a wip tag
```

One thing to note here is that Cucumber will exit with a status of 1 if your
`@wip`-tagged scenarios pass (it's a reminder that they're not works in
progress anymore since they pass).

## Assigning Data with Tables

Cucumber supports the use of tables, which can be handy for any number of
things; my favorite uses are populating fields in a form and instantiating an
ActiveRecord object with values defined.

Webrat gives us a step definition for filling in form fields (within
`features/step_definitions/webrat_steps.rb`) and can be used as such:

```cucumber
When I fill in the following:
  | First Name            | John                 |
  | Last Name             | Doe                  |
  | Email                 | john.doe@example.com |
  | Password              | password             |
  | Password Confirmation | password             |
```

With an ActiveRecord object and FactoryBot:

```cucumber
# step
Given a customer exists with the following attributes:
  | Name      | Huge Local Company |
  | Code      | HLC                |
```

```ruby
# step definition
Factory.factories.each do |name, factory|
  Given /^an? #{name} exists with the following attributes:$/ do |attrs_table|
    attrs = {}
    attrs_table.raw.each do |(attr, value)|
      sanitized_attr = attr.gsub(/\s+/, "-").underscore
      attrs[sanitized_attr.to_sym] = value
    end
    Factory(name, attrs)
  end
end
```

## Segregating Selenium and Simulated Browser Steps

If you've been ambitious enough to get your features running with Selenium, you
already know that doing so can add a significant amount of time to your tests.
Webrat is kind enough to provide you execution blocks that run in specific
modes, which makes for some snappier tests when you do run features with
Webrat.

For example, within a step that outlines signing in:

```ruby
webrat.automate do
  When %{I sign in as "#{email}/#{password}"}
end

webrat.simulate do
  visit "/session",
        :post,
        :session => {:email => email, :password => password}
end
```

Webrat will determine if you're simulating a browser and execute
`webrat.simulate` if that's the case; otherwise, it'll run the code within the
`webrat.automate` block.  This can be really helpful if you're testing the
ability to delete an item (especially if there's a confirmation dialog).

## Displaying Page Responses within a Scenario

If you're having trouble getting a feature to pass and want to view the page,
you can add in a step to have it save the result <abbr title="HyperText Markup
Language">HTML</abbr> and open the page in your default browser.

```cucumber
Scenario: User is not signed up
  Given no user exists with an email of "email@person.com"
  When I go to the sign in page
  Then show me the page # saves the HTML of that page and opens the file
  And I sign in as "email@person.com/password"
  Then I should see "Bad email or password"
  And I should be signed out
  Then show me the page # more HTML output
```

This tends to be much more convenient than adding this into your step
definition:

```ruby
puts response.body.inspect
```

There are, as always, a couple of caveats.  The <abbr title="HyperText Markup
Language">HTML</abbr> it generates won't be relative to your public folder so
Javascript and <abbr title="Cascading Style Sheets">CSS</abbr> probably won't
load correctly.  It also doesn't persist form values, so if you run it after a
step like 'I fill in "field" with "value"', it won't keep that data.  It also
creates a timestamped html file within your `RAILS_ROOT` folder.  A simple fix
to ensure this doesn't get committed with git would be to add the following line
to your `.gitignore` file in the project:

```gitignore
webrat-*.html
```

## Finally

Don't forget to [read the docs](http://wiki.github.com/aslakhellesoy/cucumber)!
They cover everything you'd ever want to know about Cucumber and how to use it
effectively.  I've listed only a handful of awesome features Cucumber and Webrat
have to offer, but each has helped me in one way or another over the course of
the past year.  Hopefully they'll be as much use to you as they were me.

## What's next

[![Ruby Science](http://media.tumblr.com/tumblr_mez6ck7Fkl1qzocnw.png)](http://rubyscience.com?utm_source=giantrobots&amp;utm_medium=blog&amp;utm_campaign=remarket&amp;utm_term=testing)

Detect emerging problems in your codebase with. We'll deliver solutions for
fixing them, and demonstrate techniques for building a Ruby on Rails application
that will be fun to work on for years to come.

[Grab a free sample of Ruby Science today!](http://rubyscience.com?utm_source=giantrobots&amp;utm_medium=blog&amp;utm_campaign=remarket&amp;utm_term=testing)
