---
title: 'Turnip: A Tasty Cucumber Alternative?'
teaser:
tags: web,testing
author: Harlow Ward
published_on: 2012-04-21
---

![''](https://images.thoughtbot.com/turnip-tasty-cucumber-alternative/vegetables.jpg)

We've used [Cucumber](http://cukes.info/ "Cucumber") heavily and successfully on client work, internal projects, and open source. We also love [RSpec](https://github.com/rspec/rspec-rails), so when we heard that [Turnip](https://github.com/jnicklas/turnip) would give the ability to run Gherkin based integration tests in our RSpec suite it was a no-brainer for us to try it out on a project.

## Highlights of Turnip

* Integrates directly into your RSpec test suite
* Features and Step definitions live in the spec directory
* No need to maintain two configuration files
* Uses Ruby style symbols instead of regular expressions in step definitions
* No need to write Given/When/Then in the step definitions file
* Speed boost when running unit tests and integration tests together

We use Cucumber integration tests in [thoughtbot's clearance gem](https://github.com/thoughtbot/clearance). In the example below I remove Cucumber and replace it with Turnip.

## Steps used to change from Cucumber to Turnip

* Set up your `features` directory inside the `spec` directory
* Remove the Given/When/Then's from the step definitions
* Replace regular expressions in the step definitions with Ruby style symbols

Cucumber and Turnip use the same Gherkin syntax:

    Scenario: Visitor signs up with valid data
    When I sign up with "email@example.com" and "password"
    Then I should be signed in

Change the step definitions from Cucumber to Turnip style:

    # Cucumber step definition
    When /^I sign up (?:with|as) "(.*)" and "(.*)"$/ do |email, password|
    visit sign_up_path
    page.should have_css("input[type='email']")
    fill_in "Email", :with => email
    fill_in "Password", :with => password
    click_button "Sign up"
    end

    # Turnip step definition
    step "I sign in with/as :email and :password" do |email, password|
    visit sign_in_path
    page.should have_css("input[type='email']")
    fill_in "Email", :with => email
    fill_in "Password", :with => password
    click_button "Sign in"
    end

## Run the test suite

An advantage having everything running through RSpec is we get an immediate boost in speed when running the whole test suite. With Cucumber running `Rake` will run the RSpec and Cucumber tests (the Rails environment will be loaded twice). With Turnip all tests run through directly through RSpec (the Rails environment is only loaded once).

We save around 12 seconds when running the entire suite:

    # Rake running RSpec and Cucumber
    ~/Development/clearance_cucumber(master) $ time rake
    /Users/training/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S rspec ./spec/controllers/pages_controller_spec.rb ./spec/helpers/application_helper_spec.rb

    Finished in 0.10696 seconds
    1 example, 0 failures
    /Users/training/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S bundle exec cucumber --profile default
    Using the default profile...
    .................................................

    13 scenarios (13 passed)
    49 steps (49 passed)
    0m1.729s
    rake 19.97s user 2.71s system 98% cpu 22.960 total

    # RSpec with Turnip
    ~/Development/clearance_turnip(master?) $ time rspec
    ..............

    Finished in 1.84 seconds
    14 examples, 0 failures, 0 pending
    rspec 8.85s user 1.06s system 95% cpu 10.362 total

## Takeaways

* Great light-weight solution for anyone already using RSpec
* Step definitions easier to read than their Cucumber counterparts
* Low barrier to entry for developers new to integration testing
