SlideShare a Scribd company logo
How To Test
 Everything

             Noel Rappin
   Pathfinder Development
How To Test
 Everything
... In Rails
              Noel Rappin
    Pathfinder Development
Guidelines
The First Guideline


Any change to the logic of the
program should be driven by a failed
test
The Second Guideline



A test should be as close as possible
to the associated code.
The Third Guideline



Test features and functionality, not
code
The Fourth Guideline


Rails works. (Mostly).

You don’t need to test it.
Framework
What Framework To
       Use?
What Framework To
         Use?
Short Answer: I don’t care
What Framework To
         Use?
Short Answer: I don’t care

Longer Answer: Start with Rails Core,
move when you have an unfulfilled
need
What Framework To
         Use?
Short Answer: I don’t care

Longer Answer: Start with Rails Core,
move when you have an unfulfilled
need

Those needs: Contexts, Factories,
Mocks
Models
Associations
Associations
No need to just check for the existence
of an association

Associations should be driven by
failing tests of actual functionality

Code extensions in an association
block should be treated like any other
code
Named
Scopes
Named Scopes

Named scopes are methods

Don’t test that a named scope has the
SQL decorations you put in

Do test that the scope correctly finds
or manages the objects you expect
Named Scope Tests
Named Scope Tests

assert_same_elements [@melvin, @thomas],
 User.primary_status
Named Scope Tests

 assert_same_elements [@melvin, @thomas],
  User.primary_status



should_have_named_scope :primary_status do |u|
 ["online", "away"]include?(u.status)
end
Should Have Scope
def self.should_match_named_scope(named_scope,
   *args, &block)
 should "match named scope #{named_scope}" do
  ar_class = self.class.model_class
  scoped_objects = ar_class.send(named_scope, *args)
  assert !scoped_objects.blank?
  scoped_objects.each do |obj|
    assert block.call(obj)
  end

  non_scoped_objects = ar_class.all - scoped_objects
  assert !non_scoped_objects.blank?
  non_scoped_objects.each do |obj|
    assert !block.call(obj)
  end
 end
end
Validations
Validations

Don’t test Rails code

Do test for valid state

Do test anything custom

And anything with a regex

Failing saves can lead to irritating test
Controllers
Filters
Filters

Generally, test as part of actual action

Don’t need to re-test refactors

Failing filters are a big cause of silent
test failures
Views
Views

Test for semantic structure (DOM ID,
class)

assert_select is your friend

Sometimes, not test first
Test for the Negative
What’s not there is as important as
what is
Test for the Negative
What’s not there is as important as
what is

   assert_select "#edit_link", :count => 0
Test for the Negative
What’s not there is as important as
what is

   assert_select "#edit_link", :count => 0




  assert_select "li:not(#edit_link)", :count => 2
Stupid assert_select
       Tricks
Stupid assert_select
       Tricks
      assert_select "input[name *= phone]"
Stupid assert_select
         Tricks
                   assert_select "input[name *= phone]"


assert_select "li#?", dom_id(@user, :item), :count => 1
Stupid assert_select
            Tricks
                       assert_select "input[name *= phone]"


   assert_select "li#?", dom_id(@user, :item), :count => 1


assert_select "ul#directory_list" do
 assert_select "li:nth-of-type(1)",
    :text => "Albert Aardvark"
 assert_select "li:nth-of-type(2)",
    :text => "Zack Zebra"
end
Helpers
Helpers

DO TEST HELPERS

Auto generated in Rails 2.3 and up

test/unit/helpers

Methods like url_for can be stubbed in
the test class
       class UsersHelperTest < ActionView::TestCase
       end
Testing Block Helpers
Testing Block Helpers
def if_logged_in
 yield if logged_in?
end
Testing Block Helpers
def if_logged_in
 yield if logged_in?
end


                       <% if_logged_in do %>
                        <%= link_to "logout", logout_path %>
                       <% end %>
Testing Block Helpers
def if_logged_in
 yield if logged_in?
end


                       <% if_logged_in do %>
                        <%= link_to "logout", logout_path %>
                       <% end %>
    test "logged_in" do
     assert !logged_in?
     assert_nil(if_logged_in {"logged in"})
     login_as users(:quentin)
     assert logged_in?
     assert_equal("logged in", if_logged_in {"logged in"})
    end
