SlideShare a Scribd company logo
Browser-level testing
    Martin Kleppmann
           Go Test It
    Email: martin@go-test.it
    Blog: yes-no-cancel.co.uk
       Twitter: @martinkl
“But I have unit
    tests!”
Browser-level testing
?
Array literals?


var x = [1,];

x.length == 1   // Firefox 3.5
x.length == 2   // IE 7
Uninitialised vars?


<div id="hello"></div>

typeof(hello) == 'undefined' // Firefox 3.5
typeof(hello) == 'object'    // IE 7
Browser-level testing
Attempt #1:
Simulate events in JavaScript.

       (Selenium, Windmill, Sahi)
Attempt #1: Simulate events in JavaScript.




        Selenium         example.com
Attempt #1: Simulate events in JavaScript.



                   click
        Selenium           example.com
Attempt #1: Simulate events in JavaScript.



                           click
         Selenium                  example.com


   http://localhost:8080      http://test.example.com
Attempt #1: Simulate events in JavaScript.
                                    Cross-domain
                                    security policy


                           click
         Selenium                  example.com


   http://localhost:8080      http://test.example.com
Attempt #1: Simulate events in JavaScript.




        Selenium         example.com
Attempt #1: Simulate events in JavaScript.




        Selenium            example.com



            test.example.com proxy
