Outside In Development With Cucumber - Presentation Transcript
Outside-In
Development
With
Ben Mabey
Saturday, March 14, 2009
Who’s my
audience?
Saturday, March 14, 2009
Saturday, March 14, 2009
Scenario: planning meeting
Given I am a Software Developer
When I am given a feature request
Then I should...
Saturday, March 14, 2009
What is the most
CRITICAL
word to keep in mind?
Saturday, March 14, 2009
W
Saturday, March 14, 2009
Scenario: planning meeting
Given I am a Software Developer
When I am given a feature request
Then I should ask why.
Saturday, March 14, 2009
_why
Saturday, March 14, 2009
Why?
Saturday, March 14, 2009
Feature Request:
Print Reports
Story from
Thought works:
http://
www.theregister.co.uk/
2007 /06/25/
Saturday, March 14, 2009
Saturday, March 14, 2009
Protect Revenue
Increase Revenue
Manage Cost
Saturday, March 14, 2009
* not executed
* documentation value
Feature: title * variant of contextra
* business value up front
In order to [Business Value]
As a [Role]
I want to [Some Action] (feature)
Saturday, March 14, 2009
There is no template.
What is important to
have in narrative:
* business value
* stakeholder role
* user role
* action to be taken by
user
Saturday, March 14, 2009
Scenario: title
Given [Context]
When I do [Action]
Then I should see [Outcome]
Saturday, March 14, 2009
Scenario: title
Given [Context]
And [More Context]
When I do [Action]
And [Other Action]
Then I should see [Outcome]
But I should not see [Outcome]
Saturday, March 14, 2009
project_root/
|
`-- features
Saturday, March 14, 2009
project_root/
|
`-- features
|-- awesomeness.feature
|-- greatest_ever.feature
Saturday, March 14, 2009
project_root/
|
`-- features
|-- awesomeness.feature
|-- greatest_ever.feature
`-- support
|-- env.rb
`-- other_helpers.rb
Saturday, March 14, 2009
project_root/
|
`-- features
|-- awesomeness.feature
|-- greatest_ever.feature
`-- support
|-- env.rb
`-- other_helpers.rb
|-- step_definitions
| |-- domain_concept_A.rb
| `-- domain_concept_B.rb
Saturday, March 14, 2009
Step
Given a widget
Saturday, March 14, 2009
Step Definition
Given /^a widget$/ do
Given a widget #codes go here
end
Saturday, March 14, 2009
Step Definition
Step Mother
Given /^a widget$/ do
Given a widget #codes go here
end
Saturday, March 14, 2009
Step Definition
Step Mother
Given /^a widget$/ do
Given a widget #codes go here
end
Saturday, March 14, 2009
Outside-In
Saturday, March 14, 2009
Saturday, March 14, 2009
Saturday, March 14, 2009
Write Scenarios
Saturday, March 14, 2009
Steps are pending
Saturday, March 14, 2009
Write Step Definition
Saturday, March 14, 2009
Go Down A Gear
Saturday, March 14, 2009
RSpec
Saturday, March 14, 2009
RSpec
We ain’t got
no RSPEC!
Saturday, March 14, 2009
RSpec, TestUnit, etc
Saturday, March 14, 2009
Write Code Example
(Unit Test)
Saturday, March 14, 2009
Make Example Pass
Saturday, March 14, 2009
REFACTOR!!
Saturday, March 14, 2009
Where Are we?
Saturday, March 14, 2009
Continue until...
Saturday, March 14, 2009
REFACTOR
and
REPEAT
Saturday, March 14, 2009
features/manage_my_wishes.feature
Feature: manage my wishes
In order to get more stuff
As a greedy person
I want to manage my wish list for my family members to view
Scenario: add wish
Given I am logged in
When I make a \"New car\" wish
Then \"New car\" should appear on my wish list
Saturday, March 14, 2009
Saturday, March 14, 2009
Line # of scenario
Saturday, March 14, 2009
Saturday, March 14, 2009
I can has backtraze?
Given I am logged in #features/manage_my_wishes.feature:8
Saturday, March 14, 2009
Saturday, March 14, 2009
features/i_can_has_wishez_plz.feature
OH HAI: I CAN HAS WISHEZ PLZ
SO DAT I CAN HAS HUGS TIEM AN PLAY TIEM AN SLEEP TIEM AN NOM TIEM
AS NICE GREEDEE KITTEH
I CAN PLZ MANEGE TEH WISHEZ
MISHUN: MAK NEW WISH
GIVN I AM LOGGD IN
WEN I MAK \"CHEEZBURGER\" WISH
DEN I C \"CHEEZBURGER\" ON ME WISHEZ LIT
Saturday, March 14, 2009
Saturday, March 14, 2009
Saturday, March 14, 2009
cucumber some.feature --language en-lol
Saturday, March 14, 2009
cucumber some.feature --language en-lol
Saturday, March 14, 2009
Saturday, March 14, 2009
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
end
Test Data Builder / Object Mother
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
end
Fixture Replacement, Fixjour, Factory Girl, etc
spec/fixjour_builders.rb
Fixjour do
define_builder(User) do |klass, overrides|
klass.new(
:email => \"user#{counter(:user)}@email.com\",
:password => 'password',
:password_confirmation => 'password'
)
end
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Webrat / Awesomeness
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Webrat / Awesomeness
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Webrat / Awesomeness
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
features/support/env.rb
require 'webrat'
Webrat.configure do |config|
config.mode = :rails
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Webrat / Awesomeness
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
features/support/env.rb
require 'webrat'
Webrat.configure do |config|
config.mode = :rails
end
Adapter
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Webrat / Awesomeness
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
features/step_definitions/webrat_steps.rb
When /^I press \"(.*)\"$/ do |button|
click_button(button)
end
19 Steps Out-of-box
When /^I follow \"(.*)\"$/ do |link|
click_link(link)
end
When /^I fill in \"(.*)\" with \"(.*)\"$/ do |field, value|
fill_in(field, :with => value)
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
session[:user_id].should == @current_user.id
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
session[:user_id].should == @current_user.id
controller.current_user.should == @current_user
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
Specify outcome, not implementation.
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
session[:user_id].should == @current_user.id
controller.current_user.should == @current_user
response.should contain(\"Signed in successfully\")
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
response.should contain(\"Signed in successfully\")
end
Saturday, March 14, 2009
Saturday, March 14, 2009
No route matches “/sessions/create” with
{:method=>:post} (ActionController::RoutingError)
Saturday, March 14, 2009
I’m going to cheat...
Saturday, March 14, 2009
I’m going to cheat...
$ gem install thoughtbot-clearance
$ ./script generate clearance
$ ./script generate clearance_features
Saturday, March 14, 2009
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
end
Then /^(.+) should appear on my wish list$/ do |wish|
end
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
end
Then /^(.+) should appear on my wish list$/ do |wish|
end
Regexp Capture -> Yielded Variable
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
visit \"/wishes\"
click_link \"Make a wish\"
fill_in \"Wish\", :with => wish
click_button
end
Then /^(.+) should appear on my wish list$/ do |wish|
end
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
visit \"/wishes\"
click_link \"Make a wish\"
fill_in \"Wish\", :with => wish
click_button
end
Then /^(.+) should appear on my wish list$/ do |wish|
response.should contain(\"Your wish has been added!\")
response.should contain(wish)
end
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
visit \"/wishes\"
click_link \"Make a wish\"
fill_in \"Wish\", :with => wish
click_button
end
No route matches “/wishes” with
{:method=>:get} appear on my wish list$/ do |wish|
Then /^(.+) should (ActionController::RoutingError)
response.should contain(\"Your wish has been added!\")
response.should contain(wish)
end
Saturday, March 14, 2009
config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :wishes
Saturday, March 14, 2009
config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :wishes
When I make a “New car” wish
uninitialized constant WishesController (NameError)
Saturday, March 14, 2009
config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :wishes
$./script generate rspec_controller new create
Saturday, March 14, 2009
config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :wishes
When I make a “New car” wish
Could not find link with text or title or
id “Make a wish” (Webrat::NotFoundError)
Saturday, March 14, 2009
app/views/wishes/index.html.erb
<%= link_to \"Make a wish\", new_wish_path %>
Saturday, March 14, 2009
app/views/wishes/index.html.erb
<%= link_to \"Make a wish\", new_wish_path %>
When I make a “New car” wish
Could not find field: “Wish” (Webrat::NotFoundError)
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
visit \"/wishes\"
click_link \"Make a wish\"
fill_in \"Wish\", :with => wish
click_button
end
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
visit \"/wishes\"
click_link \"Make a wish\"
fill_in \"Wish\", :with => wish
click_button
end
app/views/wishes/new.html.erb
<% form_for :wish do |f| %>
<%= f.label :name, \"Wish\" %>
<%= f.text_field :name %>
<%= submit_tag \"Make the wish!\" %>
<% end %>
Saturday, March 14, 2009
features/step_definitions/wish_steps.rb
When /^I make a \"(.+)\" wish$/ do |wish|
visit \"/wishes\"
click_link \"Make a wish\"
fill_in \"Wish\", :with => wish
click_button
end
Location Strategy FTW!
app/views/wishes/new.html.erb
<% form_for :wish do |f| %>
<%= f.label :name, \"Wish\" %>
<%= f.text_field :name %>
<%= submit_tag \"Make the wish!\" %>
<% end %>
Saturday, March 14, 2009
View
Controller
Saturday, March 14, 2009
spec/controllers/wishes_controller_spec.rb
describe WishesController do
describe \"POST / (#create)\" do
end
end
Saturday, March 14, 2009
spec/controllers/wishes_controller_spec.rb
describe WishesController do
describe \"POST / (#create)\" do
it \"should create a new wish for the user with the params\" do
user = mock_model(User, :wishes => mock(\"wishes association\"))
controller.stub!(:current_user).and_return(user)
user.wishes.should_receive(:create).with(wish_params)
post :create, 'wish' => {'name' => 'Dog'}
end
end
end
Saturday, March 14, 2009
app/controllers/wishes_controller.rb
class WishesController < ApplicationController
def create
current_user.wishes.create(params['wish'])
end
end
Saturday, March 14, 2009
spec/controllers/wishes_controller_spec.rb
describe WishesController do
describe \"POST / (#create)\" do
before(:each) do
.....
it \"should redirect the user to their wish list\" do
do_post
response.should redirect_to(wishes_path)
end
end
end
Saturday, March 14, 2009
app/controllers/wishes_controller.rb
def create
current_user.wishes.create(params['wish'])
redirect_to :action => :index
end
Saturday, March 14, 2009
View
Controller
Model
Saturday, March 14, 2009
app/controllers/wishes_controller.rb
def create
current_user.wishes.create(params['wish'])
redirect_to :action => :index
end
When I make a “New car” wish
undefined method `wishes` for #<User:0x268e898>
(NoMethodError)
Saturday, March 14, 2009
app/controllers/wishes_controller.rb
def create
current_user.wishes.create(params['wish'])
redirect_to :action => :index
end
$./script generate rspec_model wish
name:string user_id:integer
Saturday, March 14, 2009
app/models/wish.rb
class Wish < ActiveRecord::Base
belongs_to :user
end
app/models/user.rb
class User < ActiveRecord::Base
include Clearance::App::Models::User
has_many :wishes
end
Saturday, March 14, 2009
app/models/wish.rb
class Wish < ActiveRecord::Base
belongs_to :user
end
app/models/user.rb
When I make a “New car” wish
Then “New <car” should appear on my wish
class User ActiveRecord::Base
include Clearance::App::Models::User
has_many the following element’s content to include
expected:wishes
“Your wish has been added!”
end
Saturday, March 14, 2009
spec/controllers/wishes_controller_spec.rb
it \"should notify the user of creation via the flash\" do
do_post
flash[:success].should == \"Your wish has been added!\"
end
Saturday, March 14, 2009
spec/controllers/wishes_controller_spec.rb
it \"should notify the user of creation via the flash\" do
do_post
flash[:success].should == \"Your wish has been added!\"
end
app/controllers/wishes_controller.rb
def create
current_user.wishes.create(params['wish'])
flash[:success] = \"Your wish has been added!\"
redirect_to :action => :index
end
Saturday, March 14, 2009
spec/controllers/wishes_controller_spec.rb
it \"should notify the user of creation via the flash\" do
do_post
flash[:success].should == \"Your wish has been added!\"
end
app/controllers/wishes_controller.rb
Then “New car” should appear on my wish
expected the following element’s content to include
def create
“New car”
current_user.wishes.create(params['wish'])
flash[:success] = \"Your wish has been added!\"
redirect_to :action => :index
end
Saturday, March 14, 2009
app/views/wishes/index.html.erb
<ul>
<% @wishes.each do |wish| %>
<li><%= wish.name %></li>
<% end %>
</ul>
Saturday, March 14, 2009
spec/controllers/wishes_controller_spec.rb
describe \"GET / (#index)\" do
def do_get
get :index
end
it \"should assign the user's wishes to the view\" do
do_get
assigns[:wishes].should == @current_user.wishes
end
end
Saturday, March 14, 2009
app/controllers/wishes_controller.rb
def index
@wishes = current_user.wishes
end
Saturday, March 14, 2009
Saturday, March 14, 2009
Saturday, March 14, 2009
Scenario: view members list
Given the following wishes exist
| Wish | Family Member |
| Laptop | Thomas |
| Nintendo Wii | Candace |
| CHEEZBURGER | FuzzBuzz |
When I view the wish list for \"Candace\"
Then I should see the following wishes
| Wish |
| Nintendo Wii |
Saturday, March 14, 2009
Given the following wishes exist
| Wish | Family Member |
| Laptop | Thomas |
| Nintendo Wii | Candace |
| CHEEZBURGER | FuzzBuzz |
features/step_definitions/wish_steps.rb
Given /^the following wishes exist$/ do |table|
end
end
Saturday, March 14, 2009
Given the following wishes exist
| Wish | Family Member |
| Laptop | Thomas |
| Nintendo Wii | Candace |
| CHEEZBURGER | FuzzBuzz |
features/step_definitions/wish_steps.rb
Given /^the following wishes exist$/ do |table|
table.hashes.each do |row|
member = User.find_by_name(row[\"Family Member\"]) ||
create_user(:name => row[\"Family Member\"])
member.wishes.create!(:name => row[\"Wish\"])
end
end
Saturday, March 14, 2009
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario Outline: Add two numbers
Given I have entered <input_1> into the calculator
And I have entered <input_2> into the calculator
When I press <button>
Then the result should be <output> on the screen
Examples:
| input_1 | input_2 | button | output |
| 20 | 30 | add | 50 |
|2 | 5 | add | 7 |
|0 | 40 | add | 40 |
Saturday, March 14, 2009
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario Outline: Add two numbers
Given I have entered <input_1> into the calculator
And I have entered <input_2> into the calculator
When I press <button>
Then the result should be <output> on the screen
Examples:
| input_1 | input_2 | button | output |
| 20 | 30 | add | 50 |
|2 | 5 | add | 7 |
|0 | 40 | add | 40 |
Saturday, March 14, 2009
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario Outline: Add two numbers
Given I have entered <input_1> into the calculator
And I have entered <input_2> into the calculator
When I press <button>
Then the result should be <output> on the screen
Examples:
| input_1 | input_2 | button | output |
| 20 | 30 | add | 50 |
|2 | 5 | add | 7 |
|0 | 40 | add | 40 |
Saturday, March 14, 2009
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario Outline: Add two numbers
Given I have entered <input_1> into the calculator
And I have entered <input_2> into the calculator
When I press <button>
Then the result should be <output> on the screen
Examples:
| input_1 | input_2 | button | output |
| 20 | 30 | add | 50 |
|2 | 5 | add | 7 |
|0 | 40 | add | 40 |
Saturday, March 14, 2009
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario Outline: Add two numbers
Given I have entered <input_1> into the calculator
And I have entered <input_2> into the calculator
When I press <button>
Then the result should be <output> on the screen
Examples:
| input_1 | input_2 | button | output |
| 20 | 30 | add | 50 |
|2 | 5 | add | 7 |
|0 | 40 | add | 40 |
Saturday, March 14, 2009
Steps Within Steps
When /^I view the wish list for \"(.+)\"$/ do |user_name|
Given \"I am logged in\"
visit \"/wishes/#{user_name}\"
end
Saturday, March 14, 2009
Steps Within Steps
When /^I view the wish list for \"(.+)\"$/ do |user_name|
Given \"I am logged in\"
visit \"/wishes/#{user_name}\"
end
Saturday, March 14, 2009
Helpers - Ruby FTW
When /^I view the wish list for \"(.+)\"$/ do |user_name|
login_as(create_user)
visit \"/wishes/#{user_name}\"
end
Saturday, March 14, 2009
Helpers - Ruby FTW
When /^I view the wish list for \"(.+)\"$/ do |user_name|
login_as(create_user)
visit \"/wishes/#{user_name}\"
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
visit new_session_path
fill_in \"Email\", :with => @current_user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
def login_as(user)
visit new_session_path
fill_in \"Email\", :with => user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
response.should contain(\"Signed in successfully\")
end
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
login_as(@current_user)
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
def login_as(user)
visit new_session_path
fill_in \"Email\", :with => user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
response.should contain(\"Signed in successfully\")
end
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
login_as(@current_user)
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
def login_as(user)
visit new_session_path
fill_in \"Email\", :with => user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
“Every time you monkeypatch
click_button
# make sure we have actually logged in- so we fail fast if not
Object, a kitten dies.”
response.should contain(\"Signed in successfully\")
end
Given /^I am logged in$/ do
@current_user = create_user(:email_confirmed => true)
login_as(@current_user)
end
http://seanohalpin.github.com/unobtrusive-metaprogramming/unobtrusive-metaprogramming.html
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
module UserHelpers
def login_as(user)
visit new_session_path
fill_in \"Email\", :with => user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
response.should contain(\"Signed in successfully\")
end
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
module UserHelpers
def login_as(user)
visit new_session_path
fill_in \"Email\", :with => user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
response.should contain(\"Signed in successfully\")
end
end
Saturday, March 14, 2009
features/step_definitions/user_steps.rb
module UserHelpers
def login_as(user)
visit new_session_path
fill_in \"Email\", :with => user.email
fill_in \"Password\", :with => valid_user_attributes[\"password\"]
click_button
# make sure we have actually logged in- so we fail fast if not
response.should contain(\"Signed in successfully\")
end
end
World { |world| world.extend UserHelpers }
Saturday, March 14, 2009
I can skp teh
unit testz?
Saturday, March 14, 2009
Acceptance Tests Unit Tests
Application Level Object Level- Isolated!
For Customers For developers
Slow FAST! (should be at least)
Good confidence - Tighter Feedback Loop
Prevent against More about design!!!!!!!!!!!!
regression
Will need both gears!
Some things are easier to
test at the application
level and vice-versa.
Saturday, March 14, 2009
SRSLY?
Model specs,
Controller Specs,
and view specs!?
Saturday, March 14, 2009
Saturday, March 14, 2009
Saturday, March 14, 2009
Saturday, March 14, 2009
W
Saturday, March 14, 2009
M
Saturday, March 14, 2009
More tests ==
More Maintenance
Saturday, March 14, 2009
Test Value =
Design +
Documentation +
Defence
(regression)
Saturday, March 14, 2009
if test.value > test.cost
Suite.add(test)
end
Saturday, March 14, 2009
0 comments
Post a comment