185
Continuous Integration Testing with Hudson Wednesday, October 27, 2010

Continuous Integration Testing for Plone Using Hudson

Embed Size (px)

DESCRIPTION

http://db.tt/pdKBTHC

Citation preview

Page 1: Continuous Integration Testing for Plone Using Hudson

Continuous Integration Testing with Hudson

Wednesday, October 27, 2010

Page 2: Continuous Integration Testing for Plone Using Hudson

Continuous Integration

Wednesday, October 27, 2010

Page 3: Continuous Integration Testing for Plone Using Hudson

Continuous Integration

• Extreme Programming principle

• Martin Fowlerhttp://www.martinfowler.com/articles/continuousIntegration.html

Wednesday, October 27, 2010

Page 4: Continuous Integration Testing for Plone Using Hudson

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

Page 5: Continuous Integration Testing for Plone Using Hudson

Essentially

• Commit your code

• Test the crap out of it

• Regressions are bad

• Assign blame

• Shame is a great motivator

Wednesday, October 27, 2010

Page 6: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 7: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 8: Continuous Integration Testing for Plone Using Hudson

Hudson vs Buildbot?

Wednesday, October 27, 2010

Page 9: Continuous Integration Testing for Plone Using Hudson

*shrug*

Wednesday, October 27, 2010

Page 10: Continuous Integration Testing for Plone Using Hudson

Hudson (Pros)

Wednesday, October 27, 2010

Page 11: Continuous Integration Testing for Plone Using Hudson

Easy to install/run

%> java -jar hudson.war

Wednesday, October 27, 2010

Page 12: Continuous Integration Testing for Plone Using Hudson

Easy to Configure

• Create

• Modify

• Manage

• All TTW

Wednesday, October 27, 2010

Page 13: Continuous Integration Testing for Plone Using Hudson

Frequent Releases~ 1 / Week

Wednesday, October 27, 2010

Page 14: Continuous Integration Testing for Plone Using Hudson

Inline Documentation

Wednesday, October 27, 2010

Page 15: Continuous Integration Testing for Plone Using Hudson

Plugins

Wednesday, October 27, 2010

Page 16: Continuous Integration Testing for Plone Using Hudson

Hudson (Cons)

Wednesday, October 27, 2010

Page 17: Continuous Integration Testing for Plone Using Hudson

It’s Java.

Wednesday, October 27, 2010

Page 18: Continuous Integration Testing for Plone Using Hudson

It’s Java.1. It eats resources

2. I don’t know how to write plugins

Wednesday, October 27, 2010

Page 19: Continuous Integration Testing for Plone Using Hudson

Hudson

Wednesday, October 27, 2010

Page 20: Continuous Integration Testing for Plone Using Hudson

Project Layout

Wednesday, October 27, 2010

Page 21: Continuous Integration Testing for Plone Using Hudson

Project Layout

• Project/Job

Wednesday, October 27, 2010

Page 22: Continuous Integration Testing for Plone Using Hudson

Project Layout

• Project/Job

• Build

Wednesday, October 27, 2010

Page 23: Continuous Integration Testing for Plone Using Hudson

Project Layout

• Project

• Build

• Trigger

Wednesday, October 27, 2010

Page 24: Continuous Integration Testing for Plone Using Hudson

Triggers

• Other projects

• Remote trigger

• Periodically

• SCM polling

Wednesday, October 27, 2010

Page 25: Continuous Integration Testing for Plone Using Hudson

Project Layout

• Project/Job

• Build

• Trigger

• Build Step

Wednesday, October 27, 2010

Page 26: Continuous Integration Testing for Plone Using Hudson

Build Steps

• Shell script

• Python script

• Ant

• Maven

Wednesday, October 27, 2010

Page 27: Continuous Integration Testing for Plone Using Hudson

Project Layout

• Project/Job

• Build

• Trigger

• Build Step

• Post-Build Action

Wednesday, October 27, 2010

Page 28: Continuous Integration Testing for Plone Using Hudson

