Yura Tolstik
Ruby/Rails developer at Altoros Development

            t witter: @yltsrc
         email: yltsrc@gmail.com
Do your test


              Why?

test before          save time
     or                 or
 test after          waste time
Save time writing code???
     We spend time writing tests, but
      we save time with tests, so...




        Spent time == Saved time
Rspec best practices

$ rake spec
...........................................................
...........................................................
...........................................................
...........................................................
...........................................................
....................................................

Finished in 0.00116 seconds
Describe what you are doing
 describe User do
   describe '.authenticate' do
   end

   describe '.admins' do
   end

   describe '#admin?' do
   end

   describe '#name' do
   end
 end
Establish the context

describe '#create' do
  context 'given valid credentials' do
  end
 
  context 'given invalid credentials' do
  end
end
it only expects one thing
describe '#create' do
  it 'creates a new user' do
   User.count.should == @count + 1
  end
 
  it 'sets a flash message' do
    flash[:notice].should be
  end
 
  it "redirects to the new user's profile" do
    response.should redirect_to(user_path(assigns(:user)))
  end
end
Prefer explicitness
describe '#new' do
  context 'when not logged in' do
    subject do
      response
    end

    it 'redirects to the sign in page' do
      should redirect_to(sign_in_path)
    end

    it 'displays a message to sign in' do
      subject.body.should match(/sign in/i)
    end
  end
end
Confirm readability
UsersController
  #create
    creates a new user
    sets a flash message
    redirects to the new user's profile
  #show
    finds the given user
    displays its profile
  #show.json
    returns the given user as JSON
  #destroy
    deletes the given user
    sets a flash message
    redirects to the home page
Use the right matcher

object.should be

7.should respond_to(:zero?).with(0).arguments
7.should_not be_zero

expect { model.save! }.to
  raise_error(ActiveRecord::RecordNotFound)

collection.should have(4).items
Rspec options
describe "group with tagged specs" do
  it "example I'm working now", :focus => true do; end
  it "slow example", :speed => 'slow' do; end
  it "ordinary example", :skip => true do; end
end

