• Like

Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Continuous Integration Testing for Plone Using Hudson

  • 1,702 views
Uploaded on

http://db.tt/pdKBTHC

http://db.tt/pdKBTHC

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,702
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
45
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Continuous Integration Testing with Hudson Wednesday, October 27, 2010
  • 2. Continuous Integration Wednesday, October 27, 2010
  • 3. Continuous Integration • Extreme Programming principle • Martin Fowler http://www.martinfowler.com/articles/ continuousIntegration.html Wednesday, October 27, 2010
  • 4. Continuous Integration • Maintain a Source • Test in a Clone of the Repository Production Environment • Automate the Build • Make the Build Self- • Make it Easy to Get the Latest Testing Deliverables • Everyone Commits • Everyone Can See Every Day the Results of the • Every Commit Latest Build Should Be Built • Automate • Keep the Build Fast Deployment Wednesday, October 27, 2010
  • 5. Essentially • Commit your code • Test the crap out of it • Regressions are bad • Assign blame • Shame is a great motivator Wednesday, October 27, 2010
  • 6. Wednesday, October 27, 2010
  • 7. Wednesday, October 27, 2010
  • 8. Hudson vs Buildbot? Wednesday, October 27, 2010
  • 9. *shrug* Wednesday, October 27, 2010
  • 10. Hudson (Pros) Wednesday, October 27, 2010
  • 11. Easy to install/run %> java -jar hudson.war Wednesday, October 27, 2010
  • 12. Easy to Configure • Create • Modify • Manage • All TTW Wednesday, October 27, 2010
  • 13. Frequent Releases ~ 1 / Week Wednesday, October 27, 2010
  • 14. Inline Documentation Wednesday, October 27, 2010
  • 15. Plugins Wednesday, October 27, 2010
  • 16. Hudson (Cons) Wednesday, October 27, 2010
  • 17. It’s Java. Wednesday, October 27, 2010
  • 18. It’s Java. 1. It eats resources 2. I don’t know how to write plugins Wednesday, October 27, 2010
  • 19. Hudson Wednesday, October 27, 2010
  • 20. Project Layout Wednesday, October 27, 2010
  • 21. Project Layout • Project/Job Wednesday, October 27, 2010
  • 22. Project Layout • Project/Job • Build Wednesday, October 27, 2010
  • 23. Project Layout • Project • Build • Trigger Wednesday, October 27, 2010
  • 24. Triggers • Other projects • Remote trigger • Periodically • SCM polling Wednesday, October 27, 2010
  • 25. Project Layout • Project/Job • Build • Trigger • Build Step Wednesday, October 27, 2010
  • 26. Build Steps • Shell script • Python script • Ant • Maven Wednesday, October 27, 2010
  • 27. Project Layout • Project/Job • Build • Trigger • Build Step • Post-Build Action Wednesday, October 27, 2010
  • 28. Post-Build Actions • Trigger builds • Archive results • Generate reports • Send email Wednesday, October 27, 2010
  • 29. Build Status Wednesday, October 27, 2010
  • 30. Build Status • Successful • Unstable • Failed Wednesday, October 27, 2010
  • 31. Build Stability Wednesday, October 27, 2010
  • 32. Filesystem Layout Wednesday, October 27, 2010
  • 33. Filesystem Layout hudson / config.xml hudson.plugins.*.xml jobs / myjob / builds / 2010-10-21_11-56-40 2010-10-21_12-20-26 config.xml workspace / Wednesday, October 27, 2010
  • 34. Filesystem Layout hudson / config.xml hudson.plugins.*.xml jobs / myjob / builds / 2010-10-21_11-56-40 2010-10-21_12-20-26 config.xml workspace / Wednesday, October 27, 2010
  • 35. Filesystem Layout hudson / config.xml hudson.plugins.*.xml jobs / myjob / builds / 2010-10-21_11-56-40 2010-10-21_12-20-26 config.xml workspace / Wednesday, October 27, 2010
  • 36. Filesystem Layout hudson / config.xml hudson.plugins.*.xml jobs / myjob / builds / 2010-10-21_11-56-40 2010-10-21_12-20-26 config.xml workspace / Wednesday, October 27, 2010
  • 37. Plugins Wednesday, October 27, 2010
  • 38. Plugins • Green Balls • Violations • Python • Cobertura • Subversion • Disk Usage • Trac • Chuck Norris • Warnings Wednesday, October 27, 2010
  • 39. Plugins • Green Balls • Violations • Python • Cobertura • Subversion • Disk Usage • Trac • Chuck Norris • Warnings Wednesday, October 27, 2010
  • 40. Plone Integration Wednesday, October 27, 2010
  • 41. Buildout & mr.developer Wednesday, October 27, 2010
  • 42. buildout.cfg [buildout] ... extensions = mr.developer Wednesday, October 27, 2010
  • 43. buildout.cfg [buildout] ... extensions = mr.developer sources = sources [sources] fsd.core = svn https:.../weblion/fsd.core/trunk fsd.membrane = svn https:.../weblion/fsd.membrane/trunk Wednesday, October 27, 2010
  • 44. mr.developer • bin/develop checkout • bin/develop status • bin/develop update • bin/develop activate (deactivate) • bin/develop reset • bin/develop purge Wednesday, October 27, 2010
  • 45. buildout.cfg [buildout] ... extensions = mr.developer sources = sources auto-checkout = fsd.core fsd.membrane [sources] fsd.core = svn https:.../weblion/fsd.core/trunk fsd.membrane = svn https:.../weblion/fsd.membrane/trunk Wednesday, October 27, 2010
  • 46. buildout bin/ buildout develop ... bootstrap.py buildout.cfg ... src/ fsd.core fsd.membrane Wednesday, October 27, 2010
  • 47. Wednesday, October 27, 2010
  • 48. Wednesday, October 27, 2010
  • 49. Tests Wednesday, October 27, 2010
  • 50. Tests • bin/test returns text • Hudson wants JUnit (XML) format • collective.xmltestreport Wednesday, October 27, 2010
  • 51. hudson.cfg [buildout] extends = buildout.cfg parts += xmltestrunner [xmltestrunner] recipe = collective.xmltestreport eggs = ${test:eggs} defaults = ${test:defaults} + ['--xml'] Wednesday, October 27, 2010
  • 52. hudson.cfg [buildout] extends = buildout.cfg parts += xmltestrunner [xmltestrunner] recipe = collective.xmltestreport eggs = ${test:eggs} defaults = ${test:defaults} + ['--xml'] Wednesday, October 27, 2010
  • 53. hudson.cfg [buildout] extends = buildout.cfg parts += xmltestrunner [xmltestrunner] recipe = collective.xmltestreport eggs = ${test:eggs} defaults = ${test:defaults} + ['--xml'] Wednesday, October 27, 2010
  • 54. Wednesday, October 27, 2010
  • 55. Test Coverage Wednesday, October 27, 2010
  • 56. Test Coverage [coverage] recipe = zc.recipe.egg eggs = coverage initialization = sys.argv = sys.argv[:] + ['run', 'bin/xmltestrunner', '-k', '-q', '--xml'] Wednesday, October 27, 2010
  • 57. Test Coverage [report] recipe = zc.recipe.egg eggs = coverage scripts = coverage=report initialization = eggs = '${buildout:eggs-directory}' bin = '${buildout:directory}/bin' exclude = '--omit=' + ','.join([eggs, sys.prefix, bin]) sys.argv = sys.argv[:] + ['xml', '-i', exclude, include] Wednesday, October 27, 2010
  • 58. Test Coverage Wednesday, October 27, 2010
  • 59. Wednesday, October 27, 2010
  • 60. Wednesday, October 27, 2010
  • 61. Wednesday, October 27, 2010
  • 62. Wednesday, October 27, 2010
  • 63. Code Analysis Wednesday, October 27, 2010
  • 64. Code Analysis • zptlint • pyflakes • pylint • jslint Wednesday, October 27, 2010
  • 65. zptlint Wednesday, October 27, 2010
  • 66. zptlint • http://pypi.python.org/pypi/zptlint • Scan page templates for parser and output errors Wednesday, October 27, 2010
  • 67. zptlint [zptlint] recipe = zc.recipe.egg eggs = zptlint entry-points = zptlint=zptlint:run Wednesday, October 27, 2010
  • 68. zptlint <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" lang="en" metal:use-macro="context/main_template/macros/master"> <body> <metal:fill fill-slot="content-core"> <div tal:content="structure view/context/text/output"> <h2>People</h2> <div tal:content="structure context/@@people" /> </metal:fill> </body> </html> Wednesday, October 27, 2010
  • 69. zptlint <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" lang="en" metal:use-macro="context/main_template/macros/master"> <body> <metal:fill fill-slot="content-core"> <div tal:content="structure view/context/text/output"> <h2>People</h2> <div tal:content="structure context/@@people" /> </metal:fill> </body> </html> Wednesday, October 27, 2010
  • 70. zptlint %> bin/zptlint src/.../view.pt Wednesday, October 27, 2010
  • 71. zptlint %> bin/zptlint src/.../view.pt *** Error in: src/.../view.pt <class 'zope.tal.taldefs.TALError'>: TAL attributes on <div> require explicit </div> , at line 12, column 9 Wednesday, October 27, 2010
  • 72. Parsing Log Messages • Warnings plug-in • Regular expression • Groovy script (groovy.codehaus.org) Wednesday, October 27, 2010
  • 73. Wednesday, October 27, 2010
  • 74. Wednesday, October 27, 2010
  • 75. Wednesday, October 27, 2010
  • 76. Wednesday, October 27, 2010
  • 77. Wednesday, October 27, 2010
  • 78. Wednesday, October 27, 2010
  • 79. Wednesday, October 27, 2010
  • 80. Priorities • HIGH • NORMAL • LOW Wednesday, October 27, 2010
  • 81. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 82. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 83. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 84. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 85. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 86. zptlint [buildout] ... # A list of package locations to be examined # by Hudson package-directories = src/fsd.core/fsd/core src/fsd.membrane/fsd/membrane Wednesday, October 27, 2010
  • 87. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 88. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 89. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 90. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 91. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 92. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 93. zptlint [zptlint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -e zptlint.log ]; then echo "Old zptlint.log file removed" rm zptlint.log fi echo "Running zptlint-test" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find $pkg -regex ".*.[c|z]?pt" | xargs -r bin/zptlint | perl -p -e 's/s+$/ /g;s/s+/ /g;s/*{3}s?/n/g' >> zptlint.log done output = ${buildout:directory}/bin/zptlint-test mode = 755 Wednesday, October 27, 2010
  • 94. Wednesday, October 27, 2010
  • 95. Wednesday, October 27, 2010
  • 96. Wednesday, October 27, 2010
  • 97. Wednesday, October 27, 2010
  • 98. pyflakes Wednesday, October 27, 2010
  • 99. pyflakes • Python syntax checking • Find common errors quickly • Doesn’t attempt to run Python code Wednesday, October 27, 2010
  • 100. pyflakes [pyflakes] recipe = zc.recipe.egg eggs = pyflakes entry-points = pyflakes=pyflakes.scripts.pyflakes:main Wednesday, October 27, 2010
  • 101. pyflakes %> bin/pyflakes src/.../person.py Wednesday, October 27, 2010
  • 102. pyflakes %> bin/pyflakes src/.../person.py src/.../person.py:25: 'ATTRIBUTE_NAME' imported but unused src/.../person.py:25: 'IAttributeUUID' imported but unused Wednesday, October 27, 2010
  • 103. pyflakes [pyflakes-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -s pyflakes.log ]; then rm pyflakes.log echo "Old pyflakes.log file removed" fi echo "Running pyflakes" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find -L $pkg -regex ".*.py"|xargs -r bin/pyflakes >> pyflakes.log done output = ${buildout:directory}/bin/pyflakes-test mode = 755 Wednesday, October 27, 2010
  • 104. pyflakes [pyflakes-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -s pyflakes.log ]; then rm pyflakes.log echo "Old pyflakes.log file removed" fi echo "Running pyflakes" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find -L $pkg -regex ".*.py"|xargs -r bin/pyflakes >> pyflakes.log done output = ${buildout:directory}/bin/pyflakes-test mode = 755 Wednesday, October 27, 2010
  • 105. pyflakes [pyflakes-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -s pyflakes.log ]; then rm pyflakes.log echo "Old pyflakes.log file removed" fi echo "Running pyflakes" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find -L $pkg -regex ".*.py"|xargs -r bin/pyflakes >> pyflakes.log done output = ${buildout:directory}/bin/pyflakes-test mode = 755 Wednesday, October 27, 2010
  • 106. pyflakes [pyflakes-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -s pyflakes.log ]; then rm pyflakes.log echo "Old pyflakes.log file removed" fi echo "Running pyflakes" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find -L $pkg -regex ".*.py"|xargs -r bin/pyflakes >> pyflakes.log done output = ${buildout:directory}/bin/pyflakes-test mode = 755 Wednesday, October 27, 2010
  • 107. pyflakes [pyflakes-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -s pyflakes.log ]; then rm pyflakes.log echo "Old pyflakes.log file removed" fi echo "Running pyflakes" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find -L $pkg -regex ".*.py"|xargs -r bin/pyflakes >> pyflakes.log done output = ${buildout:directory}/bin/pyflakes-test mode = 755 Wednesday, October 27, 2010
  • 108. pyflakes [pyflakes-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -s pyflakes.log ]; then rm pyflakes.log echo "Old pyflakes.log file removed" fi echo "Running pyflakes" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find -L $pkg -regex ".*.py"|xargs -r bin/pyflakes >> pyflakes.log done output = ${buildout:directory}/bin/pyflakes-test mode = 755 Wednesday, October 27, 2010
  • 109. Wednesday, October 27, 2010
  • 110. Wednesday, October 27, 2010
  • 111. Wednesday, October 27, 2010
  • 112. Wednesday, October 27, 2010
  • 113. Wednesday, October 27, 2010
  • 114. Wednesday, October 27, 2010
  • 115. Wednesday, October 27, 2010
  • 116. Wednesday, October 27, 2010
  • 117. Wednesday, October 27, 2010
  • 118. Wednesday, October 27, 2010
  • 119. Wednesday, October 27, 2010
  • 120. Wednesday, October 27, 2010
  • 121. Wednesday, October 27, 2010
  • 122. Wednesday, October 27, 2010
  • 123. Wednesday, October 27, 2010
  • 124. pylint Wednesday, October 27, 2010
  • 125. pylint • Syntax checking • PEP8 compliance • Imports code • You’ve done everything wrong Wednesday, October 27, 2010
  • 126. pylint [pylint] recipe = zc.recipe.egg eggs = logilab.pylintinstaller extra-paths = ${instance:location}/lib/python entry-points = pylint=pylint.lint:Run arguments = [ '--output-format=parseable', '--zope=y', '--reports=y', '--disable-msg= E0611,F0401,W0232,E1101,C0103,C0111,R0201,W0201,R0911,R0904,F0220, E1103,R0901,E0211,E0213,E1002,W0622', '--generated-members=objects', ] + sys.argv[1:] Wednesday, October 27, 2010
  • 127. pylint • disable-msg • R0911: Too many return statements (%s/%s) • R0201: Method could be a function • W0201: Attribute %r defined outside of __init__ • http://pylint-messages.wikidot.com/all-messages Wednesday, October 27, 2010
  • 128. pylint [pylint-test] recipe = collective.recipe.template input = inline: #!/bin/sh if [ -s pylint.log ]; then rm pylint.log echo "Old pylint.log file removed" fi echo "Running pylint" PACKAGES="${buildout:package-directories}" for pkg in $PACKAGES do find -L $pkg -regex ".*.py" | xargs bin/pylint >> pylint.log done echo "Finished" output = ${buildout:directory}/bin/pylint-test mode = 755 Wednesday, October 27, 2010
  • 129. pylint Wednesday, October 27, 2010
  • 130. pylint Wednesday, October 27, 2010
  • 131. Wednesday, October 27, 2010
  • 132. Wednesday, October 27, 2010
  • 133. Selenium Wednesday, October 27, 2010
  • 134. Selenium • Automated web application testing Wednesday, October 27, 2010
  • 135. Selenium 1. Open this page 2. Click that thing 3. Fill out that form 4. Click submit Did it work? Wednesday, October 27, 2010
  • 136. Selenium Testcase def test_login_overlay(self): self.open("/") self.wait() self.selenium.click('link=Log in') self.waitForElement('form#login_form') self.selenium.type("name=__ac_name", TEST_USER_NAME) self.selenium.type("name=__ac_password", TEST_USER_PASSWORD) self.selenium.click("submit") self.wait() self.failUnless(self.selenium.is_text_present("Log out")) Wednesday, October 27, 2010
  • 137. Selenium Testcase class SeleniumLayer(PloneSandboxLayer): defaultBases = (HOST_ADJUSTABLE_ZSERVER_FIXTURE, PLONE_FIXTURE) # Connection parameters seleniumHost = os.environ.get('SELENIUM_HOST', 'localhost') seleniumPort = os.environ.get('SELENIUM_PORT', '4444') seleniumBrowser = os.environ.get('SELENIUM_BROWSER', '*firefox') def setUpZope(self, app, configurationContext): ... def setUpPloneSite(self, portal): ... url = "http://%s:%s/%s" % (self['host'], self['port'], PLONE_SITE_ID) self['selenium'] = selenium.selenium(self.seleniumHost, self.seleniumPort, self.seleniumBrowser, url) self['selenium'].start() def tearDownPloneSite(self, portal): self['selenium'].stop() del self['selenium'] Wednesday, October 27, 2010
  • 138. Selenium Testcase class SeleniumLayer(PloneSandboxLayer): defaultBases = (HOST_ADJUSTABLE_ZSERVER_FIXTURE, PLONE_FIXTURE) # Connection parameters seleniumHost = os.environ.get('SELENIUM_HOST', 'localhost') seleniumPort = os.environ.get('SELENIUM_PORT', '4444') seleniumBrowser = os.environ.get('SELENIUM_BROWSER', '*firefox') def setUpZope(self, app, configurationContext): ... def setUpPloneSite(self, portal): ... url = "http://%s:%s/%s" % (self['host'], self['port'], PLONE_SITE_ID) self['selenium'] = selenium.selenium(self.seleniumHost, self.seleniumPort, self.seleniumBrowser, url) self['selenium'].start() def tearDownPloneSite(self, portal): self['selenium'].stop() del self['selenium'] Wednesday, October 27, 2010
  • 139. Selenium Testcase class SeleniumLayer(PloneSandboxLayer): defaultBases = (HOST_ADJUSTABLE_ZSERVER_FIXTURE, PLONE_FIXTURE) # Connection parameters seleniumHost = os.environ.get('SELENIUM_HOST', 'localhost') seleniumPort = os.environ.get('SELENIUM_PORT', '4444') seleniumBrowser = os.environ.get('SELENIUM_BROWSER', '*firefox') def setUpZope(self, app, configurationContext): ... def setUpPloneSite(self, portal): ... url = "http://%s:%s/%s" % (self['host'], self['port'], PLONE_SITE_ID) self['selenium'] = selenium.selenium(self.seleniumHost, self.seleniumPort, self.seleniumBrowser, url) self['selenium'].start() def tearDownPloneSite(self, portal): self['selenium'].stop() del self['selenium'] Wednesday, October 27, 2010
  • 140. Selenium RC • Firefox • Internet Explorer • Safari • Chrome • Opera • more... Wednesday, October 27, 2010
  • 141. Selenium Grid Wednesday, October 27, 2010
  • 142. Wednesday, October 27, 2010
  • 143. “Firefox?” Wednesday, October 27, 2010
  • 144. Thanks! Wednesday, October 27, 2010
  • 145. Wednesday, October 27, 2010
  • 146. Selenium Test Runner fsd/ core/ ... selenium/ base.py testSelenium.py tests/ ... Wednesday, October 27, 2010
  • 147. Selenium Test Runner [selenium] recipe = collective.xmltestreport eggs = fsd.core [test] fsd.membrane [test] defaults = ['--tests-pattern', '^f?selenium$', '--xml'] Wednesday, October 27, 2010
  • 148. Selenium Test Runner [selenium] recipe = collective.xmltestreport eggs = fsd.core [test] fsd.membrane [test] defaults = ['--tests-pattern', '^f?selenium$', '--xml'] Wednesday, October 27, 2010
  • 149. Selenium Test Runner [selenium-firefox] recipe = ${selenium:recipe} eggs = ${selenium:eggs} defaults = ${selenium:defaults} [selenium-safari] recipe = ${selenium:recipe} eggs = ${selenium:eggs} defaults = ${selenium:defaults} Wednesday, October 27, 2010
  • 150. Selenium Test Runner %> bin/selenium-firefox %> bin/selenium-safari Wednesday, October 27, 2010
  • 151. Selenium Test Runner workspace/ bin/ ... parts/ selenium-firefox/ testreports/ *.xml selenium-safari/ testreports/ *.xml Wednesday, October 27, 2010
  • 152. ~ Wednesday, October 27, 2010
  • 153. Sprint! • Saturday • QA Sprint • Selenium testing and more • Free food! Wednesday, October 27, 2010
  • 154. Multi-Configuration Projects Wednesday, October 27, 2010
  • 155. Multi-Configuration Projects • Run a build for each set of n x n ( x n x n) variables. Wednesday, October 27, 2010
  • 156. Wednesday, October 27, 2010
  • 157. Wish List Wednesday, October 27, 2010
  • 158. Wish List • Load testing • Sphinx builds • Chameleon compatibility checking • Windmill Wednesday, October 27, 2010
  • 159. Best Practices Wednesday, October 27, 2010
  • 160. Check in Your Configs • Configuration is stored in XML files • Easy to back up to SVN Wednesday, October 27, 2010
  • 161. Check in Your Configs hudson / config.xml hudson.plugins.*.xml jobs / myjob / builds / 2010-10-21_11-56-40 2010-10-21_12-20-26 config.xml workspace / Wednesday, October 27, 2010
  • 162. Check in Your Configs hudson / config.xml hudson.plugins.*.xml jobs / myjob / builds / 2010-10-21_11-56-40 2010-10-21_12-20-26 config.xml workspace / Wednesday, October 27, 2010
  • 163. Check in Your Configs Wednesday, October 27, 2010
  • 164. Watch Your Disk Space • “Hudson disk-usage” plugin Wednesday, October 27, 2010
  • 165. Watch Your Disk Space Wednesday, October 27, 2010
  • 166. Watch Your Disk Space Wednesday, October 27, 2010
  • 167. Wednesday, October 27, 2010
  • 168. Use an Egg Cache • Set up a default.cfg for your hudson account. [buildout] eggs-directory = /home/hudson/.buildout/eggs download-cache = /home/hudson/.buildout/downloads Wednesday, October 27, 2010
  • 169. Pin unittest2 • (If you’re using it) • plone.app.testing • 3x faster buildout Wednesday, October 27, 2010
  • 170. Split Big Builds • How long does the build take? • How often does each part need to be run? • Tests? • Coverage? Wednesday, October 27, 2010
  • 171. Split Big Builds • Build • Test • Syntax Checking • Coverage • Selenium Wednesday, October 27, 2010
  • 172. Split Big Builds 1. “Build other projects” post-build action Wednesday, October 27, 2010
  • 173. Split Big Builds 1. “Build other projects” post-build action 2. Custom workspace Wednesday, October 27, 2010
  • 174. Split Big Builds 1. “Build other projects” post-build action 2. Custom workspace 3. Build Fingerprinting Wednesday, October 27, 2010
  • 175. Fingerprinting • “These builds are related” • Archive an md5 hash of a file to act as an identifier Wednesday, October 27, 2010
  • 176. Fingerprinting In parent build: In parent and child builds: Wednesday, October 27, 2010
  • 177. Reporting Wednesday, October 27, 2010
  • 178. Hudson Report Views Wednesday, October 27, 2010
  • 179. Email Wednesday, October 27, 2010
  • 180. Chuck Wednesday, October 27, 2010
  • 181. iPhone Wednesday, October 27, 2010
  • 182. Extreme Feedback Devices Wednesday, October 27, 2010
  • 183. hudson.plone.org • Currently builds Plone 4.0.x • Core developers have access • Add your core & collective projects Wednesday, October 27, 2010
  • 184. Thanks • Martin Aspeli • Timo Stollenwerk • Hanno Schlichting Wednesday, October 27, 2010
  • 185. QA Sprint! • Saturday • QA Sprint • Selenium testing and more • Free food! Wednesday, October 27, 2010