SlideShare ist ein Scribd-Unternehmen logo
1 von 23
Downloaden Sie, um offline zu lesen
Bag o’ Tricks: Unit Testing

        Anton ’tony’ Bangratz
 https://abangratz.github.com/
           @tony_xpro
anton.bangratz@radarservices.com

            2012-01-18
Introduction
The Art of Testing
Not (only) Rails
One Method, One Purpose

Consider:
 class TitanClass
   .
   .
   .
   def doIt(*args)
     args[:external_sources].each do |source|
       args[:data_gatherers] do |gatherer|
         gatherer.doIt(source)
       end
     end
     processed_data = []
     current_gatherers.each do |gatherer|
       processed_data << process_data(gatherer)
     end
     reports = {}
     processed_data.each do |data|
       reports[data.id] = Report.new(data)
     end
     ReportPrinter.print_all(reports)
   end
 end
One Method, One Purpose

Test:
 require ’spec_helper’

 describe TitanClass do
   it "should do everything" do
     source = double(Source)
     gatherer = double(Gatherer)
     args = {external_sources: [source],
       data_gatherers: [gatherer]}
     processed = double("ProcessedData")
     subject.should_receive(process_data)
       .with(gatherer).and_return(processed)
     report = double(Report)
     Report.should_receive(:new).with(processed).
       and_return(report)
     ReportPrinter.should_receive(:print_all).with([report])
     subject.doIt(args)
   end
 end
One Method, One Purpose

Test:
 require ’spec_helper’

 describe TitanClass do
   it "should do everything" do
     source = double(Source)
     gatherer = double(Gatherer)
     args = {external_sources: [source],
       data_gatherers: [gatherer]}
     processed = double("ProcessedData")
     subject.should_receive(process_data)
       .with(gatherer).and_return(processed)
     # Yikes, a stub on the subject under test!
     report = double(Report)
     Report.should_receive(:new).with(processed).
       and_return(report)
     # Stubbing ".new" is rarely a good idea
     ReportPrinter.should_receive(:print_all).with([report])
     # Huh. We know that a ReportPrinter prints reports,
     # but that’s more than we actually should know ...
     subject.doIt(args)
   end
One Test, One Assertion
Example


describe SmartClass do
  it "invokes the data gatherer" do
    data_gatherer = double(DataGatherer)
    source = double(Source)
    data_gatherer.should_receive(gather).with(source))
    # Our only assertion!
    subject.data_gatherer = data_gatherer # DI for the win
    subject.gather_from_source(source)
  end end
...
class SmartClass

  attr_accessor :data_gatherer

  def gather_from_source(source)
    data_gatherer_gather(source)
  end
end
Mocking and Stubbing
Testing Modules
Example


class TestSmartModule
  include SmartModule
end
describe SmartModule do
  subject { TestSmartModule.new }
  it "does something" do
    subject.something.should ...
  end
end
Testing IO
Well, Rails
Anonymous Controllers
Example


describe SomeClass, type: ’controller’ do
  controller(ApplicationControllerOrSubClass) do
    def index
      ... # do something
    end
  end

  it "makes something happen" do
    ... # assert something happens
    get :index
  end
end
Testing Models?
Another Layer
TDD
Frameworks
MiniTest or RSpec?
That’s all, folks.
Thanks

•              ¨
    Stephan Kamper
•   Lisa Crispin
•   Elisabeth Hendricks
•   Michael Bolton
•   Avdi Grimm
•   Steve Klabnik
•   Jeremy Evans
•                 ¨
    Martin Gamsjager
•   Robert C. Martin (Uncle Bob)
•   Andreas Kopecky
•   Jurgen Strobel
     ¨
•   Andreas Tiefenthaler
•   Michael Kohl
•   Floor Drees
•   Friends and colleagues that inspired me

Weitere ähnliche Inhalte

Was ist angesagt?

Concurrency on the JVM
Concurrency on the JVMConcurrency on the JVM
Concurrency on the JVM
Vaclav Pech
 
GPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstractionGPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstraction
Vaclav Pech
 
Coherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherenceCoherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherence
aragozin
 
Qtp certification questions and tutorial
Qtp certification questions and tutorialQtp certification questions and tutorial
Qtp certification questions and tutorial
Ramu Palanki
 
#win8acad : Building Metro Style Apps with XAML for .NET Developers
#win8acad : Building Metro Style Apps with XAML for .NET Developers#win8acad : Building Metro Style Apps with XAML for .NET Developers
#win8acad : Building Metro Style Apps with XAML for .NET Developers
Frederik De Bruyne
 

Was ist angesagt? (20)

Przywitaj się z reactive extensions
Przywitaj się z reactive extensionsPrzywitaj się z reactive extensions
Przywitaj się z reactive extensions
 
Data visualization by Kenneth Odoh
Data visualization by Kenneth OdohData visualization by Kenneth Odoh
Data visualization by Kenneth Odoh
 
Kotlinでテストコードを書く
Kotlinでテストコードを書くKotlinでテストコードを書く
Kotlinでテストコードを書く
 
Caching a page
Caching a pageCaching a page
Caching a page
 
Testing the unpredictable
Testing the unpredictableTesting the unpredictable
Testing the unpredictable
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET Application
 
Metaprogramming in .NET
Metaprogramming in .NETMetaprogramming in .NET
Metaprogramming in .NET
 
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn TớiTech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
 
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
CocoaHeads Moscow. Азиз Латыпов, VIPole. «Запросы в CoreData с агрегатными фу...
 
Sharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's FinagleSharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's Finagle
 
Taming the beast - how to tame React & GraphQL, one error at a time
Taming the beast - how to tame React & GraphQL, one error at a timeTaming the beast - how to tame React & GraphQL, one error at a time
Taming the beast - how to tame React & GraphQL, one error at a time
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Concurrency on the JVM
Concurrency on the JVMConcurrency on the JVM
Concurrency on the JVM
 
Gpars workshop
Gpars workshopGpars workshop
Gpars workshop
 
Reactive Programming on Android
Reactive Programming on AndroidReactive Programming on Android
Reactive Programming on Android
 
Rntb20200805
Rntb20200805Rntb20200805
Rntb20200805
 
GPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstractionGPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstraction
 
Coherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherenceCoherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherence
 
Qtp certification questions and tutorial
Qtp certification questions and tutorialQtp certification questions and tutorial
Qtp certification questions and tutorial
 
#win8acad : Building Metro Style Apps with XAML for .NET Developers
#win8acad : Building Metro Style Apps with XAML for .NET Developers#win8acad : Building Metro Style Apps with XAML for .NET Developers
#win8acad : Building Metro Style Apps with XAML for .NET Developers
 

Ähnlich wie Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
Kerry Buckley
 
Salesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUGSalesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUG
vraopolisetti
 

Ähnlich wie Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013 (20)

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
The Ring programming language version 1.10 book - Part 17 of 212
The Ring programming language version 1.10 book - Part 17 of 212The Ring programming language version 1.10 book - Part 17 of 212
The Ring programming language version 1.10 book - Part 17 of 212
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
 
Salesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUGSalesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUG
 
Business Dashboards using Bonobo ETL, Grafana and Apache Airflow
Business Dashboards using Bonobo ETL, Grafana and Apache AirflowBusiness Dashboards using Bonobo ETL, Grafana and Apache Airflow
Business Dashboards using Bonobo ETL, Grafana and Apache Airflow
 
ppopoff
ppopoffppopoff
ppopoff
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Android Automated Testing
Android Automated TestingAndroid Automated Testing
Android Automated Testing
 
The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185
 
TDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesTDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD Techniques
 
The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184
 
.NET Database Toolkit
.NET Database Toolkit.NET Database Toolkit
.NET Database Toolkit
 
Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytest
 
Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Grails queries
Grails   queriesGrails   queries
Grails queries
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a Datastore
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 

Kürzlich hochgeladen

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Kürzlich hochgeladen (20)

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

Talk about Testing at vienna.rb meetup #2 on Apr 12th, 2013

  • 1. Bag o’ Tricks: Unit Testing Anton ’tony’ Bangratz https://abangratz.github.com/ @tony_xpro anton.bangratz@radarservices.com 2012-01-18
  • 3. The Art of Testing
  • 5. One Method, One Purpose Consider: class TitanClass . . . def doIt(*args) args[:external_sources].each do |source| args[:data_gatherers] do |gatherer| gatherer.doIt(source) end end processed_data = [] current_gatherers.each do |gatherer| processed_data << process_data(gatherer) end reports = {} processed_data.each do |data| reports[data.id] = Report.new(data) end ReportPrinter.print_all(reports) end end
  • 6. One Method, One Purpose Test: require ’spec_helper’ describe TitanClass do it "should do everything" do source = double(Source) gatherer = double(Gatherer) args = {external_sources: [source], data_gatherers: [gatherer]} processed = double("ProcessedData") subject.should_receive(process_data) .with(gatherer).and_return(processed) report = double(Report) Report.should_receive(:new).with(processed). and_return(report) ReportPrinter.should_receive(:print_all).with([report]) subject.doIt(args) end end
  • 7. One Method, One Purpose Test: require ’spec_helper’ describe TitanClass do it "should do everything" do source = double(Source) gatherer = double(Gatherer) args = {external_sources: [source], data_gatherers: [gatherer]} processed = double("ProcessedData") subject.should_receive(process_data) .with(gatherer).and_return(processed) # Yikes, a stub on the subject under test! report = double(Report) Report.should_receive(:new).with(processed). and_return(report) # Stubbing ".new" is rarely a good idea ReportPrinter.should_receive(:print_all).with([report]) # Huh. We know that a ReportPrinter prints reports, # but that’s more than we actually should know ... subject.doIt(args) end
  • 8. One Test, One Assertion
  • 9. Example describe SmartClass do it "invokes the data gatherer" do data_gatherer = double(DataGatherer) source = double(Source) data_gatherer.should_receive(gather).with(source)) # Our only assertion! subject.data_gatherer = data_gatherer # DI for the win subject.gather_from_source(source) end end ... class SmartClass attr_accessor :data_gatherer def gather_from_source(source) data_gatherer_gather(source) end end
  • 12. Example class TestSmartModule include SmartModule end describe SmartModule do subject { TestSmartModule.new } it "does something" do subject.something.should ... end end
  • 16. Example describe SomeClass, type: ’controller’ do controller(ApplicationControllerOrSubClass) do def index ... # do something end end it "makes something happen" do ... # assert something happens get :index end end
  • 19. TDD
  • 23. Thanks • ¨ Stephan Kamper • Lisa Crispin • Elisabeth Hendricks • Michael Bolton • Avdi Grimm • Steve Klabnik • Jeremy Evans • ¨ Martin Gamsjager • Robert C. Martin (Uncle Bob) • Andreas Kopecky • Jurgen Strobel ¨ • Andreas Tiefenthaler • Michael Kohl • Floor Drees • Friends and colleagues that inspired me