Attempt #1: Simulate events in JavaScript.




        Selenium             example.com



             test.example.com proxy
    /selenium-server/                 /*
Attempt #1: Simulate events in JavaScript.



                        click
        Selenium                example.com



             test.example.com proxy
    /selenium-server/                  /*
Limitations

• Redirect to other domain or https
• Outside of DOM: pop-ups, Flash, ...
• Slow
Attempt #2:
Browser-specific automation
          APIs.
        (WebDriver, Watir)
Browser-level testing
IE


  Firefox


  Safari


  Chrome


  Opera


HTMLUnit
IE


              Firefox


              Safari
WebDriver
              Chrome


              Opera


            HTMLUnit
IE


              Firefox


              Safari
WebDriver
              Chrome


              Opera


            HTMLUnit
IE


              Firefox


              Safari
WebDriver
              Chrome


              Opera
  Watir

            HTMLUnit
IE


              Firefox


              Safari
WebDriver
              Chrome


              Opera
  Watir

            HTMLUnit
IE

Selenium
              Firefox


              Safari
WebDriver
              Chrome


              Opera
  Watir

            HTMLUnit
IE

Selenium
              Firefox


              Safari
WebDriver
              Chrome


              Opera
  Watir

            HTMLUnit
IE

Selenium
              Firefox


              Safari
WebDriver
              Chrome


              Opera
  Watir

            HTMLUnit
Selenium   WebDriver   Watir


  IE

  Firefox

  Safari

  Chrome

  Opera

HTMLUnit
Selenium    WebDriver        Watir

  IE        HTA/Proxy    ✔ COM          ✔ COM


  Firefox   Ext/Proxy   ✔ Extension   ✔ Extension


  Safari      Proxy         ✘         ✔ AppleScript


  Chrome      Proxy     ✔ Extension   ✔ V8 Debug


  Opera       Proxy     Dragonfly?          ✘


HTMLUnit       ✘            ✔          ✔ Celerity
Watir
require 'watir'
Watir::Browser.default = 'firefox'

describe 'Google' do
  before(:each) { @browser = Watir::Browser.new }
  after(:each) { @browser.close }

  it 'should return search results for "hello world"' do
    @browser.goto "http://www.google.co.uk"
    @browser.text_field(:name, "q").set("hello world")
    @browser.button(:name, "btnG").click
    @browser.contains_text(
      "Hello world program - Wikipedia").should be_true
  end
end
WebDriver
require 'selenium-webdriver'

describe 'Google' do
  before(:each) { @browser = Selenium::WebDriver.for :firefox }
  after(:each) { @browser.quit }

  it 'should return search results for "hello world"' do
    @browser.navigate.to "http://www.google.co.uk"
    @browser.find_element(:name, "q").send_keys("hello world")
    @browser.find_element(:name, "btnG").submit
    @browser.find_element(:partial_link_text,
      "Hello world program - Wikipedia")
  end
end
Selenium
gem 'selenium-client'; require 'selenium/client'

describe 'Google' do
  before(:each) {
    @browser = Selenium::Client::Driver.new :browser => "*firefox",
      :url => "http://www.google.co.uk"
    @browser.start
  }
  after(:each) { @browser.stop }

  it 'should return search results for "hello world"' do
    @browser.open "/"
    @browser.type "q", "hello world"
    @browser.click "btnG", :wait_for => :text, :text => 'Results'
    @browser.is_text_present("Hello world program - Wikipedia").
      should be_true
  end
end
Go Test It (≈Selenium)
require 'gotest'

gotest "http://www.google.co.uk" do
  open "/"
  type "q", "hello world"
  click "btnG"
  verify_text_present "Hello world program - Wikipedia"
end
Cucumber
Feature: Google search
  In order to learn something new
  As an enthusiast for obscure programming languages
  I want to find "Hello world" programs on Google

  Scenario: Search for "hello world"
    Given that I am on google.co.uk
    When I enter "hello world" into the search box
    And I submit the form
    Then I should be shown a list of results
    And the page should contain "Hello world program -
Wikipedia"
IE

Selenium
              Firefox


              Safari
WebDriver
              Chrome


              Opera
  Watir

            HTMLUnit
IE

Selenium
              Firefox


              Safari
WebDriver
              Chrome


              Opera
  Watir

            HTMLUnit
IE

Selenium
                         Firefox


                         Safari
           WebDriver
                         Chrome


                         Opera
 Watir

                       HTMLUnit
The future?                    IE

    Selenium
  Selenium API
                               Firefox


                               Safari
                 WebDriver
                               Chrome


                               Opera
    Watir
   Watir API

                             HTMLUnit
Ok.
Fundamental goal:
  Robust tests
Choose your locators
     carefully
Choose your locators
     carefully
             id = searchInput
              name = search
xpath = //form[@id='searchform']/input[2]
Browser-level testing
Browser-level testing
link = EU makes 7bn euro climate pledge
link = EU makes 7bn euro climate pledge

  xpath = //td[@class='text']/div[1]/a
link = EU makes 7bn euro climate pledge

  xpath = //td[@class='text']/div[1]/a

              css = a.tsh
People are complicated


 Frontend tests are
       messy
2 approaches:

         Disposable tests
   (record/playback, quick&dirty)


   Domain-specific abstractions
       (carefully crafted)
Which
approach will
 you take?
Thank you!
Martin Kleppmann
       Go Test It
Email: martin@go-test.it
Blog: yes-no-cancel.co.uk
   Twitter: @martinkl
Fundamental goal:
 Parallel tests
Don’t assume a clean database
Don’t assume a clean database
Unit tests:

Load fixtures

  Given...

  When...

  Then...

  Reset database
Don’t assume a clean database
Unit tests:        Functional tests:

Load fixtures       Set up example data

  Given...           Do stuff   Do stuff

  When...
                    Check       Check
  Then...           outcome     outcome

  Reset database
Tolerate partially run tests
Tolerate partially run tests


(Assume there is no frob)

Create frob

Check frob was created

Delete frob
Tolerate partially run tests


(Assume there is no frob)

Create frob

Check frob was created

Delete frob
Tolerate partially run tests
Bad:

       Boom!
(Assume there is no frob)

Create frob

Check frob was created

Delete frob
Tolerate partially run tests
Bad:                        Better:

       Boom!
(Assume there is no frob)   Delete frob if it exists

Create frob                 Create frob

Check frob was created      Check frob was created

Delete frob                 Delete frob (optional)
Avoid race conditions: isolation
Avoid race conditions: isolation


 Delete frob if it exists   Delete frob if it exists

 Create frob                Create frob

 Check frob was created     Check frob was created
Avoid race conditions: isolation
Log in as User A            Log in as User B


 Delete frob if it exists   Delete frob if it exists

 Create frob                Create frob

 Check frob was created     Check frob was created
Avoid race conditions: isolation
Log in as User A               Log in as User B


 Delete frob if it exists      Delete frob if it exists

 Create frob                   Create frob

 Check frob was created        Check frob was created



User A and User B: independent & not used concurrently
Make test runs unique
Make test runs unique
Make test runs unique
Take care with external services
Thank you!
Martin Kleppmann
       Go Test It
Email: martin@go-test.it
Blog: yes-no-cancel.co.uk
   Twitter: @martinkl

More Related Content

PDF
Cross-browser testing in the real world
PDF
Developing, Testing and Scaling with Apache Camel - UberConf 2015
PDF
Node.js vs Play Framework
PDF
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
PDF
Night Watch with QA
PDF
Apache Camel - FUSE community day London 2010 presentation
PDF
20160905 - BrisJS - nightwatch testing
PDF
Nightwatch at Tilt
Cross-browser testing in the real world
Developing, Testing and Scaling with Apache Camel - UberConf 2015
Node.js vs Play Framework
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Night Watch with QA
Apache Camel - FUSE community day London 2010 presentation
20160905 - BrisJS - nightwatch testing
Nightwatch at Tilt

What's hot (20)

PPTX
Cache is King
PDF
High Performance JavaScript 2011
PDF
Webdriver cheatsheets summary
KEY
2011 a grape odyssey
PDF
High Performance JavaScript - jQuery Conference SF Bay Area 2010
PDF
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Angular Summit 2015
PDF
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
PPTX
Test Automation using Ruby
PDF
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
PDF
Selenium RC: Automated Testing of Modern Web Applications
PPTX
Spring Boot Tutorial
PDF
Join the darkside: Selenium testing with Nightwatch.js
PDF
Efficient JavaScript Unit Testing, May 2012
PDF
React Native in Production
PPTX
Browser Automated Testing Frameworks - Nightwatch.js
PDF
One commit, one release. Continuously delivering a Symfony project.
PDF
Continous Delivering a PHP application
PDF
Spring Boot Actuator
PDF
PDF
Rebooting a Cloud
Cache is King
High Performance JavaScript 2011
Webdriver cheatsheets summary
2011 a grape odyssey
High Performance JavaScript - jQuery Conference SF Bay Area 2010
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Angular Summit 2015
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
Test Automation using Ruby
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
Selenium RC: Automated Testing of Modern Web Applications
Spring Boot Tutorial
Join the darkside: Selenium testing with Nightwatch.js
Efficient JavaScript Unit Testing, May 2012
React Native in Production
Browser Automated Testing Frameworks - Nightwatch.js
One commit, one release. Continuously delivering a Symfony project.
Continous Delivering a PHP application
Spring Boot Actuator
Rebooting a Cloud
Ad

Viewers also liked (20)

PPTX
Coolblue Behind The Scenes - Feb 2017 - Mikado Method
PDF
Invoicing Gem - Sales & Payments In Your App
PPTX
Building domain-specific languages with Groovy
PDF
Groovy for Java Developers
PDF
User Testing by Example
DOCX
QA Tester Junior
PDF
Agile testing and_the_banking_domain_2009
PPTX
Advanced unit testing – real life examples and mistakes
PDF
Is an agile SDLC an oxymoron?
PDF
Testing of e-Banking - Case Study
PDF
Linking Upstream and Downstream Agile
PDF
End-2-End Monitoring – Der Prüfstand jedes SLA´s – in 15 Minuten erklärt!
PDF
Unit-testing and E2E testing in JS
PPTX
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...
PDF
Reactive Thinking in Java
PPTX
The Impact of Big Data On Marketing Analytics (UpStream Software)
PDF
Code lifecycle in the jvm - TopConf Linz
PDF
JavaOne 2011: Migrating Spring Applications to Java EE 6
PPTX
Testing web application
PDF
Software testing methods, levels and types
Coolblue Behind The Scenes - Feb 2017 - Mikado Method
Invoicing Gem - Sales & Payments In Your App
Building domain-specific languages with Groovy
Groovy for Java Developers
User Testing by Example
QA Tester Junior
Agile testing and_the_banking_domain_2009
Advanced unit testing – real life examples and mistakes
Is an agile SDLC an oxymoron?
Testing of e-Banking - Case Study
Linking Upstream and Downstream Agile
End-2-End Monitoring – Der Prüfstand jedes SLA´s – in 15 Minuten erklärt!
Unit-testing and E2E testing in JS
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...
Reactive Thinking in Java
The Impact of Big Data On Marketing Analytics (UpStream Software)
Code lifecycle in the jvm - TopConf Linz
JavaOne 2011: Migrating Spring Applications to Java EE 6
Testing web application
Software testing methods, levels and types
Ad

Similar to Browser-level testing (20)

PDF
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
PDF
Selenium Tips & Tricks, presented at the Tel Aviv Selenium Meetup
PPTX
Selenium.pptx
PPT
Selenium testing - Handle Elements in WebDriver
PDF
Acceptance testing plone sites and add ons with robot framework and selenium
PDF
Integration Test Cucumber + Webrat + Selenium
 
PDF
Selenium Clinic Eurostar 2012 WebDriver Tutorial
PPT
Watir Presentation Sumanth Krishna. A
PDF
Mastering Test Automation: How to Use Selenium Successfully
PPTX
Automation Zaman Now
PPT
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
PDF
orcreatehappyusers
PDF
orcreatehappyusers
PDF
How To Use Selenium Successfully
PPTX
Automated ui-testing
PPTX
Introduction to selenium web driver
PDF
How To Use Selenium Successfully (Java Edition)
PPT
Testing Web Apps With Scripting Language - Mark Rees, Century Software
PDF
Selenium and Sauce Labs
PDF
Selenium 2 for PHP(Unit)
 
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium Tips & Tricks, presented at the Tel Aviv Selenium Meetup
Selenium.pptx
Selenium testing - Handle Elements in WebDriver
Acceptance testing plone sites and add ons with robot framework and selenium
Integration Test Cucumber + Webrat + Selenium
 
Selenium Clinic Eurostar 2012 WebDriver Tutorial
Watir Presentation Sumanth Krishna. A
Mastering Test Automation: How to Use Selenium Successfully
Automation Zaman Now
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
orcreatehappyusers
orcreatehappyusers
How To Use Selenium Successfully
Automated ui-testing
Introduction to selenium web driver
How To Use Selenium Successfully (Java Edition)
Testing Web Apps With Scripting Language - Mark Rees, Century Software
Selenium and Sauce Labs
Selenium 2 for PHP(Unit)
 

Recently uploaded (20)

PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Sensors and Actuators in IoT Systems using pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
cuic standard and advanced reporting.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Chapter 2 Digital Image Fundamentals.pdf
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
PDF
Advanced IT Governance
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Big Data Technologies - Introduction.pptx
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
NewMind AI Monthly Chronicles - July 2025
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
“AI and Expert System Decision Support & Business Intelligence Systems”
Sensors and Actuators in IoT Systems using pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
cuic standard and advanced reporting.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Chapter 2 Digital Image Fundamentals.pdf
Empathic Computing: Creating Shared Understanding
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Spectral efficient network and resource selection model in 5G networks
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
Advanced IT Governance
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Review of recent advances in non-invasive hemoglobin estimation
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Big Data Technologies - Introduction.pptx
CIFDAQ's Market Insight: SEC Turns Pro Crypto
NewMind AI Monthly Chronicles - July 2025
20250228 LYD VKU AI Blended-Learning.pptx
Bridging biosciences and deep learning for revolutionary discoveries: a compr...

Browser-level testing

  • 1. Browser-level testing Martin Kleppmann Go Test It Email: [email protected] Blog: yes-no-cancel.co.uk Twitter: @martinkl
  • 2. “But I have unit tests!”
  • 4. ?
  • 5. Array literals? var x = [1,]; x.length == 1 // Firefox 3.5 x.length == 2 // IE 7
  • 6. Uninitialised vars? <div id="hello"></div> typeof(hello) == 'undefined' // Firefox 3.5 typeof(hello) == 'object' // IE 7
  • 8. Attempt #1: Simulate events in JavaScript. (Selenium, Windmill, Sahi)
  • 9. Attempt #1: Simulate events in JavaScript. Selenium example.com
  • 10. Attempt #1: Simulate events in JavaScript. click Selenium example.com
  • 11. Attempt #1: Simulate events in JavaScript. click Selenium example.com http://localhost:8080 http://test.example.com
  • 12. Attempt #1: Simulate events in JavaScript. Cross-domain security policy click Selenium example.com http://localhost:8080 http://test.example.com
  • 13. Attempt #1: Simulate events in JavaScript. Selenium example.com
  • 14. Attempt #1: Simulate events in JavaScript. Selenium example.com test.example.com proxy
  • 15. Attempt #1: Simulate events in JavaScript. Selenium example.com test.example.com proxy /selenium-server/ /*
  • 16. Attempt #1: Simulate events in JavaScript. click Selenium example.com test.example.com proxy /selenium-server/ /*
  • 17. Limitations • Redirect to other domain or https • Outside of DOM: pop-ups, Flash, ... • Slow
  • 18. Attempt #2: Browser-specific automation APIs. (WebDriver, Watir)
  • 20. IE Firefox Safari Chrome Opera HTMLUnit
  • 21. IE Firefox Safari WebDriver Chrome Opera HTMLUnit
  • 22. IE Firefox Safari WebDriver Chrome Opera HTMLUnit
  • 23. IE Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 24. IE Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 25. IE Selenium Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 26. IE Selenium Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 27. IE Selenium Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 28. Selenium WebDriver Watir IE Firefox Safari Chrome Opera HTMLUnit
  • 29. Selenium WebDriver Watir IE HTA/Proxy ✔ COM ✔ COM Firefox Ext/Proxy ✔ Extension ✔ Extension Safari Proxy ✘ ✔ AppleScript Chrome Proxy ✔ Extension ✔ V8 Debug Opera Proxy Dragonfly? ✘ HTMLUnit ✘ ✔ ✔ Celerity
  • 30. Watir require 'watir' Watir::Browser.default = 'firefox' describe 'Google' do before(:each) { @browser = Watir::Browser.new } after(:each) { @browser.close } it 'should return search results for "hello world"' do @browser.goto "http://www.google.co.uk" @browser.text_field(:name, "q").set("hello world") @browser.button(:name, "btnG").click @browser.contains_text( "Hello world program - Wikipedia").should be_true end end
  • 31. WebDriver require 'selenium-webdriver' describe 'Google' do before(:each) { @browser = Selenium::WebDriver.for :firefox } after(:each) { @browser.quit } it 'should return search results for "hello world"' do @browser.navigate.to "http://www.google.co.uk" @browser.find_element(:name, "q").send_keys("hello world") @browser.find_element(:name, "btnG").submit @browser.find_element(:partial_link_text, "Hello world program - Wikipedia") end end
  • 32. Selenium gem 'selenium-client'; require 'selenium/client' describe 'Google' do before(:each) { @browser = Selenium::Client::Driver.new :browser => "*firefox", :url => "http://www.google.co.uk" @browser.start } after(:each) { @browser.stop } it 'should return search results for "hello world"' do @browser.open "/" @browser.type "q", "hello world" @browser.click "btnG", :wait_for => :text, :text => 'Results' @browser.is_text_present("Hello world program - Wikipedia"). should be_true end end
  • 33. Go Test It (≈Selenium) require 'gotest' gotest "http://www.google.co.uk" do open "/" type "q", "hello world" click "btnG" verify_text_present "Hello world program - Wikipedia" end
  • 34. Cucumber Feature: Google search In order to learn something new As an enthusiast for obscure programming languages I want to find "Hello world" programs on Google Scenario: Search for "hello world" Given that I am on google.co.uk When I enter "hello world" into the search box And I submit the form Then I should be shown a list of results And the page should contain "Hello world program - Wikipedia"
  • 35. IE Selenium Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 36. IE Selenium Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 37. IE Selenium Firefox Safari WebDriver Chrome Opera Watir HTMLUnit
  • 38. The future? IE Selenium Selenium API Firefox Safari WebDriver Chrome Opera Watir Watir API HTMLUnit
  • 39. Ok.
  • 40. Fundamental goal: Robust tests
  • 41. Choose your locators carefully
  • 42. Choose your locators carefully id = searchInput name = search xpath = //form[@id='searchform']/input[2]
  • 45. link = EU makes 7bn euro climate pledge
  • 46. link = EU makes 7bn euro climate pledge xpath = //td[@class='text']/div[1]/a
  • 47. link = EU makes 7bn euro climate pledge xpath = //td[@class='text']/div[1]/a css = a.tsh
  • 48. People are complicated Frontend tests are messy
  • 49. 2 approaches: Disposable tests (record/playback, quick&dirty) Domain-specific abstractions (carefully crafted)
  • 51. Thank you! Martin Kleppmann Go Test It Email: [email protected] Blog: yes-no-cancel.co.uk Twitter: @martinkl
  • 53. Don’t assume a clean database
  • 54. Don’t assume a clean database Unit tests: Load fixtures Given... When... Then... Reset database
  • 55. Don’t assume a clean database Unit tests: Functional tests: Load fixtures Set up example data Given... Do stuff Do stuff When... Check Check Then... outcome outcome Reset database
  • 57. Tolerate partially run tests (Assume there is no frob) Create frob Check frob was created Delete frob
  • 58. Tolerate partially run tests (Assume there is no frob) Create frob Check frob was created Delete frob
  • 59. Tolerate partially run tests Bad: Boom! (Assume there is no frob) Create frob Check frob was created Delete frob
  • 60. Tolerate partially run tests Bad: Better: Boom! (Assume there is no frob) Delete frob if it exists Create frob Create frob Check frob was created Check frob was created Delete frob Delete frob (optional)
  • 62. Avoid race conditions: isolation Delete frob if it exists Delete frob if it exists Create frob Create frob Check frob was created Check frob was created
  • 63. Avoid race conditions: isolation Log in as User A Log in as User B Delete frob if it exists Delete frob if it exists Create frob Create frob Check frob was created Check frob was created
  • 64. Avoid race conditions: isolation Log in as User A Log in as User B Delete frob if it exists Delete frob if it exists Create frob Create frob Check frob was created Check frob was created User A and User B: independent & not used concurrently
  • 65. Make test runs unique
  • 66. Make test runs unique
  • 67. Make test runs unique
  • 68. Take care with external services
  • 69. Thank you! Martin Kleppmann Go Test It Email: [email protected] Blog: yes-no-cancel.co.uk Twitter: @martinkl