June 5, 2010

Rails 3, RSpec, and Cucumber

This is a walkthrough of getting Rails 3 up and running with RSpec and Cucumber.

Rails 3 and Rails 2 don’t play nicely together, so I recommend you use RVM to create a separate gemset for Rails 3. (I did all this under Ruby 1.9.1 just for fun. YMMV.)

Rails 3

To install the latest rails pre-release (Rails 3 beta 3 at the time of this writing):

gem install rails --pre

It’s got a lot of dependencies nowadays, so enjoy watching them all scroll past.

Now let’s create a little Rails app to try it out. The laws of Rails physics dictate that it must be a blog, so:

rails new blog --skip-testunit

(If you’re on a version of Rails 3 earlier than beta 4, you’ll need to leave out the “new” from the above command.)

Given we’re going to be installing RSpec, I've told it to skip over creating the test directory.

If you’re a git user (which you should be), now is a good time to check stuff in:

cd blog
git init
git add .
git commit -m "Initial import."

Rails 3 has, rather thoughfully, already set up a .gitignore file for you, and sprinkled .gitkeep files in directories that need to stick around.

RSpec

Ok, now you need to start getting friendly with Bundler. Edit your app’s Gemfile and add the following:

group :test do
  gem 'rspec-rails', '>= 2.0.0.beta.10'
end

Then, to install the gems, just run this from your app’s root directory:

bundle install

Now to add the necessary bits and bobs to your app:

script/rails generate rspec:install

(Notice how all the various commands under the script directory have gone away in Rails 3? Everything now lives under the single rails command.)

Magic! Now you can tell Rails 3’s fancy new generators to always use RSpec rather than Test::Unit. Open up your config/applicaton.rb and find the commented out section relating to generators. Add this:

config.generators do |g|
  g.test_framework :rspec
end

Let’s try it out:

$ script/rails generate model post title:string body:text published:boolean
      invoke  active_record
      create    db/migrate/20100605021005_create_posts.rb
      create    app/models/post.rb
      invoke    rspec
      create      spec/models/post_spec.rb

Check it out! A migration, a model, and a spec file. Fancy, huh? Does it really work?

$ rake db:migrate
==  CreatePosts: migrating ====================================================
-- create_table(:posts)
   -> 0.0021s
==  CreatePosts: migrated (0.0022s) ===========================================

$ rake spec
*
Finished in 0.01027 seconds
1 example, 0 failures, 1 pending

Pending:
  Post add some examples to (or delete) ./spec/models/post_spec.rb (Not Yet Implemented)
   # ./spec/models/post_spec.rb:4

Yep, sure does! It even gives you a helpful pending spec to cajole you into writing some proper tests.

Cucumber

Setting up Cucumber is a similar process. First add this to your Gemfile:

group :cucumber do
  gem 'capybara'
  gem 'database_cleaner'
  gem 'cucumber-rails'
  gem 'cucumber', '0.7.3'
  gem 'rspec-rails', '>= 2.0.0.beta.10'
  gem 'spork'
  gem 'launchy'    # So you can do Then show me the page
end  

Then use Bundler to install everything:

bundle install

And set up your Rails app:

script/rails generate cucumber:skeleton --rspec --capybara

Now you’re off and running, and can start adding features and step definitions to your heart’s content.

I recommend not using the feature generator. It generates feature-coupled steps, which is considered an anti-pattern. Write your own feature files from scratch, and put your steps in files corresponding to the models they work with. The RSpec Beta Book has really good advice on how to structure your features and steps.

(As of this writing, rake cucumber spits out a rather noisy warning when you run it. If you’re lucky, they've already been fixed by the time you’re reading this. If not, you can safely ignore them.)

What Now?

I strongly recommend you check out the latest RailsCasts on Rails 3, in which Ryan Bates is doing an awesome job of covering the best new features.

Awesome post! Thank you for the step by step description.

June 9, 2010

Hey great article. Very helpful for me :)

I would just add one thing: make sure that the rubygems version is 1.3.6 or higher, as anything before that seems to cause a ton of warnings before any cucumber or rake command.

Thanks!

June 11, 2010

Thanks for the great info. I found that everything installed fine but when I tried running cucumber it didn’t work. I removed the version parameter for cucumber in the gemfile, rebundled and it all worked. This installed v0.8.3. With this version the generate command is now cucumber:install instead of cucumber:skeleton.

June 18, 2010

I got no such file to load — gherkin/parser/tag_expression

when trying this with Rails 3.0.0.rc

I changed the cucumber requirement from ‘0.7.3’ to ‘0.8.5’ and it works. The moral of the tale: Check for the latest cucumber version!

August 3, 2010

This seemed to work for me: ruby script/rails generate cucumber:install —rspec

coder_tim
August 6, 2010

Thanks for the writeup Pete, great stuff! I didn’t see the pending spec when I ran ‘rake spec’ and then found this that explains why:

http://blog.davidchelimsky.net/2010/07/11/rspec-rails-2-generators-and-rake-tasks-part-ii/

After making the change to put rspec-rails in :development things are all good.

August 10, 2010