Testing Output
   Helpers
Testing Output
def make_headline
                  Helpers
 concat("<h1 class='headline'>#{yield}</h1>")
end
Testing Output
def make_headline
                  Helpers
 concat("<h1 class='headline'>#{yield}</h1>")
end

test "make headline" do
 assert_dom_equal("<h1 class='headline'>fred</h1>",
    make_headline { "fred" })
end
Testing Output
def make_headline
                  Helpers
 concat("<h1 class='headline'>#{yield}</h1>")
end

test "make headline" do
 assert_dom_equal("<h1 class='headline'>fred</h1>",
    make_headline { "fred" })
end

test "make headline with output buffer" do
 make_headline { "fred" }
 assert_dom_equal("<h1 class='headline'>fred</h1>",
    output_buffer)
end
assert_select helpers
assert_select helpers
setup :setup_response
def setup_response
 @output_buffer = ""
 @request = ActionController::TestRequest.new
 @response = ActionController::TestResponse.new
end

def make_response(text)
 @response.body = text
end
assert_select helpers
setup :setup_response
def setup_response
 @output_buffer = ""
 @request = ActionController::TestRequest.new
 @response = ActionController::TestResponse.new
end

def make_response(text)
 @response.body = text
end
            test "make headline with response body" do
             make_headline { "fred" }
             make_response output_buffer
             assert_select("h1.headline")
            end
Email
Email
           ActionMailer::Base.deliveries.clear

Treat emails like views

assert_select_email

email_spec plugin for Cucumber &
RSpec

Shoulda: assert_did_not_sent_email,
assert_sent_email
Email
             ActionMailer::Base.deliveries.clear

Treat emails like views

assert_select_email

email_spec plugin for Cucumber &
RSpec

Shoulda: assert_did_not_sent_email, do
                 should "send an email to mom"
assert_sent_email assert_sent_email do |email|
                        email.to == "mom@mommy.com"
                       end
                      end
User
Interaction
Multi-User Interaction
Integration tests
 test "user interaction" do
  my_session = open_session
  your_session = open_session
  my_session.post("messages/send", :to => you)
  your_session.get("messages/show")
  assert_equal 1, your_session.assigns(:messages).size
 end
Ajax
Ajax



assert_select_rjs, but only for Rails
stuff
      test "an ajax call"
       xhr get :create
       assert_select_rjs :replace, :dom_id, 12
      end
Blue Ridge /
                 Screw.Unit
Screw.Unit(function() {
  describe("With my search box and default", function() {
    it("should switch the default", function() {
      search_focus($('#search'));
      expect($('#search').attr('value')).to(equal, '');
    });
  });
});
External Sites
Third Party Sites/ Web

Mock, Mock, Mock, Mock

Encapsulate call into an easily-mocked
method

Remember to test failure response
Rake
Rake Tasks
Encapsulate the task into a class/
method and test that method
Rake Tasks
Encapsulate the task into a class/
method and test that method
     test "my rake task" do
      @rake = Rake::Application.new
      Rake.application = @rake
      Rake.application.rake_require "lib/tasks/app"
      Rake::Task.define_task(:environment)
      @rake[:task_name].invoke
     end
                                    http://
                                www.philsergi.com
Dates and
  Time
Date/Time
Timecop
Date/Time
Timecop
          setup :timecop_freeze
          teardown :timecop_return

          def timecop_freeze
           Timecop.freeze(Time.now)
          end

          def timecop_return
           Timecop.return
          end
Date/Time
Timecop
            setup :timecop_freeze
            teardown :timecop_return

            def timecop_freeze
             Timecop.freeze(Time.now)
            end

            def timecop_return
             Timecop.return
            end


   Timecop.freeze(Date.parse('8 April 2009').to_time)
File Upload
File Uploads



fixture_file_upload
post :update,
   :image => fixture_file_upload(
       '/test/fixtures/face.png', 'image/png')
Rack
Rails Metal
Rails Metal
         Rack Middleware
Integration tests and cucumber

