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.

4 comments:

oldroy said...

Thanks,
I had been struggling with this. The simple change to a more declarative style of the cuke story and using capybara dsl makes everything much more straightforward.

How would you flesh out your rspec specs for your model and your controller as you go? Any examples?

Radar said...

Thank you so much for doing this :) I'll bookmark it and link it to people who ask now. Until the edit is done.

Unknown said...

Thanks, really helpful comments.

andy said...

Thanks for doing this. The fun doesn't end in chapter 3, as the Factory Girl syntax, etc. has changed as well. I wrote a post to get people started:
http://andyhill.us/codeblog/2012/10/14/more-rails-3-in-action-fun-chapter-4/

Post a Comment