Would you happen to know where script/spec has gone? Rake spec works fine, but how would I run an individual spec? If I use the global spec command I get: .rvm/rubies/ruby-1.8.7-p299/lib/ruby/site_ruby/1.8/rubygems.rb:335:in `bin_path': can’t find executable spec for rspec-2.0.0.beta.19 (Gem::Exception).

August 11, 2010

This all works fine for me until “script/rails generate cucumber:skeleton —rspec —capybara” which results in “Could not find generator cucumber:skeleton”.

My only deviation from the instructions above is that I'm specifying ‘rspec-rails’, ‘>= 2.0.0.beta.10’ and ‘cucumber’, ‘0.8.5’.

August 15, 2010

Thanks for the helpful post! I noticed a small typo: apparently as of rails 3.0.0rc, the arg is —skip-test-unit (note extra dash). I think it doesn’t affect the outcome of the content here, but it may surprise some folks that the stock tests would get created anyway.

Scott Rehorn
August 17, 2010

tomtt,

The spec command is gone in rspec 2. It’s become “rspec”.

If you want to use spec for say rspec 1.3.0, you’ll want to do “spec 1.3.0 spec/something”

Take a look here for info: https://rspec.lighthouseapp.com/projects/5645/tickets/953-having-rspec2-on-the-system-breaks-rspec-13#ticket-953-15

August 26, 2010

So this post inspired me to update a project of mine called Beet. The steps above are simple, but I hate repeating them on each new idea/prototype/etc, so I've updated Beet to a) work with rails 3 and b) do these steps for you.

You can take a look at the rails 3 branch here:

http://github.com/jackdempsey/beet/tree/rails3

Currently you’ll need the source checked out to do this, but once you've cloned it, you can quickly repeat the above steps with just this command:

$ beet_top_level/bin/beet -g -r rails3/testing/cucumber

-g generates a new project, and -r specifies a recipe to run. This does assume that your rails command is bound to the rails 3 version, and the recipe currently doesn’t do the —skip-test-unit piece. I'm thinking about allowing recipes to setup options for the rails command itself, but that will require some more rejiggering.

Anyway, hope you find it useful.

August 27, 2010

Yes. Great post. Thank you for the info!

eric hosick
August 27, 2010

Steve Jorgensen,

You need use:

rails g cucumber:install —rspec —capybara

mtfk
October 12, 2010

Thanks for this intro, but please update the cucumber version to 0.8.5. I also had issues with 0.7.3.

thanks!

Chris Lemcke
November 30, 2010

I did what you say, but I commented out the gem versions, so I will get newest cucumber and rspec gems. Got 0.10.0 and 2.2.0, respectively

And I get this:

$ cucumber features/transliterate.feature 
Using the default profile...
no such file to load -- spec/expectations (LoadError)
(...stacktrace...)

Any hint where should I look?

December 9, 2010

I get it too. Cucumber 0.10.0 rspec (2.4.0, 2.1.0, 1.3.1) rspec-rails (2.4.1, 2.1.0, 1.3.3) rspec-expectations (2.4.0, 2.1.0) Jruby 1.6.0 RC1 on Solaris

group :test, :cucumber do gem ‘cucumber-rails’ gem ‘spork’ gem ‘webrat’ gem ‘factory_girl’ end

I tried with fresh features/support/env.rb, and i tried adding this to features/support/paths.rb: World(NavigationHelpers) World(Rack::Test::Methods) World(Webrat::Methods) World(Webrat::Matchers)

Anders Lundström
February 5, 2011

Great post, too bad I didn’t start this at the beg. of the project. I have 5 failures and 30 pending to sort through now!

March 9, 2011

Thank you man! You really save my day !

SimeON
June 10, 2011

Thank you man! You really save my day ! (2)

December 29, 2011

Hi all, im new in cucumber/watir and have any question: can you help me please ?

i don’t know how do for example use the sentences cucumber into ruby class.

I knew for java have so:

import cucumber.annotation.en.Given;

public class SomeOtherStepsdef {

@Given("^the following users$")
public void the_following_users(List<Entry> entries) {
    // iterate through the list and do something
}

for ruby what is the gem ?

sasan
June 14, 2012

Yesterday was brutal for me. I was lucky I only had one class to teach after I threw up the first time. I had to take 10 mitunes from my class to run to the staff bathroom and have the rest of my lunch violently force its way up. My body had drained all its fluids 40 mitunes later, so I was basically choking on this thick sludge as it made its way up my throat.[descriptive enough for ya? haha]I was weak today, but my stomach hasn’t given me any troubles. Luckily I have good co-teachers and some compassionate students, otherwise yesterday would've been a nightmare!Glad to hear all your things are being sorted out. It can be a nerve-wracking process trying to seal the deal on these things when you have to leave the country so soon!

September 6, 2012

8iSvHb <a href="http://jfgqjabqeuhq.com/">jfgqjabqeuhq</a>

September 7, 2012

En8SAo <a href="http://oxvayiqjvngz.com/">oxvayiqjvngz</a>

September 9, 2012
  1. Use Markdown for formatting.

  2. I’ll keep your email address private.