Rack::Test
def test_redirect_logged_in_users_to_dashboard
  authorize "bryan", "secret"
  get "/"
  follow_redirect!
  assert_equal "http://example.org/redirected",
   last_request.url
  assert last_response.ok?
 end
Legacy
Applications
Legacy Apps
Acceptance is the first step

Make sure the suite runs

Try black-box tests

Try mock objects

Look for seams

Don’t look backward
Wrap Up
Wrap Up

Code should flow from failed tests

Test features and functionality

Look for tools to help

The goal is great code that delivers
value
For More Info
http://speakerrate.com/events/183

http://www.pathf.com/blogs

http://blog.railsrx.com

http://www.twitter.com/noelrap

http://www.pragprog.com/titles/

More Related Content

PPT
TDD, BDD, RSpec
Nascenia IT
 
PDF
Intro to Unit Testing in AngularJS
Jim Lynch
 
PPT
Test driven development_for_php
Lean Teams Consultancy
 
PDF
Test-Driven Development of AngularJS Applications
FITC
 
PDF
Why Your Test Suite Sucks - PHPCon PL 2015
CiaranMcNulty
 
KEY
Unit Test Your Database
David Wheeler
 
PPTX
Rspec 101
Jason Noble
 
PDF
TDD, BDD and mocks
Kerry Buckley
 
TDD, BDD, RSpec
Nascenia IT
 
Intro to Unit Testing in AngularJS
Jim Lynch
 
Test driven development_for_php
Lean Teams Consultancy
 
Test-Driven Development of AngularJS Applications
FITC
 
Why Your Test Suite Sucks - PHPCon PL 2015
CiaranMcNulty
 
Unit Test Your Database
David Wheeler
 
Rspec 101
Jason Noble
 
TDD, BDD and mocks
Kerry Buckley
 

What's hot (20)

PDF
AngularJS Unit Testing w/Karma and Jasmine
foxp2code
 
KEY
Working Effectively With Legacy Code
scidept
 
PPTX
Apex Testing and Best Practices
Jitendra Zaa
 
