Having built my feedback form and the action to which it submits, I am ready to work my way back out to the Cucumber scenario driving this particular feature:
Telling Webrat to click the "submit" button is not specific enough. Webrat needs a value or
id
attribute. So I will rewrite that step as:When I click the "Send Comments" buttonI can define that step with:
When /^click the "([^\"]+)" button$/ do |button_text|When I run this scenario, I find:
click_button button_text
end
Scenario: Give feedback to the authors of this fantastic siteHunh. Cannot find the "Send Comments" button? I was sure I had that in the Haml template:
Given 25 yummy meals
When I view the site's homepage
And I click "Send us comments"
Then I should see a feedback form
When I fill out the form with effusive praise
And click the "Send Comments" button
Could not find button "Send Comments" (Webrat::NotFoundError)
features/site.feature:53:in `And click the "Send Comments" button'
Then I should see a thank you note
...Ah. I gave the button a name, but not a value. Another obvious mistake on my part caught by Cucumber. I give the button a proper name:
%label
Message
%textarea{:name => "message", :rows => 8, :cols => 55}
%input{:type => "submit", :name => "Send Comments"}
...And then I re-run the Cucumber scenario, only to find:
%label
Message
%textarea{:name => "message", :rows => 8, :cols => 55}
%input{:type => "submit", :name => "b", :value => "Send Comments"}
Scenario: Give feedback to the authors of this fantastic siteThis error I do not quite understand. If I am working in the top level URL space of a site (e.g. http://eeecooks.com/feedback), then I expect any form submitted without an absolute URL to be relative to the top-level namespace (i.e.
Given 25 yummy meals
When I view the site's homepage
And I click "Send us comments"
Then I should see a feedback form
When I fill out the form with effusive praise
And I click the "Send Comments" button
PATH_INFO must start with / (Rack::Lint::LintError)
(eval):7:in `get'
features/site.feature:53:in `And I click the "Send Comments" button'
Then I should see a thank you note
email
should be submitted to http://eeecooks.com/email). No matter, I change:%form{:action => "email"}to:
%form{:action => "/email"}And finally that step is passing. The last step is to verify that the user now sees a "thanks for the feedback" message. It is a step so simple that it almost seems not worth bothering. Still, it cannot hurt to define, especially since the step is so easy to define:
Then /^I should see a thank you note$/ doFinally, I get to see my simple feedback scenario is all of its glory:
response.should have_selector("h1", :content => "Thank You")
end
Scenario: Give feedback to the authors of this fantastic siteAaarrrgh! Not found?! How can that be?
Given 25 yummy meals
When I view the site's homepage
And I click "Send us comments"
Then I should see a feedback form
When I fill out the form with effusive praise
And I click the "Send Comments" button
Then I should see a thank you note
expected following output to contain a <h1>Thank You</h1> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><h1>Not Found</h1></body></html>
(Spec::Expectations::ExpectationNotMetError)
features/site.feature:54:in `Then I should see a thank you note'
After much soul searching and questioning of my ability as a developer, I finally ask myself how could it not be found? It is clearly defined in my Sinatra application:
post '/email' doThe answer, of course, is in the first word of that code snippet:
message = <<"_EOM"
From: #{params[:name]}
Email: #{params[:email]}
#{params[:message]}
_EOM
Pony.mail(:to => "us _at_ eeecooks.com".gsub(/\s*_at_\s*/, '@'),
:subject => params[:subject],
:body => message)
haml :email
end
post
. The /email
action is only defined for POST actions, not GETs. Changing the form action definition in the Haml template will resolve everything:%form{:action => "/email", :method => "post"}Finally, I get:
cstrom@jaynestown:~/repos/eee-code$ cucumber features -n \Oops. An actual email is trying to go out there. If I had
-s "Give feedback to the authors of this fantastic site"
Sinatra::Test is deprecated; use Rack::Test instead.
Feature: Site
So that I may explore many wonderful recipes and see the meals in which they were served
As someone interested in cooking
I want to be able to easily explore this awesome site
Scenario: Give feedback to the authors of this fantastic site
Given 25 yummy meals
When I view the site's homepage
And I click "Send us comments"
Then I should see a feedback form
When I fill out the form with effusive praise
sendmail: 553 jaynestown.mail.rr.com does not exist
And I click the "Send Comments" button
Then I should see a thank you note
1 scenario
7 passed steps
sendmail
configured correctly, I would be spamming myself right now.Cucumber is an awesome full-stack testing tool, but, at least in this case, I do not want to test the entire stack. What I want to do is stub out the
Pony.mail
call right before the form is submitted:When /^I click the "([^\"]*)" button$/ do |button_text|That will not work because Cucumber don't do stubbing:
# Don't send email in tests
Pony.stub!(:mail)
click_button button_text
end
Scenario: Give feedback to the authors of this fantastic siteCucumber really is a full stack testing framework. Fortunately, Bryan Helmkamp has written some nice instructions for including RSpec stubbing and mocking in Cucumber. Following those instructions, I add this to my Cucumber's
Given 25 yummy meals
When I view the site's homepage
And I click "Send us comments"
Then I should see a feedback form
When I fill out the form with effusive praise
And I click the "Send Comments" button
undefined method `stub!' for Pony:Module (NoMethodError)
features/site.feature:53:in `And I click the "Send Comments" button'
Then I should see a thank you note
support/env.rb
:# RSpec mocks / stubsAnd now, I am done with this scenario:
require 'spec/mocks'
Before do
$rspec_mocks ||= Spec::Mocks::Space.new
...
end
After do
begin
$rspec_mocks.verify_all
ensure
$rspec_mocks.reset_all
end
...
Tomorrow, I will likely add another small feature to the feedback mechanism before moving onto RSS feeds.
No comments:
Post a Comment