SlideShare uma empresa Scribd logo
1 de 74
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/

Mais conteúdo relacionado

Mais procurados

AngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and JasmineAngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and Jasminefoxp2code
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Codescidept
 
Apex Testing and Best Practices
Apex Testing and Best PracticesApex Testing and Best Practices
Apex Testing and Best PracticesJitendra Zaa
 
Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Vysakh Sreenivasan
 
PgTAP Best Practices
PgTAP Best PracticesPgTAP Best Practices
PgTAP Best PracticesDavid Wheeler
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe TestingGetting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe TestingMark Rickerby
 
RSpock Testing Framework for Ruby
RSpock Testing Framework for RubyRSpock Testing Framework for Ruby
RSpock Testing Framework for RubyBrice Argenson
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingAdvanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingLars Thorup
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineGil Fink
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmineTimothy Oxley
 
Client side unit tests - using jasmine & karma
Client side unit tests - using jasmine & karmaClient side unit tests - using jasmine & karma
Client side unit tests - using jasmine & karmaAdam Klein
 
Testing most things in JavaScript - LeedsJS 31/05/2017
Testing most things in JavaScript - LeedsJS 31/05/2017Testing most things in JavaScript - LeedsJS 31/05/2017
Testing most things in JavaScript - LeedsJS 31/05/2017Colin Oakley
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobCiaranMcNulty
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails AppsRabble .
 
Unit testing of java script and angularjs application using Karma Jasmine Fra...
Unit testing of java script and angularjs application using Karma Jasmine Fra...Unit testing of java script and angularjs application using Karma Jasmine Fra...
Unit testing of java script and angularjs application using Karma Jasmine Fra...Samyak Bhalerao
 
RSpec 3: The new, the old, the good
RSpec 3: The new, the old, the goodRSpec 3: The new, the old, the good
RSpec 3: The new, the old, the goodmglrnm
 
Unit Testing in SilverStripe
Unit Testing in SilverStripeUnit Testing in SilverStripe
Unit Testing in SilverStripeIngo Schommer
 
Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018Justin James
 

Mais procurados (20)

AngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and JasmineAngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and Jasmine
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Apex Testing and Best Practices
Apex Testing and Best PracticesApex Testing and Best Practices
Apex Testing and Best Practices
 
Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)
 
PgTAP Best Practices
PgTAP Best PracticesPgTAP Best Practices
PgTAP Best Practices
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe TestingGetting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
 
RSpock Testing Framework for Ruby
RSpock Testing Framework for RubyRSpock Testing Framework for Ruby
RSpock Testing Framework for Ruby
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingAdvanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit Testing
 
Clean Code
Clean CodeClean Code
Clean Code
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
 
Factory Girl
Factory GirlFactory Girl
Factory Girl
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmine
 
Client side unit tests - using jasmine & karma
Client side unit tests - using jasmine & karmaClient side unit tests - using jasmine & karma
Client side unit tests - using jasmine & karma
 
Testing most things in JavaScript - LeedsJS 31/05/2017
Testing most things in JavaScript - LeedsJS 31/05/2017Testing most things in JavaScript - LeedsJS 31/05/2017
Testing most things in JavaScript - LeedsJS 31/05/2017
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the Job
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
Unit testing of java script and angularjs application using Karma Jasmine Fra...
Unit testing of java script and angularjs application using Karma Jasmine Fra...Unit testing of java script and angularjs application using Karma Jasmine Fra...
Unit testing of java script and angularjs application using Karma Jasmine Fra...
 
RSpec 3: The new, the old, the good
RSpec 3: The new, the old, the goodRSpec 3: The new, the old, the good
RSpec 3: The new, the old, the good
 
Unit Testing in SilverStripe
Unit Testing in SilverStripeUnit Testing in SilverStripe
Unit Testing in SilverStripe
 
Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018
 

Semelhante a How To Test Everything

Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiRan Mizrahi
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slidesericholscher
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdfHans Jones
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in LaravelAhmed Yahia
 
