If you can't read please download the document
Upload
panoptic-development-inc
View
30.213
Download
5
Embed Size (px)
DESCRIPTION
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.
Citation preview
2. What are web application integration tests? 3. High-level TESTS 4. High-level TESTS That simulate Web Browser Interaction 5. A.K.A. Acceptance Testing Browser Testing 6. Web apps? Unit testing? Integration testing? 7. EXAMPLE Test that a user can log in toyour web app 8. EXAMPLE 9. USE CASES? 10. Customer-tracked user stories 11. Customer-tracked user stories A user should be able to create a profile and update their address 12. High-level tests that span multiple components 13. High-level tests that span multiple components Beyond the scope of unit tests 14. Large, inherited applications 15. Large, inherited applications A less overwhelming way to track big feature sets 16. Non-application updates 17. Non-application updates Testing client applications after a data migration or infrastructure upgrades 18. But integration tests can test low-level logic too! 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 22. Pick your Battles
23. Pick your Battles
24. There's more state to manage 25. Pick your Battles
26. There's more state to manage 27. They take longer to update 28. Pick your Battles
29. There's more state to manage 30. They take longer to update 31. Very simple app or CMS? 32. Very simple app or CMS?
33. Existing tools 34. Existing tools: Bare-metal selenium 35. 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() 36. 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 37. 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 38. Existing tools: Splinter 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 "Yes, the official website was found!" else: print "No, it wasn't found... We need to improve our SEO techniques" browser.quit() 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 "Yes, the official website was found!" else: print "No, it wasn't found... We need to improve our SEO techniques" browser.quit() Much better! 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 "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...
42. Navigation still a bit clunky 43. TheRubycommunityis obsessed With testing 44. TheRubycommunityis obsessed With testing How do they do it? 45. # Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert response.body.include?(Welcome!) end 46. # Example: Capybara test framework include Rack::Test::Methods def test_it_says_welcome get '/' click 'link text' assert response.body.include?(Welcome!) end 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 48. Entereasy_integration! 49. Entereasy_integration! The lightweight testing lib I wrote. 50. easy_integration
51. easy_integration
52. easy_integration
No browser object management 53. easy_integration
No browser object management 54. Smart defaults:
56. easy_integration Tiny, simple API:
59. select() 60. displays() 61. easy_integration Tiny, simple API:
64. select() 65. displays() That's it 66. DEMO TIME (Django example) 67. Other tools:
69. Still challenging for complex django apps
70. Manage time-consuming database transactions 71. Coming in Django 1.4
72. Questions?
73. https://github.com/mleone/easy-integration 74. http://www.panopticdev.com/