Your SlideShare is downloading. ×
0
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Continuous Integration Testing for Plone Using Hudson

1,802

Published on

http://db.tt/pdKBTHC

http://db.tt/pdKBTHC

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

No Downloads
Views
Total Views
1,802
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
51
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 Repository • Automate the Build • Make the Build Self- Testing • Everyone Commits Every Day • Every Commit Should Be Built • Keep the Build Fast • Test in a Clone of the Production Environment • Make it Easy to Get the Latest Deliverables • Everyone Can See the Results of the Latest Build • Automate 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 • Python • Subversion • Trac • Warnings • Violations • Cobertura • Disk Usage • Chuck Norris Wednesday, October 27, 2010
  • 39. Plugins • Green Balls • Python • Subversion • Trac • Warnings • Violations • Cobertura • Disk Usage • Chuck Norris 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-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 pyflakes 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 inYour Configs • Configuration is stored in XML files • Easy to back up to SVN Wednesday, October 27, 2010
  • 161. Check inYour 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. hudson / config.xml hudson.plugins.*.xml jobs / myjob / builds / 2010-10-21_11-56-40 2010-10-21_12-20-26 config.xml workspace / Check inYour Configs Wednesday, October 27, 2010
  • 163. Check inYour Configs Wednesday, October 27, 2010
  • 164. WatchYour Disk Space • “Hudson disk-usage” plugin Wednesday, October 27, 2010
  • 165. WatchYour Disk Space Wednesday, October 27, 2010
  • 166. WatchYour 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 ReportViews 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

×