rspec   spec/*_spec.rb   --tag @focus
rspec   spec/*_spec.rb   --tag ~@focus
rspec   spec/*_spec.rb   --tag @speed:slow
rspec   spec/*_spec.rb   --format=progress --color

# spec_helper.rb
RSpec.configure do |config|
  config.color_enabled = true
  config.formatter = :documentation
         # :progress, :html, :textmate
end
Cucumber best practices
Organize your garden

bank_account_add.feature
bank_account_delete.feature
user_signup.feature
user_signup_when_invited.feature
user_login.feature
Thinking declaratively
Scenario: Create a slide
  Given I am signed in as an admin
  When I go to the admin dashboard
    And I create a new slide

Scenario: Create a slide
  Given I am signed as an admin
  When I go to the admin dashboard
    And I create a new slide
  Then I should be able to edit it
Cucumber helps you
Feature: Search engine optimization
  In order to find company
  As a future customer
  I want to find company in google

  Scenario: Find company in google
    Given I ask google for "company"
    Then I should see "http://company.url"


$ cucumber
...
Given /^I ask google for "([^"]*)"$/ do |arg1|
  pending
end

#Gemfile
gem "cucumber-rails-training-wheels", :group => :test
Make your scenario DRY
Feature: A user can cancel a transaction unless it's
         claimed by the recipient
 
  Background:
    Given I am logged in
    And I send "$10" to "mukmuk@example.com" from my "Bank account"
 
  Scenario: I can cancel as long as the payment is not claimed
    When I cancel my latest transaction
    Then I should see a cancellation confirmation
 
  Scenario: I can't cancel once the payment is claimed
    Given "Mukmuk" claimed the latest transaction
    Then I can't cancel my latest transaction
Scenario with variables
Scenario Outline: Add invalid bank account displays inline
  errors

  Given I follow "Add Bank Account"
  When I fill in "<field>" with "<value>"
  And I press "Add Bank Account"
  And I should see the inline error "<error>" for "<field>"
 
  Examples:
    | field   | value         | error                    |
    | Account |               | Can't be blank           |
    | Account | Sixty five    | Should be 1 to 12 digits |
    | Account | 1234567890123 | Should be 1 to 12 digits | 
Cucumber options
@smoke
Feature: Find site in search engines
  @javascript @wip
  Scenario: Find site in google



cucumber --name "Find site in search engines"

cucumber features --tags @wip:3

cucumber --tags @wip,@smoke # logical OR (@wip || @smoke)

# logical AND (@wip && !@slow)
cucumber --tags @wip --tags ~@slow

cucumber features/account_*.feature --format=progress --quiet
Cucumber profiles
#cucumber.yml
<%
std_opts = "--format pretty --quiet --strict --tags ~@wip"
%>

default: <%= std_opts << " --tags ~@javascript" %> features
selenium: <%= std_opts %> features
wip: --tags @wip:3 --wip features




cucumber --profile=wip
rake cucumber:wip
Questions




       http://blog.carbonfive.com/2010/10/21/rspec-best-practices/
  https://www.relishapp.com/rspec/rspec-core/v/2-6/docs/command-line/
                https://github.com/rspec/rspec-expectations
http://eggsonbread.com/2010/09/06/my-cucumber-best-practices-and-tips/

Do your test

  • 1.
    Yura Tolstik Ruby/Rails developerat Altoros Development t witter: @yltsrc email: yltsrc@gmail.com
  • 2.
    Do your test Why? test before save time or or test after waste time
  • 3.
    Save time writingcode??? We spend time writing tests, but we save time with tests, so... Spent time == Saved time
  • 4.
    Rspec best practices $rake spec ........................................................... ........................................................... ........................................................... ........................................................... ........................................................... .................................................... Finished in 0.00116 seconds
  • 5.
    Describe what youare doing describe User do   describe '.authenticate' do   end   describe '.admins' do   end   describe '#admin?' do   end   describe '#name' do   end end
  • 6.
    Establish the context describe'#create' do   context 'given valid credentials' do   end     context 'given invalid credentials' do   end end
  • 7.
    it only expectsone thing describe '#create' do it 'creates a new user' do    User.count.should == @count + 1   end     it 'sets a flash message' do     flash[:notice].should be   end     it "redirects to the new user's profile" do     response.should redirect_to(user_path(assigns(:user)))   end end
  • 8.
    Prefer explicitness describe '#new'do context 'when not logged in' do     subject do       response     end     it 'redirects to the sign in page' do       should redirect_to(sign_in_path)     end     it 'displays a message to sign in' do       subject.body.should match(/sign in/i)     end   end end
  • 9.
    Confirm readability UsersController   #create     creates anew user     sets a flash message     redirects to the new user's profile   #show     finds the given user     displays its profile   #show.json     returns the given user as JSON   #destroy     deletes the given user     sets a flash message     redirects to the home page
  • 10.
    Use the rightmatcher object.should be 7.should respond_to(:zero?).with(0).arguments 7.should_not be_zero expect { model.save! }.to raise_error(ActiveRecord::RecordNotFound) collection.should have(4).items
  • 11.
    Rspec options describe "groupwith tagged specs" do it "example I'm working now", :focus => true do; end it "slow example", :speed => 'slow' do; end it "ordinary example", :skip => true do; end end rspec spec/*_spec.rb --tag @focus rspec spec/*_spec.rb --tag ~@focus rspec spec/*_spec.rb --tag @speed:slow rspec spec/*_spec.rb --format=progress --color # spec_helper.rb RSpec.configure do |config| config.color_enabled = true config.formatter = :documentation # :progress, :html, :textmate end
  • 12.
  • 13.
  • 14.
    Thinking declaratively Scenario: Createa slide Given I am signed in as an admin When I go to the admin dashboard And I create a new slide Scenario: Create a slide Given I am signed as an admin When I go to the admin dashboard And I create a new slide Then I should be able to edit it
  • 15.
    Cucumber helps you Feature:Search engine optimization In order to find company As a future customer I want to find company in google Scenario: Find company in google Given I ask google for "company" Then I should see "http://company.url" $ cucumber ... Given /^I ask google for "([^"]*)"$/ do |arg1| pending end #Gemfile gem "cucumber-rails-training-wheels", :group => :test
  • 16.
    Make your scenarioDRY Feature: A user can cancel a transaction unless it's claimed by the recipient     Background:     Given I am logged in     And I send "$10" to "mukmuk@example.com" from my "Bank account"     Scenario: I can cancel as long as the payment is not claimed     When I cancel my latest transaction     Then I should see a cancellation confirmation     Scenario: I can't cancel once the payment is claimed     Given "Mukmuk" claimed the latest transaction     Then I can't cancel my latest transaction
  • 17.
    Scenario with variables ScenarioOutline: Add invalid bank account displays inline errors   Given I follow "Add Bank Account"   When I fill in "<field>" with "<value>"   And I press "Add Bank Account"   And I should see the inline error "<error>" for "<field>"     Examples:     | field   | value         | error                    |     | Account |               | Can't be blank           |     | Account | Sixty five    | Should be 1 to 12 digits |     | Account | 1234567890123 | Should be 1 to 12 digits | 
  • 18.
    Cucumber options @smoke Feature: Findsite in search engines @javascript @wip Scenario: Find site in google cucumber --name "Find site in search engines" cucumber features --tags @wip:3 cucumber --tags @wip,@smoke # logical OR (@wip || @smoke) # logical AND (@wip && !@slow) cucumber --tags @wip --tags ~@slow cucumber features/account_*.feature --format=progress --quiet
  • 19.
    Cucumber profiles #cucumber.yml <% std_opts ="--format pretty --quiet --strict --tags ~@wip" %> default: <%= std_opts << " --tags ~@javascript" %> features selenium: <%= std_opts %> features wip: --tags @wip:3 --wip features cucumber --profile=wip rake cucumber:wip
  • 20.
    Questions http://blog.carbonfive.com/2010/10/21/rspec-best-practices/ https://www.relishapp.com/rspec/rspec-core/v/2-6/docs/command-line/ https://github.com/rspec/rspec-expectations http://eggsonbread.com/2010/09/06/my-cucumber-best-practices-and-tips/