PDF
Testing Ruby with Rspec (a beginner's guide)
Vysakh Sreenivasan
 
KEY
PgTAP Best Practices
David Wheeler
 
ODP
Getting to Grips with SilverStripe Testing
Mark Rickerby
 
PDF
RSpock Testing Framework for Ruby
Brice Argenson
 
PDF
Advanced Jasmine - Front-End JavaScript Unit Testing
Lars Thorup
 
PPTX
Clean Code
Nascenia IT
 
PDF
Quick tour to front end unit testing using jasmine
Gil Fink
 
PDF
Factory Girl
Gabe Evans
 
PDF
Intro to testing Javascript with jasmine
Timothy Oxley
 
PDF
Client side unit tests - using jasmine & karma
Adam Klein
 
PDF
Testing most things in JavaScript - LeedsJS 31/05/2017
Colin Oakley
 
PDF
Finding the Right Testing Tool for the Job
CiaranMcNulty
 
PDF
Testing Legacy Rails Apps
Rabble .
 
PPTX
Unit testing of java script and angularjs application using Karma Jasmine Fra...
Samyak Bhalerao
 
PDF
RSpec 3: The new, the old, the good
mglrnm
 
PDF
Unit Testing in SilverStripe
Ingo Schommer
 
PDF
Angular Unit Testing NDC Minn 2018
Justin James
 
AngularJS Unit Testing w/Karma and Jasmine
foxp2code
 
Working Effectively With Legacy Code
scidept
 
Apex Testing and Best Practices
Jitendra Zaa
 
Testing Ruby with Rspec (a beginner's guide)
Vysakh Sreenivasan
 
PgTAP Best Practices
David Wheeler
 
Getting to Grips with SilverStripe Testing
Mark Rickerby
 
RSpock Testing Framework for Ruby
Brice Argenson
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Lars Thorup
 
Clean Code
Nascenia IT
 
Quick tour to front end unit testing using jasmine
Gil Fink
 
Factory Girl
Gabe Evans
 
Intro to testing Javascript with jasmine
Timothy Oxley
 
Client side unit tests - using jasmine & karma
Adam Klein
 
Testing most things in JavaScript - LeedsJS 31/05/2017
Colin Oakley
 
Finding the Right Testing Tool for the Job
CiaranMcNulty
 
Testing Legacy Rails Apps
Rabble .
 
Unit testing of java script and angularjs application using Karma Jasmine Fra...
Samyak Bhalerao
 
RSpec 3: The new, the old, the good
mglrnm
 
Unit Testing in SilverStripe
Ingo Schommer
 
Angular Unit Testing NDC Minn 2018
Justin James
 
Ad

Similar to How To Test Everything (20)

PPTX
TDD & BDD
Arvind Vyas
 
ODP
Advanced Perl Techniques
Dave Cross
 
PDF
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi
 
ODP
Rtt preso
fdschoeneman
 
PDF
Token Testing Slides
ericholscher
 
ODP
Grails unit testing
pleeps
 
ODP
Bring the fun back to java
ciklum_ods
 
PDF
MT_01_unittest_python.pdf
Hans Jones
 
ODP
Testing in Laravel
Ahmed Yahia
 
PDF
Software Testing & PHPSpec
Darren Craig
 
PDF
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
 
KEY
Django’s nasal passage
Erik Rose
 
PDF
Php tests tips
Damian Sromek
 
PDF
Testing Code and Assuring Quality
Kent Cowgill
 
PDF
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
PDF
PHPUnit best practices presentation
Thanh Robi
 
KEY
Ruby/Rails
rstankov
 
KEY
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
PPTX
Clean tests good tests
Shopsys Framework
 
PPT
Ruby for C# Developers
Cory Foy
 
TDD & BDD
Arvind Vyas
 
Advanced Perl Techniques
Dave Cross
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi
 
Rtt preso
fdschoeneman
 
Token Testing Slides
ericholscher
 
Grails unit testing
pleeps
 
Bring the fun back to java
ciklum_ods
 
MT_01_unittest_python.pdf
Hans Jones
 
Testing in Laravel
Ahmed Yahia
 
Software Testing & PHPSpec
Darren Craig
 
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
 
Django’s nasal passage
Erik Rose
 
Php tests tips
Damian Sromek
 
Testing Code and Assuring Quality
Kent Cowgill
 
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
PHPUnit best practices presentation
Thanh Robi
 
Ruby/Rails
rstankov
 
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
Clean tests good tests
Shopsys Framework
 
Ruby for C# Developers
Cory Foy
 
Ad

Recently uploaded (20)

PDF
How-Cloud-Computing-Impacts-Businesses-in-2025-and-Beyond.pdf
Artjoker Software Development Company
 
PDF
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
PDF
Software Development Methodologies in 2025
KodekX
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PDF
REPORT: Heating appliances market in Poland 2024
SPIUG
 
PDF
Why Your AI & Cybersecurity Hiring Still Misses the Mark in 2025
Virtual Employee Pvt. Ltd.
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PDF
This slide provides an overview Technology
mineshkharadi333
 
PDF
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
PDF
Building High-Performance Oracle Teams: Strategic Staffing for Database Manag...
SMACT Works
 
PDF
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
PPTX
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 
PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
PPT
L2 Rules of Netiquette in Empowerment technology
Archibal2
 
PPT
Coupa-Kickoff-Meeting-Template presentai
annapureddyn
 
PDF
Software Development Company | KodekX
KodekX
 
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
How-Cloud-Computing-Impacts-Businesses-in-2025-and-Beyond.pdf
Artjoker Software Development Company
 
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
Software Development Methodologies in 2025
KodekX
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
REPORT: Heating appliances market in Poland 2024
SPIUG
 
Why Your AI & Cybersecurity Hiring Still Misses the Mark in 2025
Virtual Employee Pvt. Ltd.
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
This slide provides an overview Technology
mineshkharadi333
 
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
Building High-Performance Oracle Teams: Strategic Staffing for Database Manag...
SMACT Works
 
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
L2 Rules of Netiquette in Empowerment technology
Archibal2
 
Coupa-Kickoff-Meeting-Template presentai
annapureddyn
 
Software Development Company | KodekX
KodekX
 
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 

How To Test Everything