Software Testing & PHPSpec
Software Testing & PHPSpecSoftware Testing & PHPSpec
Software Testing & PHPSpecDarren Craig
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
Django’s nasal passage
Django’s nasal passageDjango’s nasal passage
Django’s nasal passageErik Rose
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentationThanh Robi
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# DevelopersCory Foy
 

Semelhante a How To Test Everything (20)

TDD & BDD
TDD & BDDTDD & BDD
TDD & BDD
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Rtt preso
Rtt presoRtt preso
Rtt preso
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slides
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in Laravel
 
Software Testing & PHPSpec
Software Testing & PHPSpecSoftware Testing & PHPSpec
Software Testing & PHPSpec
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Django’s nasal passage
Django’s nasal passageDjango’s nasal passage
Django’s nasal passage
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Clean tests good tests
Clean tests   good testsClean tests   good tests
Clean tests good tests
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
 

Último

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 

Último (20)

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 

How To Test Everything

  • 1. How To Test Everything Noel Rappin Pathfinder Development
  • 2. How To Test Everything ... In Rails Noel Rappin Pathfinder Development
  • 4. The First Guideline Any change to the logic of the program should be driven by a failed test
  • 5. The Second Guideline A test should be as close as possible to the associated code.
  • 6. The Third Guideline Test features and functionality, not code
  • 7. The Fourth Guideline Rails works. (Mostly). You don’t need to test it.
  • 10. What Framework To Use? Short Answer: I don’t care
  • 11. What Framework To Use? Short Answer: I don’t care Longer Answer: Start with Rails Core, move when you have an unfulfilled need
  • 12. 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
  • 15. 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
  • 17. 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
  • 19. Named Scope Tests assert_same_elements [@melvin, @thomas], User.primary_status
  • 20. 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
  • 21. 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
  • 23. 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
  • 26. 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
  • 27. Views
  • 28. Views Test for semantic structure (DOM ID, class) assert_select is your friend Sometimes, not test first
  • 29. Test for the Negative What’s not there is as important as what is
  • 30. Test for the Negative What’s not there is as important as what is assert_select "#edit_link", :count => 0
  • 31. 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
  • 33. Stupid assert_select Tricks assert_select "input[name *= phone]"
  • 34. Stupid assert_select Tricks assert_select "input[name *= phone]" assert_select "li#?", dom_id(@user, :item), :count => 1
  • 35. 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
  • 37. 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
  • 39. Testing Block Helpers def if_logged_in yield if logged_in? end
  • 40. Testing Block Helpers def if_logged_in yield if logged_in? end <% if_logged_in do %> <%= link_to "logout", logout_path %> <% end %>
  • 41. 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
  • 42. Testing Output Helpers
  • 43. Testing Output def make_headline Helpers concat("<h1 class='headline'>#{yield}</h1>") end
  • 44. 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
  • 45. 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
  • 47. 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
  • 48. 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
  • 49. Email
  • 50. 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
  • 51. 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
  • 53. 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
  • 54. Ajax
  • 55. Ajax assert_select_rjs, but only for Rails stuff test "an ajax call" xhr get :create assert_select_rjs :replace, :dom_id, 12 end
  • 56. 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, ''); }); }); });
  • 58. Third Party Sites/ Web Mock, Mock, Mock, Mock Encapsulate call into an easily-mocked method Remember to test failure response
  • 59. Rake
  • 60. Rake Tasks Encapsulate the task into a class/ method and test that method
  • 61. 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
  • 62. Dates and Time
  • 64. Date/Time Timecop setup :timecop_freeze teardown :timecop_return def timecop_freeze Timecop.freeze(Time.now) end def timecop_return Timecop.return end
  • 65. 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)
  • 67. File Uploads fixture_file_upload post :update, :image => fixture_file_upload( '/test/fixtures/face.png', 'image/png')
  • 69. 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
  • 71. 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
  • 73. 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