SlideShare a Scribd company logo
Continuous Integration
Testing with Hudson
Wednesday, October 27, 2010
Continuous Integration
Wednesday, October 27, 2010
Continuous Integration
• Extreme Programming principle
• Martin Fowler
http://www.martinfowler.com/articles/
continuousIntegration.html
Wednesday, October 27, 2010
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
Essentially
• Commit your code
• Test the crap out of it
• Regressions are bad
• Assign blame
• Shame is a great motivator
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Hudson vs Buildbot?
Wednesday, October 27, 2010
*shrug*
Wednesday, October 27, 2010
Hudson (Pros)
Wednesday, October 27, 2010
Easy to install/run
%> java -jar hudson.war
Wednesday, October 27, 2010
Easy to Configure
• Create
• Modify
• Manage
• All TTW
Wednesday, October 27, 2010
Frequent Releases
~ 1 / Week
Wednesday, October 27, 2010
Inline Documentation
Wednesday, October 27, 2010
Plugins
Wednesday, October 27, 2010
Hudson (Cons)
Wednesday, October 27, 2010
It’s Java.
Wednesday, October 27, 2010
It’s Java.
1. It eats resources
2. I don’t know how to write plugins
Wednesday, October 27, 2010
Hudson
Wednesday, October 27, 2010
Project Layout
Wednesday, October 27, 2010
Project Layout
• Project/Job
Wednesday, October 27, 2010
Project Layout
• Project/Job
• Build
Wednesday, October 27, 2010
Project Layout
• Project
• Build
• Trigger
Wednesday, October 27, 2010
Triggers
• Other projects
• Remote trigger
• Periodically
• SCM polling
Wednesday, October 27, 2010
Project Layout
• Project/Job
• Build
• Trigger
• Build Step
Wednesday, October 27, 2010
Build Steps
• Shell script
• Python script
• Ant
• Maven
Wednesday, October 27, 2010
Project Layout
• Project/Job
• Build
• Trigger
• Build Step
• Post-Build Action
Wednesday, October 27, 2010
Post-Build Actions
• Trigger builds
• Archive results
• Generate reports
• Send email
Wednesday, October 27, 2010
Build Status
Wednesday, October 27, 2010
Build Status
• Successful
• Unstable
• Failed
Wednesday, October 27, 2010
Build Stability
Wednesday, October 27, 2010
Filesystem Layout
Wednesday, October 27, 2010
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
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
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
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
Plugins
Wednesday, October 27, 2010
Plugins
• Green Balls
• Python
• Subversion
• Trac
• Warnings
• Violations
• Cobertura
• Disk Usage
• Chuck Norris
Wednesday, October 27, 2010
Plugins
• Green Balls
• Python
• Subversion
• Trac
• Warnings
• Violations
• Cobertura
• Disk Usage
• Chuck Norris
Wednesday, October 27, 2010
Plone Integration
Wednesday, October 27, 2010
Buildout &
mr.developer
Wednesday, October 27, 2010
buildout.cfg
[buildout]
...
extensions =
mr.developer
Wednesday, October 27, 2010
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
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
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
buildout
bin/
buildout
develop
...
bootstrap.py
buildout.cfg
...
src/
fsd.core
fsd.membrane
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Tests
Wednesday, October 27, 2010
Tests
• bin/test returns text
• Hudson wants JUnit (XML) format
• collective.xmltestreport
Wednesday, October 27, 2010
hudson.cfg
[buildout]
extends = buildout.cfg
parts +=
xmltestrunner
[xmltestrunner]
recipe = collective.xmltestreport
eggs = ${test:eggs}
defaults = ${test:defaults} + ['--xml']
Wednesday, October 27, 2010
hudson.cfg
[buildout]
extends = buildout.cfg
parts +=
xmltestrunner
[xmltestrunner]
recipe = collective.xmltestreport
eggs = ${test:eggs}
defaults = ${test:defaults} + ['--xml']
Wednesday, October 27, 2010
hudson.cfg
[buildout]
extends = buildout.cfg
parts +=
xmltestrunner
[xmltestrunner]
recipe = collective.xmltestreport
eggs = ${test:eggs}
defaults = ${test:defaults} + ['--xml']
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Test Coverage
Wednesday, October 27, 2010
Test Coverage
[coverage]
recipe = zc.recipe.egg
eggs = coverage
initialization =
sys.argv = sys.argv[:] + ['run',
'bin/xmltestrunner', '-k', '-q', '--xml']
Wednesday, October 27, 2010
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
Test Coverage
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Code Analysis
Wednesday, October 27, 2010
Code Analysis
• zptlint
• pyflakes
• pylint
• jslint
Wednesday, October 27, 2010
zptlint
Wednesday, October 27, 2010
zptlint
• http://pypi.python.org/pypi/zptlint
• Scan page templates for parser and output
errors
Wednesday, October 27, 2010
zptlint
[zptlint]
recipe = zc.recipe.egg
eggs = zptlint
entry-points = zptlint=zptlint:run
Wednesday, October 27, 2010
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
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
zptlint
%> bin/zptlint src/.../view.pt
Wednesday, October 27, 2010
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
Parsing Log Messages
• Warnings plug-in
• Regular expression
• Groovy script (groovy.codehaus.org)
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Priorities
• HIGH
• NORMAL
• LOW
Wednesday, October 27, 2010
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
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
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
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
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
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
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
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
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
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
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
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
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
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
pyflakes
Wednesday, October 27, 2010
pyflakes
• Python syntax checking
• Find common errors quickly
• Doesn’t attempt to run Python code
Wednesday, October 27, 2010
pyflakes
[pyflakes]
recipe = zc.recipe.egg
eggs = pyflakes
entry-points = pyflakes=pyflakes.scripts.pyflakes:main
Wednesday, October 27, 2010
pyflakes
%> bin/pyflakes src/.../person.py
Wednesday, October 27, 2010
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
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
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
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
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
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
[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
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
pylint
Wednesday, October 27, 2010
pylint
• Syntax checking
• PEP8 compliance
• Imports code
• You’ve done everything wrong
Wednesday, October 27, 2010
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
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
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
pylint
Wednesday, October 27, 2010
pylint
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Selenium
Wednesday, October 27, 2010
Selenium
• Automated web application testing
Wednesday, October 27, 2010
Selenium
1. Open this page
2. Click that thing
3. Fill out that form
4. Click submit
Did it work?
Wednesday, October 27, 2010
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
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
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
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
Selenium RC
• Firefox
• Internet Explorer
• Safari
• Chrome
• Opera
• more...
Wednesday, October 27, 2010
Selenium Grid
Wednesday, October 27, 2010
Wednesday, October 27, 2010
“Firefox?”
Wednesday, October 27, 2010
Thanks!
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Selenium Test Runner
fsd/
core/
...
selenium/
base.py
testSelenium.py
tests/
...
Wednesday, October 27, 2010
Selenium Test Runner
[selenium]
recipe = collective.xmltestreport
eggs =
fsd.core [test]
fsd.membrane [test]
defaults = ['--tests-pattern', '^f?selenium$',
'--xml']
Wednesday, October 27, 2010
Selenium Test Runner
[selenium]
recipe = collective.xmltestreport
eggs =
fsd.core [test]
fsd.membrane [test]
defaults = ['--tests-pattern', '^f?selenium$',
'--xml']
Wednesday, October 27, 2010
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
Selenium Test Runner
%> bin/selenium-firefox
%> bin/selenium-safari
Wednesday, October 27, 2010
Selenium Test Runner
workspace/
bin/
...
parts/
selenium-firefox/
testreports/
*.xml
selenium-safari/
testreports/
*.xml
Wednesday, October 27, 2010
~
Wednesday, October 27, 2010
Sprint!
• Saturday
• QA Sprint
• Selenium testing and more
• Free food!
Wednesday, October 27, 2010
Multi-Configuration
Projects
Wednesday, October 27, 2010
Multi-Configuration
Projects
• Run a build for each set of n x n ( x n x n)
variables.
Wednesday, October 27, 2010
Wednesday, October 27, 2010
Wish List
Wednesday, October 27, 2010
Wish List
• Load testing
• Sphinx builds
• Chameleon compatibility checking
• Windmill
Wednesday, October 27, 2010
Best Practices
Wednesday, October 27, 2010
Check inYour Configs
• Configuration is stored in XML files
• Easy to back up to SVN
Wednesday, October 27, 2010
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
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
Check inYour Configs
Wednesday, October 27, 2010
WatchYour Disk Space
• “Hudson disk-usage” plugin
Wednesday, October 27, 2010
WatchYour Disk Space
Wednesday, October 27, 2010
WatchYour Disk Space
Wednesday, October 27, 2010
Wednesday, October 27, 2010
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
Pin unittest2
• (If you’re using it)
• plone.app.testing
• 3x faster buildout
Wednesday, October 27, 2010
Split Big Builds
• How long does the build take?
• How often does each part need to be run?
• Tests?
• Coverage?
Wednesday, October 27, 2010
Split Big Builds
• Build
• Test
• Syntax Checking
• Coverage
• Selenium
Wednesday, October 27, 2010
Split Big Builds
1. “Build other projects” post-build action
Wednesday, October 27, 2010
Split Big Builds
1. “Build other projects” post-build action
2. Custom workspace
Wednesday, October 27, 2010
Split Big Builds
1. “Build other projects” post-build action
2. Custom workspace
3. Build Fingerprinting
Wednesday, October 27, 2010
Fingerprinting
• “These builds are related”
• Archive an md5 hash of a file to act as an
identifier
Wednesday, October 27, 2010
Fingerprinting
In parent build:
In parent and child builds:
Wednesday, October 27, 2010
Reporting
Wednesday, October 27, 2010
Hudson ReportViews
Wednesday, October 27, 2010
Email
Wednesday, October 27, 2010
Chuck
Wednesday, October 27, 2010
iPhone
Wednesday, October 27, 2010
Extreme Feedback
Devices
Wednesday, October 27, 2010
hudson.plone.org
• Currently builds Plone 4.0.x
• Core developers have access
• Add your core & collective projects
Wednesday, October 27, 2010
Thanks
• Martin Aspeli
• Timo Stollenwerk
• Hanno Schlichting
Wednesday, October 27, 2010
QA Sprint!
• Saturday
• QA Sprint
• Selenium testing and more
• Free food!
Wednesday, October 27, 2010

More Related Content

What's hot

In depth with html5 java2days 2010
In depth with html5 java2days 2010In depth with html5 java2days 2010
In depth with html5 java2days 2010
Mystic Coders, LLC
 
Natm business travel 2.0
Natm business travel 2.0 Natm business travel 2.0
Natm business travel 2.0
Vincent Everts
 
Business of APIs Conference 2011 - Unicorns
Business of APIs Conference 2011 - UnicornsBusiness of APIs Conference 2011 - Unicorns
Business of APIs Conference 2011 - Unicorns
Mashery
 
From where OpenVBX came from to how we open sourced it
From where OpenVBX came from to how we open sourced itFrom where OpenVBX came from to how we open sourced it
From where OpenVBX came from to how we open sourced it
minddog
 
about:labs
about:labsabout:labs
about:labs
Anant Narayanan
 
Drumbler
DrumblerDrumbler
Drumbler
eojthebrave
 
Building Brilliant APIs
Building Brilliant APIsBuilding Brilliant APIs
Building Brilliant APIs
bencollier
 
Getting Involved in the Drupal Community
Getting Involved in the Drupal CommunityGetting Involved in the Drupal Community
Getting Involved in the Drupal Community
karschsp
 
Beginning Plugin d
Beginning Plugin dBeginning Plugin d
Beginning Plugin d
vegasgeek
 
Mastering CSS3 Selectors
Mastering CSS3 SelectorsMastering CSS3 Selectors
Mastering CSS3 Selectors
Rachel Andrew
 
Customer Service & Social Media: You Can Do Better
Customer Service & Social Media: You Can Do BetterCustomer Service & Social Media: You Can Do Better
Customer Service & Social Media: You Can Do Better
Mike Petroff
 

What's hot (11)

In depth with html5 java2days 2010
In depth with html5 java2days 2010In depth with html5 java2days 2010
In depth with html5 java2days 2010
 
Natm business travel 2.0
Natm business travel 2.0 Natm business travel 2.0
Natm business travel 2.0
 
Business of APIs Conference 2011 - Unicorns
Business of APIs Conference 2011 - UnicornsBusiness of APIs Conference 2011 - Unicorns
Business of APIs Conference 2011 - Unicorns
 
From where OpenVBX came from to how we open sourced it
From where OpenVBX came from to how we open sourced itFrom where OpenVBX came from to how we open sourced it
From where OpenVBX came from to how we open sourced it
 
about:labs
about:labsabout:labs
about:labs
 
Drumbler
DrumblerDrumbler
Drumbler
 
Building Brilliant APIs
Building Brilliant APIsBuilding Brilliant APIs
Building Brilliant APIs
 
Getting Involved in the Drupal Community
Getting Involved in the Drupal CommunityGetting Involved in the Drupal Community
Getting Involved in the Drupal Community
 
Beginning Plugin d
Beginning Plugin dBeginning Plugin d
Beginning Plugin d
 
Mastering CSS3 Selectors
Mastering CSS3 SelectorsMastering CSS3 Selectors
Mastering CSS3 Selectors
 
Customer Service & Social Media: You Can Do Better
Customer Service & Social Media: You Can Do BetterCustomer Service & Social Media: You Can Do Better
Customer Service & Social Media: You Can Do Better
 

Viewers also liked

Eric Steele – World Plone Day 2010 – Plone 4 Overview
Eric Steele – World Plone Day 2010 – Plone 4 OverviewEric Steele – World Plone Day 2010 – Plone 4 Overview
Eric Steele – World Plone Day 2010 – Plone 4 Overview
Eric Steele
 
SQLAlchemy e Plone: no more zsql methods
SQLAlchemy e Plone: no more zsql methodsSQLAlchemy e Plone: no more zsql methods
SQLAlchemy e Plone: no more zsql methods
Simples Consultoria
 
O Futuro do Plone
O Futuro do PloneO Futuro do Plone
O Futuro do Plone
Simples Consultoria
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
Eric Steele
 
The State of Plone – Plone Conference 2012
The State of Plone – Plone Conference 2012The State of Plone – Plone Conference 2012
The State of Plone – Plone Conference 2012
Eric Steele
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
Eric Steele
 
Plone e JQuery ao gosto do Cliente
Plone e JQuery ao gosto do ClientePlone e JQuery ao gosto do Cliente
Plone e JQuery ao gosto do Cliente
Simples Consultoria
 
Varnish3, Plone4: Discutindo a Relação
Varnish3, Plone4: Discutindo a RelaçãoVarnish3, Plone4: Discutindo a Relação
Varnish3, Plone4: Discutindo a Relação
Simples Consultoria
 
A Look at Plone 4
A Look at Plone 4A Look at Plone 4
A Look at Plone 4
Eric Steele
 
The headless CMS
The headless CMSThe headless CMS
The headless CMS
Érico Andrei
 

Viewers also liked (10)

Eric Steele – World Plone Day 2010 – Plone 4 Overview
Eric Steele – World Plone Day 2010 – Plone 4 OverviewEric Steele – World Plone Day 2010 – Plone 4 Overview
Eric Steele – World Plone Day 2010 – Plone 4 Overview
 
SQLAlchemy e Plone: no more zsql methods
SQLAlchemy e Plone: no more zsql methodsSQLAlchemy e Plone: no more zsql methods
SQLAlchemy e Plone: no more zsql methods
 
O Futuro do Plone
O Futuro do PloneO Futuro do Plone
O Futuro do Plone
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
 
The State of Plone – Plone Conference 2012
The State of Plone – Plone Conference 2012The State of Plone – Plone Conference 2012
The State of Plone – Plone Conference 2012
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
 
Plone e JQuery ao gosto do Cliente
Plone e JQuery ao gosto do ClientePlone e JQuery ao gosto do Cliente
Plone e JQuery ao gosto do Cliente
 
Varnish3, Plone4: Discutindo a Relação
Varnish3, Plone4: Discutindo a RelaçãoVarnish3, Plone4: Discutindo a Relação
Varnish3, Plone4: Discutindo a Relação
 
A Look at Plone 4
A Look at Plone 4A Look at Plone 4
A Look at Plone 4
 
The headless CMS
The headless CMSThe headless CMS
The headless CMS
 

Similar to Continuous Integration Testing for Plone Using Hudson

Mongo db
Mongo dbMongo db
Mongo db
Antonio Terreno
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with Transmogrifier
Clayton Parker
 
Sustainable TDD
Sustainable TDDSustainable TDD
Sustainable TDD
Steven Mak
 
iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...
iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...
iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...
Rudy Jahchan
 
Plone on RelStorage
Plone on RelStoragePlone on RelStorage
Plone on RelStorage
Calvin Hendryx-Parker
 
Buildout for the Future
Buildout for the FutureBuildout for the Future
Buildout for the Future
Clayton Parker
 
Buildout future
Buildout futureBuildout future
Buildout future
Clayton Parker
 
"How Mozilla Uses Selenium"
"How Mozilla Uses Selenium""How Mozilla Uses Selenium"
"How Mozilla Uses Selenium"
Stephen Donner
 
Mini training - Moving to xUnit.net
Mini training - Moving to xUnit.netMini training - Moving to xUnit.net
Mini training - Moving to xUnit.net
Betclic Everest Group Tech Team
 
Chef
ChefChef
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
Rajat Pandit
 
Batou - multi-(host|component|environment|version|platform) deployment
Batou - multi-(host|component|environment|version|platform) deploymentBatou - multi-(host|component|environment|version|platform) deployment
Batou - multi-(host|component|environment|version|platform) deployment
Christian Theune
 
The Tech Side of Project Argo
The Tech Side of Project ArgoThe Tech Side of Project Argo
The Tech Side of Project Argo
Wesley Lindamood
 
Testing iOS Apps
Testing iOS AppsTesting iOS Apps
Testing iOS Apps
C4Media
 
Feature Bits at LSSC10
Feature  Bits at LSSC10Feature  Bits at LSSC10
Feature Bits at LSSC10
Erik Sowa
 
Derailed chef update-oct2010
Derailed chef update-oct2010Derailed chef update-oct2010
Derailed chef update-oct2010
jtimberman
 
Git talk from Open 2011 conference in Israel
Git talk from Open 2011 conference in IsraelGit talk from Open 2011 conference in Israel
Git talk from Open 2011 conference in Israel
Reuven Lerner
 
Build Automation of PHP Applications
Build Automation of PHP ApplicationsBuild Automation of PHP Applications
Build Automation of PHP Applications
Pavan Kumar N
 
Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)
Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)
Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)
Google Developer Relations Team
 
