Your SlideShare is downloading. ×
0
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 <ul><li>Integration tests are SLOW </li></ul>
Pick your Battles <ul><li>Integration tests are SLOW
There's more state to manage </li></ul>
Pick your Battles <ul><li>Integration tests are SLOW
There's more state to manage
They take longer to update </li></ul>
Pick your Battles <ul><li>Integration tests are SLOW
There's more state to manage
They take longer to update </li></ul>
Very simple app or CMS?
Very simple app or CMS? <ul>An integration-only test suite may make sense </ul>
Existing tools
Existing tools: Bare-metal selenium
import xmlrpclib # Make an object to represent the XML-RPC server. server_url = &quot;http://localhost:8080/selenium-drive...
import xmlrpclib # Make an object to represent the XML-RPC server. server_url = &quot;http://localhost:8080/selenium-drive...
import xmlrpclib # Make an object to represent the XML-RPC server. server_url = &quot;http://localhost:8080/selenium-drive...
Existing tools: Splinter
from splinter.browser import Browser browser = Browser() browser.visit('http://google.com') browser.fill('q', 'splinter - ...
from splinter.browser import Browser browser = Browser() browser.visit('http://google.com') browser.fill('q', 'splinter - ...
from splinter.browser import Browser browser = Browser() browser.visit('http://google.com') browser.fill('q', 'splinter - ...
Navigation still a bit clunky </li></ul>
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 r...
# Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert r...
# Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert r...
Enter  easy_integration!
Enter  easy_integration!   The lightweight testing lib I wrote.
easy_integration <ul><li>Runs on top of splinter </li></ul>
easy_integration <ul><li>Runs on top of splinter </li><ul><ul><li>Which runs on top of selenium </li></ul></ul></ul>
easy_integration <ul><li>Runs on top of splinter </li><ul><ul><li>Which runs on top of selenium </li></ul></ul><li>No brow...
easy_integration <ul><li>Runs on top of splinter </li><ul><ul><li>Which runs on top of selenium </li></ul></ul><li>No brow...
Smart defaults: </li><ul><ul><li>Chrome browser
Upcoming SlideShare
Loading in...5
×

Integration Testing in Python

30,614

Published on

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.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
30,614
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
60
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Integration Testing in Python"

  1. 1. Integration Testing In Python And why I Love it so Much Mike Leone Panoptic Development February 29, 2012
  2. 2. What are web application integration tests?
  3. 3. High-level TESTS
  4. 4. High-level TESTS That simulate Web Browser Interaction
  5. 5. A.K.A. Acceptance Testing Browser Testing
  6. 6. Web apps? Unit testing? Integration testing?
  7. 7. EXAMPLE Test that a user can log in to your web app
  8. 8. EXAMPLE
  9. 9. USE CASES?
  10. 10. Customer-tracked user stories
  11. 11. Customer-tracked user stories “ A user should be able to create a profile and update their address”
  12. 12. High-level tests that span multiple components
  13. 13. High-level tests that span multiple components Beyond the scope of unit tests
  14. 14. Large, inherited applications
  15. 15. Large, inherited applications A less overwhelming way to track big feature sets
  16. 16. Non-application updates
  17. 17. Non-application updates Testing client applications after a data migration or infrastructure upgrades
  18. 18. But integration tests can test low-level logic too!
  19. 19. But integration tests can test low-level logic too! So let's write integration tests only, and forgo unit tests!
  20. 21. Pick your Battles
  21. 22. Pick your Battles <ul><li>Integration tests are SLOW </li></ul>
  22. 23. Pick your Battles <ul><li>Integration tests are SLOW
  23. 24. There's more state to manage </li></ul>
  24. 25. Pick your Battles <ul><li>Integration tests are SLOW
  25. 26. There's more state to manage
  26. 27. They take longer to update </li></ul>
  27. 28. Pick your Battles <ul><li>Integration tests are SLOW
  28. 29. There's more state to manage
  29. 30. They take longer to update </li></ul>
  30. 31. Very simple app or CMS?
  31. 32. Very simple app or CMS? <ul>An integration-only test suite may make sense </ul>
  32. 33. Existing tools
  33. 34. Existing tools: Bare-metal selenium
  34. 35. import xmlrpclib # Make an object to represent the XML-RPC server. server_url = &quot;http://localhost:8080/selenium-driver/RPC2&quot; 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('&quot;C:Program FilesMozilla Firefoxfirefox.exe&quot;' + '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()
  35. 36. import xmlrpclib # Make an object to represent the XML-RPC server. server_url = &quot;http://localhost:8080/selenium-driver/RPC2&quot; 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('&quot;C:Program FilesMozilla Firefoxfirefox.exe&quot;' + '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
  36. 37. import xmlrpclib # Make an object to represent the XML-RPC server. server_url = &quot;http://localhost:8080/selenium-driver/RPC2&quot; 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('&quot;C:Program FilesMozilla Firefoxfirefox.exe&quot;' + '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
  37. 38. Existing tools: Splinter
  38. 39. 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 &quot;Yes, the official website was found!&quot; else: print &quot;No, it wasn't found... We need to improve our SEO techniques&quot; browser.quit()
  39. 40. 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 &quot;Yes, the official website was found!&quot; else: print &quot;No, it wasn't found... We need to improve our SEO techniques&quot; browser.quit() Much better!
  40. 41. 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 &quot;Yes, the official website was found!&quot; else: print &quot;No, it wasn't found... We need to improve our SEO techniques&quot; browser.quit() Much better! But... <ul><li>Still have to manage browser object
  41. 42. Navigation still a bit clunky </li></ul>
  42. 43. The Ruby community is obsessed With testing
  43. 44. The Ruby community is obsessed With testing How do they do it?
  44. 45. # Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert response.body.include?(“Welcome!”) end
  45. 46. # Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert response.body.include?(“Welcome!”) end
  46. 47. # 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
  47. 48. Enter easy_integration!
  48. 49. Enter easy_integration! The lightweight testing lib I wrote.
  49. 50. easy_integration <ul><li>Runs on top of splinter </li></ul>
  50. 51. easy_integration <ul><li>Runs on top of splinter </li><ul><ul><li>Which runs on top of selenium </li></ul></ul></ul>
  51. 52. easy_integration <ul><li>Runs on top of splinter </li><ul><ul><li>Which runs on top of selenium </li></ul></ul><li>No browser object management </li></ul>
  52. 53. easy_integration <ul><li>Runs on top of splinter </li><ul><ul><li>Which runs on top of selenium </li></ul></ul><li>No browser object management
  53. 54. Smart defaults: </li><ul><ul><li>Chrome browser
  54. 55. Test server running, port 8001 </li></ul></ul></ul>
  55. 56. easy_integration Tiny, simple API: <ul><ul><ul><li>visit()
  56. 57. click()
  57. 58. fill_in()
  58. 59. select()
  59. 60. displays() </li></ul></ul></ul>
  60. 61. easy_integration Tiny, simple API: <ul><ul><ul><li>visit()
  61. 62. click()
  62. 63. fill_in()
  63. 64. select()
  64. 65. displays() </li></ul></ul></ul>That's it
  65. 66. DEMO TIME (Django example)
  66. 67. Other tools: <ul><ul><ul><li>Nose
  67. 68. Lettuce </li></ul></ul></ul>
  68. 69. Still challenging for complex django apps <ul><li>Manage test server
  69. 70. Manage time-consuming database transactions </li></ul>
  70. 71. Coming in Django 1.4 <ul><li>LiveServerTestCase </li></ul>
  71. 72. Questions? <ul><li>https://github.com/mleone
  72. 73. https://github.com/mleone/easy-integration
  73. 74. http://www.panopticdev.com/ </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×