Post-Build Actions

• Trigger builds

• Archive results

• Generate reports

• Send email

Wednesday, October 27, 2010

Page 29: Continuous Integration Testing for Plone Using Hudson

Build Status

Wednesday, October 27, 2010

Page 30: Continuous Integration Testing for Plone Using Hudson

Build Status

• Successful

• Unstable

• Failed

Wednesday, October 27, 2010

Page 31: Continuous Integration Testing for Plone Using Hudson

Build Stability

Wednesday, October 27, 2010

Page 32: Continuous Integration Testing for Plone Using Hudson

Filesystem Layout

Wednesday, October 27, 2010

Page 33: Continuous Integration Testing for Plone Using Hudson

Filesystem Layouthudson /

config.xmlhudson.plugins.*.xmljobs /

myjob / builds /

2010-10-21_11-56-402010-10-21_12-20-26

config.xmlworkspace /

Wednesday, October 27, 2010

Page 34: Continuous Integration Testing for Plone Using Hudson

Filesystem Layouthudson /

config.xmlhudson.plugins.*.xmljobs /

myjob / builds /

2010-10-21_11-56-402010-10-21_12-20-26

config.xmlworkspace /

Wednesday, October 27, 2010

Page 35: Continuous Integration Testing for Plone Using Hudson

Filesystem Layouthudson /

config.xmlhudson.plugins.*.xmljobs /

myjob / builds /

2010-10-21_11-56-402010-10-21_12-20-26

config.xmlworkspace /

Wednesday, October 27, 2010

Page 36: Continuous Integration Testing for Plone Using Hudson

Filesystem Layouthudson /

config.xmlhudson.plugins.*.xmljobs /

myjob / builds /

2010-10-21_11-56-402010-10-21_12-20-26

config.xmlworkspace /

Wednesday, October 27, 2010

Page 37: Continuous Integration Testing for Plone Using Hudson

Plugins

Wednesday, October 27, 2010

Page 38: Continuous Integration Testing for Plone Using Hudson

Plugins

• Green Balls

• Python

• Subversion

• Trac

• Warnings

• Violations

• Cobertura

• Disk Usage

• Chuck Norris

Wednesday, October 27, 2010

Page 39: Continuous Integration Testing for Plone Using Hudson

Plugins

• Green Balls

• Python

• Subversion

• Trac

• Warnings

• Violations

• Cobertura

• Disk Usage

• Chuck Norris

Wednesday, October 27, 2010

Page 40: Continuous Integration Testing for Plone Using Hudson

Plone Integration

Wednesday, October 27, 2010

Page 41: Continuous Integration Testing for Plone Using Hudson

Buildout & mr.developer

Wednesday, October 27, 2010

Page 42: Continuous Integration Testing for Plone Using Hudson

buildout.cfg[buildout]...extensions = mr.developer

Wednesday, October 27, 2010

Page 43: Continuous Integration Testing for Plone Using Hudson

buildout.cfg[buildout]...extensions = mr.developersources = sources

[sources]fsd.core = svn https:.../weblion/fsd.core/trunkfsd.membrane = svn https:.../weblion/fsd.membrane/trunk

Wednesday, October 27, 2010

Page 44: Continuous Integration Testing for Plone Using Hudson

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

Page 45: Continuous Integration Testing for Plone Using Hudson

buildout.cfg[buildout]...extensions = mr.developersources = sourcesauto-checkout = fsd.core fsd.membrane

[sources]fsd.core = svn https:.../weblion/fsd.core/trunkfsd.membrane = svn https:.../weblion/fsd.membrane/trunk

Wednesday, October 27, 2010

Page 46: Continuous Integration Testing for Plone Using Hudson

buildoutbin/

buildoutdevelop...

bootstrap.pybuildout.cfg...src/

fsd.corefsd.membrane

Wednesday, October 27, 2010

Page 47: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 48: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 49: Continuous Integration Testing for Plone Using Hudson

Tests

Wednesday, October 27, 2010