Intro to PHP Testing
Intro to PHP TestingIntro to PHP Testing
Intro to PHP Testing
Ran Mizrahi
 

Similar to Continuous Integration Testing for Plone Using Hudson (20)

Mongo db
Mongo dbMongo db
Mongo db
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with Transmogrifier
 
Sustainable TDD
Sustainable TDDSustainable TDD
Sustainable TDD
 
iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...
iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...
iOSDevCamp 2011 - Getting "Test"-y: Test Driven Development & Automated Deplo...
 
Plone on RelStorage
Plone on RelStoragePlone on RelStorage
Plone on RelStorage
 
Buildout for the Future
Buildout for the FutureBuildout for the Future
Buildout for the Future
 
Buildout future
Buildout futureBuildout future
Buildout future
 
"How Mozilla Uses Selenium"
"How Mozilla Uses Selenium""How Mozilla Uses Selenium"
"How Mozilla Uses Selenium"
 
Mini training - Moving to xUnit.net
Mini training - Moving to xUnit.netMini training - Moving to xUnit.net
Mini training - Moving to xUnit.net
 
Chef
ChefChef
Chef
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
Batou - multi-(host|component|environment|version|platform) deployment
Batou - multi-(host|component|environment|version|platform) deploymentBatou - multi-(host|component|environment|version|platform) deployment
Batou - multi-(host|component|environment|version|platform) deployment
 
The Tech Side of Project Argo
The Tech Side of Project ArgoThe Tech Side of Project Argo
The Tech Side of Project Argo
 
Testing iOS Apps
Testing iOS AppsTesting iOS Apps
Testing iOS Apps
 
Feature Bits at LSSC10
Feature  Bits at LSSC10Feature  Bits at LSSC10
Feature Bits at LSSC10
 
Derailed chef update-oct2010
Derailed chef update-oct2010Derailed chef update-oct2010
Derailed chef update-oct2010
 
Git talk from Open 2011 conference in Israel
Git talk from Open 2011 conference in IsraelGit talk from Open 2011 conference in Israel
Git talk from Open 2011 conference in Israel
 
Build Automation of PHP Applications
Build Automation of PHP ApplicationsBuild Automation of PHP Applications
Build Automation of PHP Applications
 
Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)
Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)
Google Developer DAy 2010 Japan: HTML5 についての最新情報 (マイク スミス)
 
Intro to PHP Testing
Intro to PHP TestingIntro to PHP Testing
Intro to PHP Testing
 

Recently uploaded

LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
TIPNGVN2
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 

Recently uploaded (20)

LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 

Continuous Integration Testing for Plone Using Hudson