Integration Testing in Python
Upcoming SlideShare
Loading in...5
×
 

Integration Testing in Python

on

  • 28,307 views

This presentation addresses web app integration testing (a.k.a. browser testing) in Python. It focuses on currently-available tools, including one that I wrote, and looks at some specific integration ...

This presentation addresses web app integration testing (a.k.a. browser testing) in Python. It focuses on currently-available tools, including one that I wrote, and looks at some specific integration testing concerns for the Django web framework.

Statistics

Views

Total Views
28,307
Views on SlideShare
9,275
Embed Views
19,032

Actions

Likes
3
Downloads
43
Comments
0

8 Embeds 19,032

http://leone.panopticdev.com 18759
http://blog.mikeleone.com 137
http://translate.googleusercontent.com 63
http://7781964911499645745_73fcfa2288a103bf59aad4aec7f7296adcc6dc5a.blogspot.com 59
http://feeds.feedburner.com 7
http://207.46.192.232 5
http://natas5.natas.labs.overthewire.org 1
http://131.253.14.66 1
More...

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Integration Testing in Python Integration Testing in Python Presentation Transcript

  • Integration Testing In Python And why I Love it so Much Mike Leone Panoptic Development February 29, 2012
  • What are web application integration tests?
  • High-level TESTS
  • High-level TESTS That simulate Web Browser Interaction
  • A.K.A. Acceptance Testing Browser Testing
  • Web apps? Unit testing? Integration testing?
  • EXAMPLE Test that a user can log in to your web app
  • EXAMPLE
  • USE CASES?
  • Customer-tracked user stories
  • Customer-tracked user stories “ A user should be able to create a profile and update their address”
  • High-level tests that span multiple components
  • High-level tests that span multiple components Beyond the scope of unit tests
  • Large, inherited applications
  • Large, inherited applications A less overwhelming way to track big feature sets
  • Non-application updates
  • Non-application updates Testing client applications after a data migration or infrastructure upgrades
  • But integration tests can test low-level logic too!
  • But integration tests can test low-level logic too! So let's write integration tests only, and forgo unit tests!
  •  
  • Pick your Battles
  • Pick your Battles
    • Integration tests are SLOW
  • Pick your Battles
    • Integration tests are SLOW
    • There's more state to manage
  • Pick your Battles
    • Integration tests are SLOW
    • There's more state to manage
    • They take longer to update
  • Pick your Battles
    • Integration tests are SLOW
    • There's more state to manage
    • They take longer to update
  • Very simple app or CMS?
  • Very simple app or CMS?
      An integration-only test suite may make sense
  • Existing tools
  • Existing tools: Bare-metal selenium
  • import xmlrpclib # Make an object to represent the XML-RPC server. server_url = "http://localhost:8080/selenium-driver/RPC2" app = xmlrpclib.ServerProxy(server_url) # Bump timeout a little higher than the default 5 seconds app.setTimeout(15) import os #os.system('start run_firefox.bat') os.system('"C:Program FilesMozilla Firefoxfirefox.exe"' + 'http://localhost:8080/selenium-driver/SeleneseRunner.html') print app.open('http://localhost:8080/AUT/000000A/http/www.google.com/') print app.verifyTitle('Google') print app.type('q','Selenium ThoughtWorks') print app.verifyValue('q','Selenium ThoughtWorks') print app.clickAndWait('btnG') print app.verifyTextPresent('selenium.thoughtworks.com','') print app.verifyTitle('Google Search: Selenium ThoughtWorks') print app.testComplete()
  • import xmlrpclib # Make an object to represent the XML-RPC server. server_url = "http://localhost:8080/selenium-driver/RPC2" app = xmlrpclib.ServerProxy(server_url) # Bump timeout a little higher than the default 5 seconds app.setTimeout(15) import os #os.system('start run_firefox.bat') os.system('"C:Program FilesMozilla Firefoxfirefox.exe"' + 'http://localhost:8080/selenium-driver/SeleneseRunner.html') print app.open('http://localhost:8080/AUT/000000A/http/www.google.com/') print app.verifyTitle('Google') print app.type('q','Selenium ThoughtWorks') print app.verifyValue('q','Selenium ThoughtWorks') print app.clickAndWait('btnG') print app.verifyTextPresent('selenium.thoughtworks.com','') print app.verifyTitle('Google Search: Selenium ThoughtWorks') print app.testComplete() Too much boilerplate
  • import xmlrpclib # Make an object to represent the XML-RPC server. server_url = "http://localhost:8080/selenium-driver/RPC2" app = xmlrpclib.ServerProxy(server_url) # Bump timeout a little higher than the default 5 seconds app.setTimeout(15) import os #os.system('start run_firefox.bat') os.system('"C:Program FilesMozilla Firefoxfirefox.exe"' + 'http://localhost:8080/selenium-driver/SeleneseRunner.html') print app.open('http://localhost:8080/AUT/000000A/http/www.google.com/') print app.verifyTitle('Google') print app.type('q','Selenium ThoughtWorks') print app.verifyValue('q','Selenium ThoughtWorks') print app.clickAndWait('btnG') print app.verifyTextPresent('selenium.thoughtworks.com','') print app.verifyTitle('Google Search: Selenium ThoughtWorks') print app.testComplete() Too much boilerplate Too verbose, API too big
  • Existing tools: Splinter
  • from splinter.browser import Browser browser = Browser() browser.visit('http://google.com') browser.fill('q', 'splinter - python acceptance testing for web applications') browser.find_by_css('.lsb').first.click() if browser.is_text_present('splinter.cobrateam.info'): print "Yes, the official website was found!" else: print "No, it wasn't found... We need to improve our SEO techniques" browser.quit()
  • from splinter.browser import Browser browser = Browser() browser.visit('http://google.com') browser.fill('q', 'splinter - python acceptance testing for web applications') browser.find_by_css('.lsb').first.click() if browser.is_text_present('splinter.cobrateam.info'): print "Yes, the official website was found!" else: print "No, it wasn't found... We need to improve our SEO techniques" browser.quit() Much better!
  • from splinter.browser import Browser browser = Browser() browser.visit('http://google.com') browser.fill('q', 'splinter - python acceptance testing for web applications') browser.find_by_css('.lsb').first.click() if browser.is_text_present('splinter.cobrateam.info'): print "Yes, the official website was found!" else: print "No, it wasn't found... We need to improve our SEO techniques" browser.quit() Much better! But...
    • Still have to manage browser object
    • Navigation still a bit clunky
  • The Ruby community is obsessed With testing
  • The Ruby community is obsessed With testing How do they do it?
  • # Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert response.body.include?(“Welcome!”) end
  • # Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert response.body.include?(“Welcome!”) end
  • # Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert response.body.include?(“Welcome!”) end That's what I want
  • Enter easy_integration!
  • Enter easy_integration! The lightweight testing lib I wrote.
  • easy_integration
    • Runs on top of splinter
  • easy_integration
    • Runs on top of splinter
        • Which runs on top of selenium
  • easy_integration
    • Runs on top of splinter
        • Which runs on top of selenium
    • No browser object management
  • easy_integration
    • Runs on top of splinter
        • Which runs on top of selenium
    • No browser object management
    • Smart defaults:
        • Chrome browser
        • Test server running, port 8001
  • easy_integration Tiny, simple API:
        • visit()
        • click()
        • fill_in()
        • select()
        • displays()
  • easy_integration Tiny, simple API:
        • visit()
        • click()
        • fill_in()
        • select()
        • displays()
    That's it
  • DEMO TIME (Django example)
  • Other tools:
        • Nose
        • Lettuce
  • Still challenging for complex django apps
    • Manage test server
    • Manage time-consuming database transactions
  • Coming in Django 1.4
    • LiveServerTestCase
  • Questions?
    • https://github.com/mleone
    • https://github.com/mleone/easy-integration
    • http://www.panopticdev.com/