Page 50: Continuous Integration Testing for Plone Using Hudson

Tests

• bin/test returns text

• Hudson wants JUnit (XML) format

• collective.xmltestreport

Wednesday, October 27, 2010

Page 51: Continuous Integration Testing for Plone Using Hudson

hudson.cfg[buildout]extends = buildout.cfg

parts += xmltestrunner

[xmltestrunner]recipe = collective.xmltestreporteggs = ${test:eggs}defaults = ${test:defaults} + ['--xml']

Wednesday, October 27, 2010

Page 52: Continuous Integration Testing for Plone Using Hudson

hudson.cfg[buildout]extends = buildout.cfg

parts += xmltestrunner

[xmltestrunner]recipe = collective.xmltestreporteggs = ${test:eggs}defaults = ${test:defaults} + ['--xml']

Wednesday, October 27, 2010

Page 53: Continuous Integration Testing for Plone Using Hudson

hudson.cfg[buildout]extends = buildout.cfg

parts += xmltestrunner

[xmltestrunner]recipe = collective.xmltestreporteggs = ${test:eggs}defaults = ${test:defaults} + ['--xml']

Wednesday, October 27, 2010

Page 54: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 55: Continuous Integration Testing for Plone Using Hudson

Test Coverage

Wednesday, October 27, 2010

Page 56: Continuous Integration Testing for Plone Using Hudson

Test Coverage

[coverage]recipe = zc.recipe.eggeggs = coverageinitialization = sys.argv = sys.argv[:] + ['run', 'bin/xmltestrunner', '-k', '-q', '--xml']

Wednesday, October 27, 2010

Page 57: Continuous Integration Testing for Plone Using Hudson

Test Coverage[report]recipe = zc.recipe.eggeggs = coveragescripts = coverage=reportinitialization = 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

Page 58: Continuous Integration Testing for Plone Using Hudson

Test Coverage

Wednesday, October 27, 2010

Page 59: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 60: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 61: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 62: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 63: Continuous Integration Testing for Plone Using Hudson

Code Analysis

Wednesday, October 27, 2010

Page 64: Continuous Integration Testing for Plone Using Hudson

Code Analysis

• zptlint

• pyflakes

• pylint

• jslint

Wednesday, October 27, 2010

Page 65: Continuous Integration Testing for Plone Using Hudson

zptlint

Wednesday, October 27, 2010

Page 66: Continuous Integration Testing for Plone Using Hudson

zptlint

• http://pypi.python.org/pypi/zptlint

• Scan page templates for parser and output errors

Wednesday, October 27, 2010

Page 67: Continuous Integration Testing for Plone Using Hudson

zptlint

[zptlint]recipe = zc.recipe.eggeggs = zptlintentry-points = zptlint=zptlint:run

Wednesday, October 27, 2010

Page 68: Continuous Integration Testing for Plone Using Hudson

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

Page 69: Continuous Integration Testing for Plone Using Hudson

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

Page 70: Continuous Integration Testing for Plone Using Hudson

zptlint

%> bin/zptlint src/.../view.pt

Wednesday, October 27, 2010

Page 71: Continuous Integration Testing for Plone Using Hudson

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

Page 72: Continuous Integration Testing for Plone Using Hudson

Parsing Log Messages

• Warnings plug-in

• Regular expression

• Groovy script (groovy.codehaus.org)

Wednesday, October 27, 2010

Page 73: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 74: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 75: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 76: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 77: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 78: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 79: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 80: Continuous Integration Testing for Plone Using Hudson

Priorities

• HIGH

• NORMAL

• LOW

Wednesday, October 27, 2010

Page 81: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 82: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 83: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 84: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 85: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 86: Continuous Integration Testing for Plone Using Hudson

zptlint[buildout]...# A list of package locations to be examined # by Hudsonpackage-directories = src/fsd.core/fsd/core src/fsd.membrane/fsd/membrane

Wednesday, October 27, 2010

