Tuesday, October 25, 2011

When the Cucumber is mightier than the Pen - Fixing Rails 3 in Action

Aslak Hellesoy and the good people behind Cucumber have realized there was a problem in the Cucumber community. People were using web_steps to build, rather than just as a set of examples. So, the latest versions of cucumber have removed the creation of web_steps and the attendant files when you run the generator.

As Mr. Hellesoy noted in his blog entry, this is going to break a lot of Rails training materials which have come to rely on these files being available.

Having recently gotten a copy of Rails 3 in Action and noticing that an edit seems to be a ways off, I offer my humble solution for getting through chapter 3 of this book using the latest Cucumber. You can and probably should still read through the text that I skip in the book, as it does give you insights, but my path below will allow you to use Cucumber the 'right' way.


The trouble starts on Page 55

I have rewritten the Gherkin for the feature file. Notice the more domain language syntax?

Listing 3.8 
Feature: Create projects
In order to have projects to assign tickets to
As a user
I want to create them easily 
Scenario: Creating a project
Given I am on the homepage
When I navigate to the new project creation page
And I create a new project
Then I should be shown the project created verification message

Then skip to the portion about doing the db migration

rake db:migrate (page 56)
rake cucumber:ok

You can implement step definitions for undefined steps with these snippets:

Given /^I am on the homepage$/ do
  pending # express the regexp above with the code you wish you had
end
When /^I navigate to the new project creation page$/ do
  pending # express the regexp above with the code you wish you had
end
When /^I create a new project$/ do
  pending # express the regexp above with the code you wish you had
end
Then /^I should be shown the project created verification$/ do
  pending # express the regexp above with the code you wish you had
end


stick this in features/step_definitions/project_steps.rb


Given /^I am on the homepage$/ do
  visit('/')
end
When /^I navigate to the new project creation page$/ do
  click_link('New Project')
end
When /^I create a new project$/ do
  fill_in('Name', :with => 'TextMate 2')
  click_button('Create Project')
end
Then /^I should be shown the project created verification$/ do
  page.should have_content("Project has been created.")
end


The visit('/') is substituted for the path_to stuff from web_steps that is mentioned on page 56

basically we are sending it to the root 

continue to page 57-58

when editing the routes.rb file


  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => 'welcome#index'
  root :to => "projects#index"
...

continue through to page 61

when editing routes.rb


  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products
  resources :projects
You can continue on till Page 73 adding a title:

add the following line to the creating_projects.feature

And I should be on the project page for the new project

running rake cucumber:ok will give you the following step def to add to your file (project_steps.rb)

Then /^I should be on the project page for the new project$/ do
  pending # express the regexp above with the code you wish you had
end 
Then edit this to:
Then /^I should be on the project page for the new project$/ do
  current_path.should == project_path(Project.find_by_name!('TextMate 2'))
  page.should have_content("TextMate 2 - Projects - Ticketee")
end

This replaces the paths.rb stuff and the other web_steps.rb stuff referred to on page 73

do read the stuff on the bottom of page 73-74 about the dynamic method invocation

rake cucumber:ok

will give following error:


"expected there to be content "TextMate 2 - Projects - Ticketee" in "Ticketee\n\n  \n    Project has been created.\n  \nTextMate 2\n\n\n" (RSpec::Expectations::ExpectationNotMetError)"
(instead of the expected #has_content? error mentioned in the text)

both are Rspec type errors though

continue on with page 74-77

New Cucumber Feature for Page 77

make your features/creating_projects.feature look like:

Feature: Creating projects
  In order to have projects to assign tickets to
  As a user
  I want to create them easily 
  Background:
     Given I am on the homepage
     When I navigate to the new project creation page

  Scenario: Creating a project 
    And I create a new project                           
    Then I should be shown the project created verification
    And I should be on the project page for the new project 
  Scenario: Creating a project without a name
     And I try to create a project without a name
     Then I should be informed that the project has not been created
     And I should be told that the name is required

rake cucumber:ok

Add these to the project_steps.rb

When /^I try to create a project without a name$/ do
  pending # express the regexp above with the code you wish you had
end
Then /^I should be informed that the project has not been created$/ do
  pending # express the regexp above with the code you wish you had
end
Then /^I should be told that the name is required\.$/ do
  pending # express the regexp above with the code you wish you had
end

Implement them as per below:

When /^I try to create a project without a name$/ do
  click_button('Create Project')
end
Then /^I should be informed that the project has not been created$/ do
  page.should have_content("Project has not been created.")
end
Then /^I should be told that the name is required\.$/ do
  page.should have_content("Name can't be blank")
end

This should get you on track to continue at the bottom of page 77.


I realize my Tests are not ideal. For instance the second scenario could also check that on a failed verification you stay on the New Project page. I was simply trying to mirror what the book had and put it into a more business domain syntax. It also nicely shows the division between the Gherkin and the step definitions.

Hopefully this is helpful to others. As I have time to go through the book, I will try to add further updates, but this should give most a good start in the right direction.

I am eager to see other modifications others make to this.