Page 87: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 88: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 89: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 90: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 91: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 92: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 93: Continuous Integration Testing for Plone Using Hudson

zptlint[zptlint-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/zptlint-testmode = 755

Wednesday, October 27, 2010

Page 94: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 95: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 96: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 97: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 98: Continuous Integration Testing for Plone Using Hudson

pyflakes

Wednesday, October 27, 2010

Page 99: Continuous Integration Testing for Plone Using Hudson

pyflakes

• Python syntax checking

• Find common errors quickly

• Doesn’t attempt to run Python code

Wednesday, October 27, 2010

Page 100: Continuous Integration Testing for Plone Using Hudson

pyflakes

[pyflakes]recipe = zc.recipe.eggeggs = pyflakesentry-points = pyflakes=pyflakes.scripts.pyflakes:main

Wednesday, October 27, 2010

Page 101: Continuous Integration Testing for Plone Using Hudson

pyflakes%> bin/pyflakes src/.../person.py

Wednesday, October 27, 2010

Page 102: Continuous Integration Testing for Plone Using Hudson

pyflakes%> bin/pyflakes src/.../person.py

src/.../person.py:25: 'ATTRIBUTE_NAME' imported but unusedsrc/.../person.py:25: 'IAttributeUUID' imported but unused

Wednesday, October 27, 2010

Page 103: Continuous Integration Testing for Plone Using Hudson

pyflakes[pyflakes-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/pyflakes-testmode = 755

Wednesday, October 27, 2010

Page 104: Continuous Integration Testing for Plone Using Hudson

pyflakes[pyflakes-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/pyflakes-testmode = 755

Wednesday, October 27, 2010

Page 105: Continuous Integration Testing for Plone Using Hudson

pyflakes[pyflakes-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/pyflakes-testmode = 755

Wednesday, October 27, 2010

Page 106: Continuous Integration Testing for Plone Using Hudson

pyflakes[pyflakes-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/pyflakes-testmode = 755

Wednesday, October 27, 2010

Page 107: Continuous Integration Testing for Plone Using Hudson

pyflakes[pyflakes-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/pyflakes-testmode = 755

Wednesday, October 27, 2010

Page 108: Continuous Integration Testing for Plone Using Hudson

[pyflakes-test]recipe = collective.recipe.templateinput = 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 doneoutput = ${buildout:directory}/bin/pyflakes-testmode = 755

pyflakes

Wednesday, October 27, 2010

Page 109: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 110: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 111: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 112: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 113: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 114: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 115: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 116: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 117: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 118: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 119: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 120: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 121: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 122: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 123: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 124: Continuous Integration Testing for Plone Using Hudson

pylint

Wednesday, October 27, 2010

Page 125: Continuous Integration Testing for Plone Using Hudson

pylint

• Syntax checking

• PEP8 compliance

• Imports code

• You’ve done everything wrong

Wednesday, October 27, 2010

Page 126: Continuous Integration Testing for Plone Using Hudson

pylint

[pylint]recipe = zc.recipe.eggeggs = logilab.pylintinstallerextra-paths = ${instance:location}/lib/pythonentry-points = pylint=pylint.lint:Runarguments = [ '--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

Page 127: Continuous Integration Testing for Plone Using Hudson

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

Page 128: Continuous Integration Testing for Plone Using Hudson

pylint[pylint-test]recipe = collective.recipe.templateinput = 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-testmode = 755

Wednesday, October 27, 2010

Page 129: Continuous Integration Testing for Plone Using Hudson

pylint

Wednesday, October 27, 2010

Page 130: Continuous Integration Testing for Plone Using Hudson

pylint

Wednesday, October 27, 2010

Page 131: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 132: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 133: Continuous Integration Testing for Plone Using Hudson

Selenium

Wednesday, October 27, 2010

Page 134: Continuous Integration Testing for Plone Using Hudson

Selenium• Automated web application testing

Wednesday, October 27, 2010

Page 135: Continuous Integration Testing for Plone Using Hudson

Selenium1. Open this page

2. Click that thing

3. Fill out that form

4. Click submit

Did it work?

Wednesday, October 27, 2010

Page 136: Continuous Integration Testing for Plone Using Hudson

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

Page 137: Continuous Integration Testing for Plone Using Hudson

Selenium Testcaseclass 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

Page 138: Continuous Integration Testing for Plone Using Hudson

Selenium Testcaseclass 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

Page 139: Continuous Integration Testing for Plone Using Hudson

Selenium Testcaseclass 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

Page 140: Continuous Integration Testing for Plone Using Hudson

Selenium RC

• Firefox

• Internet Explorer

• Safari

• Chrome

• Opera

• more...

Wednesday, October 27, 2010

Page 141: Continuous Integration Testing for Plone Using Hudson

Selenium Grid

Wednesday, October 27, 2010

Page 142: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 143: Continuous Integration Testing for Plone Using Hudson

“Firefox?”

Wednesday, October 27, 2010

Page 144: Continuous Integration Testing for Plone Using Hudson

Thanks!

Wednesday, October 27, 2010

Page 145: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 146: Continuous Integration Testing for Plone Using Hudson

Selenium Test Runnerfsd/

core/...selenium/

base.pytestSelenium.py

tests/...

Wednesday, October 27, 2010

Page 147: Continuous Integration Testing for Plone Using Hudson

Selenium Test Runner

[selenium]recipe = collective.xmltestreporteggs = fsd.core [test] fsd.membrane [test]defaults = ['--tests-pattern', '^f?selenium$', '--xml']

Wednesday, October 27, 2010

Page 148: Continuous Integration Testing for Plone Using Hudson

Selenium Test Runner

[selenium]recipe = collective.xmltestreporteggs = fsd.core [test] fsd.membrane [test]defaults = ['--tests-pattern', '^f?selenium$', '--xml']

Wednesday, October 27, 2010

Page 149: Continuous Integration Testing for Plone Using Hudson

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

Page 150: Continuous Integration Testing for Plone Using Hudson

Selenium Test Runner

%> bin/selenium-firefox%> bin/selenium-safari

Wednesday, October 27, 2010

Page 151: Continuous Integration Testing for Plone Using Hudson

Selenium Test Runner

workspace/bin/...parts/

selenium-firefox/testreports/

*.xmlselenium-safari/

testreports/*.xml

Wednesday, October 27, 2010

Page 152: Continuous Integration Testing for Plone Using Hudson

~

Wednesday, October 27, 2010

Page 153: Continuous Integration Testing for Plone Using Hudson

Sprint!

• Saturday

• QA Sprint

• Selenium testing and more

• Free food!

Wednesday, October 27, 2010

Page 154: Continuous Integration Testing for Plone Using Hudson

Multi-Configuration Projects

Wednesday, October 27, 2010

Page 155: Continuous Integration Testing for Plone Using Hudson

Multi-Configuration Projects

• Run a build for each set of n x n ( x n x n) variables.

Wednesday, October 27, 2010

Page 156: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 157: Continuous Integration Testing for Plone Using Hudson

Wish List

Wednesday, October 27, 2010

Page 158: Continuous Integration Testing for Plone Using Hudson

Wish List

• Load testing

• Sphinx builds

• Chameleon compatibility checking

• Windmill

Wednesday, October 27, 2010

Page 159: Continuous Integration Testing for Plone Using Hudson

Best Practices

Wednesday, October 27, 2010

Page 160: Continuous Integration Testing for Plone Using Hudson

Check in Your Configs

• Configuration is stored in XML files

• Easy to back up to SVN

Wednesday, October 27, 2010

Page 161: Continuous Integration Testing for Plone Using Hudson

Check in Your Configshudson /

config.xmlhudson.plugins.*.xmljobs /

myjob / builds /

2010-10-21_11-56-402010-10-21_12-20-26

config.xmlworkspace /

Wednesday, October 27, 2010

Page 162: Continuous Integration Testing for Plone Using Hudson

hudson /config.xmlhudson.plugins.*.xmljobs /

myjob / builds /

2010-10-21_11-56-402010-10-21_12-20-26

config.xmlworkspace /

Check in Your Configs

Wednesday, October 27, 2010

Page 163: Continuous Integration Testing for Plone Using Hudson

Check in Your Configs

Wednesday, October 27, 2010

Page 164: Continuous Integration Testing for Plone Using Hudson

Watch Your Disk Space

• “Hudson disk-usage” plugin

Wednesday, October 27, 2010

Page 165: Continuous Integration Testing for Plone Using Hudson

Watch Your Disk Space

Wednesday, October 27, 2010

Page 166: Continuous Integration Testing for Plone Using Hudson

Watch Your Disk Space

Wednesday, October 27, 2010

Page 167: Continuous Integration Testing for Plone Using Hudson

Wednesday, October 27, 2010

Page 168: Continuous Integration Testing for Plone Using Hudson

Use an Egg Cache

• Set up a default.cfg for your hudson account.

[buildout]eggs-directory =

/home/hudson/.buildout/eggsdownload-cache =

/home/hudson/.buildout/downloads

Wednesday, October 27, 2010

Page 169: Continuous Integration Testing for Plone Using Hudson

Pin unittest2

• (If you’re using it)

• plone.app.testing

• 3x faster buildout

Wednesday, October 27, 2010

Page 170: Continuous Integration Testing for Plone Using Hudson

Split Big Builds

• How long does the build take?

• How often does each part need to be run?

• Tests?

• Coverage?

Wednesday, October 27, 2010

Page 171: Continuous Integration Testing for Plone Using Hudson

Split Big Builds

• Build

• Test

• Syntax Checking

• Coverage

• Selenium

Wednesday, October 27, 2010

Page 172: Continuous Integration Testing for Plone Using Hudson

Split Big Builds1. “Build other projects” post-build action

Wednesday, October 27, 2010

Page 173: Continuous Integration Testing for Plone Using Hudson

Split Big Builds1. “Build other projects” post-build action

2. Custom workspace

Wednesday, October 27, 2010

Page 174: Continuous Integration Testing for Plone Using Hudson

Split Big Builds1. “Build other projects” post-build action

2. Custom workspace

3. Build Fingerprinting

Wednesday, October 27, 2010

Page 175: Continuous Integration Testing for Plone Using Hudson

Fingerprinting

• “These builds are related”

• Archive an md5 hash of a file to act as an identifier

Wednesday, October 27, 2010

Page 176: Continuous Integration Testing for Plone Using Hudson

FingerprintingIn parent build:

In parent and child builds:

Wednesday, October 27, 2010

Page 177: Continuous Integration Testing for Plone Using Hudson

Reporting

Wednesday, October 27, 2010

Page 178: Continuous Integration Testing for Plone Using Hudson

Hudson Report Views

Wednesday, October 27, 2010

Page 179: Continuous Integration Testing for Plone Using Hudson

Email

Wednesday, October 27, 2010

Page 180: Continuous Integration Testing for Plone Using Hudson

Chuck

Wednesday, October 27, 2010

Page 181: Continuous Integration Testing for Plone Using Hudson

iPhone

Wednesday, October 27, 2010

Page 182: Continuous Integration Testing for Plone Using Hudson

Extreme Feedback Devices

Wednesday, October 27, 2010

Page 183: Continuous Integration Testing for Plone Using Hudson

hudson.plone.org

• Currently builds Plone 4.0.x

• Core developers have access

• Add your core & collective projects

Wednesday, October 27, 2010

Page 184: Continuous Integration Testing for Plone Using Hudson

Thanks

• Martin Aspeli

• Timo Stollenwerk

• Hanno Schlichting

Wednesday, October 27, 2010

Page 185: Continuous Integration Testing for Plone Using Hudson

QA Sprint!

• Saturday

• QA Sprint

• Selenium testing and more

• Free food!

Wednesday, October 27, 2010