<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;C08FQ30zeip7ImA9WhRaEEw.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964</id><updated>2012-02-12T14:56:52.382+13:00</updated><category term="mantis" /><category term="linux" /><category term="firefox" /><category term="me" /><category term="tools" /><category term="opinion" /><category term="python" /><category term="web" /><category term="tap" /><category term="methodology" /><category term="mozilla" /><category term="selenium" /><category term="testing" /><category term="open source" /><category term="automation" /><category term="thunderbird" /><category term="review" /><category term="ldtp" /><category term="links" /><category term="totb" /><title>Dave's Testing Blog</title><subtitle type="html">This is my blog where I write about Software Testing stuff.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.karit.geek.nz/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/geek/UdDW" /><feedburner:info uri="geek/uddw" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;C08ARnY4eyp7ImA9Wx9XE0g.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-8073142473127728023</id><published>2011-01-07T11:07:00.002+13:00</published><updated>2011-01-07T11:10:47.833+13:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-07T11:10:47.833+13:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="selenium" /><title>Selenium Grid Part 4 – How to get Multiple Browsers and Operating Systems working</title><content type="html">One of the cool features of &lt;a href="http://selenium-grid.seleniumhq.org/"&gt;Selenium Grid&lt;/a&gt; other than being able to distribute your tests over multiple computers is its support for multiple environments. An environment is a combination of the operating system and the browser. For instance I have four virtual machines one running Ubuntu and two running Windows XP. I needed two windows machines as it is easier to set up two machines than get two version of IE running on the same machine. These are the environments I set up:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Firefox 3.5 on Linux&lt;/li&gt;
&lt;li&gt;Firefox 3.6 on Linux&lt;/li&gt;
&lt;li&gt;Firefox 3.5 on Windows XP&lt;/li&gt;
&lt;li&gt;Firefox 3.6 on Windows XP&lt;/li&gt;
&lt;li&gt;IE6 on Windows XP&lt;/li&gt;
&lt;li&gt;IE7 on Windows XP&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The environments are fully flexible so you can set up pretty much anything you want in the way of environments. The only limit in combinations is the different browsers and operating systems which &lt;a href="http://seleniumhq.org/about/platforms.html"&gt;Selenium has support for&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
So where to start? Firstly have a look at my other blog posts on getting Selenium Grid set up and running (links at the bottom of the page).&lt;br /&gt;
&lt;br /&gt;
The Grid Hub will need to know about the environments you want to have. This is configure in the grid_configuration.yml file. This the config I am using:&lt;br /&gt;
grid_configuration.yml &lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;hub:
   port: 4444
   remoteControlPollingIntervalInSeconds: 180
   sessionMaxIdleTimeInSeconds: 300
   environments:
       - name:    "Firefox35 on Linux"
         browser: "*firefox"
       - name:    "Firefox36 on Linux"
         browser: "*firefox"
       - name:    "IE6 on WindowsXP"
         browser: "*iehta"
       - name:    "IE7 on WindowsXP"
         browser: "*iehta"
       - name:    "Firefox35 on WindowsXP"
         browser: "*firefox"
       - name:    "Firefox36 on WindowsXP"
         browser: "*firefox"
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
For the different version of Firefox I didn't install them per se as you can only really have one Firefox installed at a time. On Linux I downloaded the &lt;a href="ftp://ftp.mozilla.org/pub/firefox/releases/"&gt;.tar.bz2 files from Mozilla&lt;/a&gt; and just extracted them. On Windows I used the &lt;a href="http://portableapps.com/apps/internet/firefox_portable"&gt;Portable Apps versions of Firefox&lt;/a&gt; as would allow me to install independent of Firefox that don't mess with the registry and stomp on each other.&lt;br /&gt;
&lt;br /&gt;
For each different browser you want to have available on an Operating System you need to have a separate remote control running (though there is &lt;a href="http://jira.openqa.org/browse/GRID-19"&gt;bug open for this&lt;/a&gt;). To tell the remote control where to find the different Firefoxes I added the relelvant path to the Firefox executable to the path before launching the remote control. You can see some examples below; the main gotcha is ensuring that the port numbers don't clash and that you change the IP address to the current host (I am researching how I could make this automatic if you have any ideas please let me know). &lt;br /&gt;
Firefox 3.5 on Linux:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;cd Desktop/selenium-grid-1.0.8/
export PATH="$PATH:/home/user/Desktop/firefox35/"
ant -Dport=5555 -Dhost=172.24.128.70 -DhubURL=&lt;a class="linkification-ext" href="http://172.24.128.68:4444/" title="Linkification: http://172.24.128.68:4444/"&gt;http://172.24.128.68:4444/&lt;/a&gt; -Denvironment="Firefox35 on Linux" -DseleniumArgs="-multiWindow"  launch-remote-control
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Firefox 3.5 on Windows:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;cd c:\selenium-grid-1.0.8
path %path%;C:\Firefox35\App\Firefox
C:\apache-ant-1.8.2\bin\ant.bat -Dport=5555 -Dhost=172.24.128.76 -DhubURL=&lt;a class="linkification-ext" href="http://172.24.128.68:4444/" title="Linkification: http://172.24.128.68:4444/"&gt;http://172.24.128.68:4444/&lt;/a&gt; -Denvironment="Firefox35 on WindowsXP" -DseleniumArgs="-multiWindow"  launch-remote-control
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
IE6 on Windows:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;cd c:\selenium-grid-1.0.8
C:\apache-ant-1.8.2\bin\ant.bat -Dport=5554 -Dhost=172.24.128.76 -DhubURL=&lt;a class="linkification-ext" href="http://172.24.128.68:4444/" title="Linkification: http://172.24.128.68:4444/"&gt;http://172.24.128.68:4444/&lt;/a&gt; -Denvironment="IE6 on WindowsXP" -DseleniumArgs="-multiWindow"  launch-remote-control
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
From those you should be able to figure out how to do most other broswers.&lt;br /&gt;
&lt;br /&gt;
Once you have started them up you should be able to see them all connected to the hub when you have a look at its console (http://&lt;hub's ip=""&gt;:4444/console). So now you need to run your tests against all the different environments you know have. Will I basically outlined the process in &lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-3-integrating.html"&gt;Part 3&lt;/a&gt; so you can copy most of the code from there. The change I made was to SWrunner.py to add more browsers to it. You can see it below:&lt;/hub's&gt;&lt;br /&gt;
SWrunner.py&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;#!/usr/bin/python
'''
Created on 17 July 2010
@author: Dave

This is the test runner to run all the tests

Idea from: &lt;a class="linkification-ext" href="http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/suite_sumo.py?view=markup" title="Linkification: http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/suite_sumo.py?view=markup"&gt;http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/suite_sumo.py?view=markup&lt;/a&gt;
Idea from: &lt;a class="linkification-ext" href="http://saucelabs.com/blog/index.php/2009/09/running-your-selenium-tests-in-parallel-python/" title="Linkification: http://saucelabs.com/blog/index.php/2009/09/running-your-selenium-tests-in-parallel-python/"&gt;http://saucelabs.com/blog/index.php/2009/09/running-your-selenium-tests-in-parallel-python/&lt;/a&gt;
'''

import SWfunctions
from SWconfig import connectionParameters
from SWtestList import testList
import sys
from subprocess import Popen


args = sys.argv

type = None

if len(args) &amp;lt; 2:
    type = 'smoke'
else:
    type = args[1]

tests = []    

if type == 'smoke':
    tests = testList.smoke_list
elif type == 'full':
    tests = testList.full_list

browsers = []
#browsers.append('*firefox')
#browsers.append('Firefox40\ on\ Linux')
browsers.append('Firefox35\ on\ Linux')
browsers.append('Firefox36\ on\ Linux')
browsers.append('IE6\ on\ WindowsXP')
browsers.append('IE7\ on\ WindowsXP')
browsers.append('Firefox35\ on\ WindowsXP')
browsers.append('Firefox36\ on\ WindowsXP')
#browsers.append('Firefox40\ on\ WindowsXP')

processes = []

for browser in browsers:
    vars = connectionParameters
    for test in tests:
        processes.append(Popen('python %s %s %s %s %s %s' % (test, vars.server, vars.port, browser, vars.baseurl, vars.page_load_timeout), shell = True))
        
for process in processes:
    process.wait()
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
So basically that is what you need to do to Selenium Grid working with multiple environments. Any questions, comments, suggestions, etc there is the comments section at the bottom of this post.&lt;br /&gt;
&lt;br /&gt;
The Series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1 - Getting Started &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-2-getting-hudson-to.html"&gt;Part 2 - Getting Hudson to run the tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-3-integrating.html"&gt;Part 3 - Integrating Selenium Python tests with Hudson and having them run in parallel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2011/01/selenium-grid-part-4-how-to-get.html"&gt;Part 4 - How to get Multiple Browsers and Operating Systems working&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Upcoming ideas for the series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Putting the test suite in SVN and running from there&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-8073142473127728023?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tx2mqN56NsXKq4JZm1Zsb_qKfog/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tx2mqN56NsXKq4JZm1Zsb_qKfog/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tx2mqN56NsXKq4JZm1Zsb_qKfog/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tx2mqN56NsXKq4JZm1Zsb_qKfog/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/fHgqHA9Oqw8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/8073142473127728023/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=8073142473127728023" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/8073142473127728023?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/8073142473127728023?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/fHgqHA9Oqw8/selenium-grid-part-4-how-to-get.html" title="Selenium Grid Part 4 – How to get Multiple Browsers and Operating Systems working" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>6</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2011/01/selenium-grid-part-4-how-to-get.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AHSX07eip7ImA9Wx9XE0g.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3804596419936105856</id><published>2010-07-18T14:11:00.002+12:00</published><updated>2011-01-07T11:08:58.302+13:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-07T11:08:58.302+13:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="selenium" /><title>Selenium Grid Part 3 - Integrating Selenium Python tests with Hudson and having them run in parallel</title><content type="html">In part 3 of the my &lt;a href="http://selenium-grid.seleniumhq.org/"&gt;Selenium Grid&lt;/a&gt; series I will be looking at using &lt;a href="http://python.org/"&gt;Python&lt;/a&gt; as the scripting language to write the tests. I am borrowing the ideas from &lt;a href="http://quality.mozilla.org/"&gt;Mozilla QA's&lt;/a&gt; testing of their sites. Their SVN server has some Python base &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; scripts (&lt;a href="http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/"&gt;SUMO SVN&lt;/a&gt; and &lt;a href="http://viewvc.svn.mozilla.org/vc/addons/trunk/site/app/tests/selenium/pythonTests/"&gt;AMO SVN&lt;/a&gt;). I saw an interesting video of them talk about &lt;a href="http://www.testingtv.com/2010/06/08/how-mozilla-uses-selenium/"&gt;Mozilla talking about their use of Selenium at a Conference&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Firstly down &lt;a href="http://seleniumhq.org/download/"&gt;Selenium RC&lt;/a&gt; and from the zip file copy /selenium-python-client-driver-1.0.1/selenium.py and place that in your test directory. This is the library file for allowing Python to talk to the Selenium Grid Hub. Another file that you will need is &lt;a href="http://www.rittau.org/python/"&gt;XML Test Runner&lt;/a&gt;.&amp;nbsp; This XML Test Runner is an extension to Python's built in Unit Testing that will output jUnit style XML reports that Hudson can read and display the results for. &lt;br /&gt;
&lt;br /&gt;
The test suite I am setting out below will run the tests in parallel and has provisions to do more in the future. It can be set up in the future to run different sets of tests, run all the tests in different browsers and has some early examples of external configuration and common functions.&lt;br /&gt;
&lt;br /&gt;
So in my Selenium job in Hudson I changed the execute shell to be: ./Swrunner.py and said that the published jUnit test results are *.xml. I also had to chmod the working directory to give the Hudson user permission to write out the jUnit results out to this directory. One other change I made was to stop using the Selenium Grid Hudson plugin as that seem to have issues with running more tests than there were available nodes, so I fixed this by like in &lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1&lt;/a&gt; of just running the Hub from the command line and that seems to work well.&lt;br /&gt;
&lt;br /&gt;
You can either see the scripts below to &lt;a href="http://files.karit.geek.nz/selenium/python-selenium-example.zip"&gt;download them in a zip file&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
selenium.py - from Selenium RC zip file&lt;br /&gt;
&lt;br /&gt;
SWconfig.py: &lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;'''
Created on 17 July 2010
@author: Dave

These are connection details

Idea from: &lt;a class="linkification-ext" href="http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/vars.py?view=markup" title="Linkification: http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/vars.py?view=markup"&gt;http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/vars.py?view=markup&lt;/a&gt;
'''

class connectionParameters:
    server = '172.24.128.200'
    port = 4444
    baseurl = '&lt;a class="linkification-ext" href="http://shihadwiki.com/" title="Linkification: http://shihadwiki.com"&gt;http://shihadwiki.com&lt;/a&gt;'
    page_load_timeout = 600000
    browser = '*firefox'
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
SWfunctions.py:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;'''
Created on 17 July 2010
@author: Dave

These are some generic function examples for running ShihadWiki.com
'''

     
def openSite(sel, page_load_timeout):
    sel.open("/wiki/Main_Page")
    sel.wait_for_page_to_load(page_load_timeout)
    
def clickMenu(sel, link, page_load_timeout):
    sel.click('//li[@id=\'n-%s\']/a' % (link))
    sel.wait_for_page_to_load(page_load_timeout)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
SWrunner.py:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;#!/usr/bin/python
'''
Created on 17 July 2010
@author: Dave

This is the test runner to run all the tests

Idea from: &lt;a class="linkification-ext" href="http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/suite_sumo.py?view=markup" title="Linkification: http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/suite_sumo.py?view=markup"&gt;http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/suite_sumo.py?view=markup&lt;/a&gt;
Idea from: &lt;a class="linkification-ext" href="http://saucelabs.com/blog/index.php/2009/09/running-your-selenium-tests-in-parallel-python/" title="Linkification: http://saucelabs.com/blog/index.php/2009/09/running-your-selenium-tests-in-parallel-python/"&gt;http://saucelabs.com/blog/index.php/2009/09/running-your-selenium-tests-in-parallel-python/&lt;/a&gt;
'''

import SWfunctions
from SWconfig import connectionParameters
from SWtestList import testList
import sys
from subprocess import Popen


args = sys.argv

type = None

if len(args) &amp;lt; 2:
    type = 'smoke'
else:
    type = args[1]

tests = []    

if type == 'smoke':
    tests = testList.smoke_list
elif type == 'full':
    tests = testList.full_list

browsers = []
browsers.append('*firefox')

processes = []

for browser in browsers:
    vars = connectionParameters
    for test in tests:
        processes.append(Popen('python %s %s %s %s %s %s' % (test, vars.server, vars.port, browser, vars.baseurl, vars.page_load_timeout), shell = True))
        
for process in processes:
    process.wait()
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
SWtestList.py: &lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;'''
Created on 17 July 2010
@author: Dave

These are the tests to execute

Idea from: &lt;a class="linkification-ext" href="http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/tests.py?view=markup" title="Linkification: http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/tests.py?view=markup"&gt;http://viewvc.svn.mozilla.org/vc/projects/sumo/tests/frontend/python_tests/tests.py?view=markup&lt;/a&gt;
'''

class testList():

    smoke_list = []
    #smoke_list.append(file-name.py)
    smoke_list.append('test-gigs.py')
    smoke_list.append('test-songs.py')
    smoke_list.append('test-discography.py')   
    
    full_list = []
    full_list.extend(smoke_list)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
test-discography.py:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;from selenium import selenium
import unittest, time, re
import sys
import SWfunctions
from  xmlrunner import *

host = None
port = None
broswer = None
baseurl = None
page_load_timeout = None

class test_discography(unittest.TestCase):
    
    def setUp(self):
        self.verificationErrors = []
        self.selenium = selenium(host, port, broswer, baseurl)        
        self.selenium.start()
        self.selenium.set_timeout(page_load_timeout)
        
    
    def test_discography(self):
        sel = self.selenium
        SWfunctions.openSite(sel, page_load_timeout)
        SWfunctions.clickMenu(sel, 'Discography', page_load_timeout)
        self.assertEqual("Discography - Shihad Wiki", sel.get_title())
        try: self.failUnless(sel.is_text_present("Discogarphy"))
        except AssertionError, e: self.verificationErrors.append(str(e))
    
    def tearDown(self):
        self.selenium.stop()
        self.assertEqual([], self.verificationErrors)

if __name__ == '__main__':
    args = sys.argv
    host = args[1]
    port  = args[2]
    broswer = args[3]
    baseurl = args[4]
    page_load_timeout = args[5]
    suite = unittest.TestSuite()
    suite.addTest(test_discography('test_discography'))
    #suite.addTest(test_songs.test_songs)
    #unittest.TextTestRunner().run(suite)
    runner = XMLTestRunner(file('results_test_discography_%s.xml' % (broswer), "w"))
    runner.run(suite)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
test-gigs.py&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;from selenium import selenium
import unittest, time, re
import sys
import SWfunctions
from  xmlrunner import *

host = None
port = None
broswer = None
baseurl = None
page_load_timeout = None

class test_gigs(unittest.TestCase):
    
    def setUp(self):
        self.verificationErrors = []
        self.selenium = selenium(host, port, broswer, baseurl)        
        self.selenium.start()
        self.selenium.set_timeout(page_load_timeout)
        
    
    def test_gigs(self):
        sel = self.selenium
        SWfunctions.openSite(sel, page_load_timeout)
        SWfunctions.clickMenu(sel, 'Gigs', page_load_timeout)
        self.assertEqual("Gigs - Shihad Wiki", sel.get_title())
        try: self.failUnless(sel.is_text_present("Gigs"))
        except AssertionError, e: self.verificationErrors.append(str(e))
    
    def tearDown(self):
        self.selenium.stop()
        self.assertEqual([], self.verificationErrors)

if __name__ == '__main__':
    args = sys.argv
    host = args[1]
    port  = args[2]
    broswer = args[3]
    baseurl = args[4]
    page_load_timeout = args[5]
    suite = unittest.TestSuite()
    suite.addTest(test_gigs('test_gigs'))
    #unittest.TextTestRunner().run(suite)
    #runner = xmlrunner.XmlTestRunner(sys.stdout)
    runner = XMLTestRunner(file('results_test_gigs_%s.xml' % (broswer), "w"))
    runner.run(suite)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
test-songs.py&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;from selenium import selenium
import unittest, time, re
import sys
import SWfunctions
from  xmlrunner import *

host = None
port = None
broswer = None
baseurl = None
page_load_timeout = None

class test_songs(unittest.TestCase):
    
    def setUp(self):
        self.verificationErrors = []
        self.selenium = selenium(host, port, broswer, baseurl)        
        self.selenium.start()
        self.selenium.set_timeout(page_load_timeout)
        
    
    def test_songs(self):
        sel = self.selenium
        SWfunctions.openSite(sel, page_load_timeout)
        SWfunctions.clickMenu(sel, 'Songs', page_load_timeout)
        self.assertEqual("Category:Songs - Shihad Wiki", sel.get_title())
        try: self.failUnless(sel.is_text_present("Songs"))
        except AssertionError, e: self.verificationErrors.append(str(e))
    
    def tearDown(self):
        self.selenium.stop()
        self.assertEqual([], self.verificationErrors)

if __name__ == '__main__':
    args = sys.argv
    host = args[1]
    port  = args[2]
    broswer = args[3]
    baseurl = args[4]
    page_load_timeout = args[5]
    suite = unittest.TestSuite()
    suite.addTest(test_songs('test_songs'))
    #suite.addTest(test_songs.test_songs)
    #unittest.TextTestRunner().run(suite)
    runner = XMLTestRunner(file('results_test_songs_%s.xml' % (broswer), "w"))
    runner.run(suite)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
xmlrunner.py - from &lt;a href="http://www.rittau.org/python/"&gt;http://www.rittau.org/python/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1 - Getting Started &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-2-getting-hudson-to.html"&gt;Part 2 - Getting Hudson to run the tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-3-integrating.html"&gt;Part 3 - Integrating Selenium Python tests with Hudson and having them run in parallel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2011/01/selenium-grid-part-4-how-to-get.html"&gt;Part 4 - How to get Multiple Browsers and Operating Systems working&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Upcoming ideas for the series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Putting the test suite in SVN and running from there&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3804596419936105856?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VE3QzRFTILT2yTMxIs5eNTDEJZg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VE3QzRFTILT2yTMxIs5eNTDEJZg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VE3QzRFTILT2yTMxIs5eNTDEJZg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VE3QzRFTILT2yTMxIs5eNTDEJZg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/W3r5RtdAppQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3804596419936105856/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3804596419936105856" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3804596419936105856?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3804596419936105856?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/W3r5RtdAppQ/selenium-grid-part-3-integrating.html" title="Selenium Grid Part 3 - Integrating Selenium Python tests with Hudson and having them run in parallel" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2010/07/selenium-grid-part-3-integrating.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ADRXs_eSp7ImA9Wx9XE0g.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-8289222279278709381</id><published>2010-07-11T17:22:00.003+12:00</published><updated>2011-01-07T11:09:34.541+13:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-07T11:09:34.541+13:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="selenium" /><title>Selenium Grid Part 2 - Getting Hudson to run the tests</title><content type="html">In &lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1&lt;/a&gt; of this series I just did a basic &lt;a href="http://selenium-grid.seleniumhq.org/"&gt;Selenium Grid&lt;/a&gt; setup. In this part I will look at getting &lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt; set up and have that running your tests on command or triggered when some one checks in some code. I will just get it set up to run the tests on command from a local directory as at home I don't have a source control system or code that can be checked in and then tested.&lt;br /&gt;
&lt;br /&gt;
For this I assume you already familiar with the concepts and setup in &lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1&lt;/a&gt;.&lt;br /&gt;
On the Hub server shut down Selenium Grid Hub and following the &lt;a href="http://hudson-ci.org/debian/"&gt;Ubuntu/Debian instructions on the Hudson site&lt;/a&gt;:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;wget -O /tmp/key &lt;a class="linkification-ext" href="http://hudson-ci.org/debian/hudson-ci.org.key" title="Linkification: http://hudson-ci.org/debian/hudson-ci.org.key"&gt;http://hudson-ci.org/debian/hudson-ci.org.key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;sudo apt-key add /tmp/key&lt;/li&gt;
&lt;li&gt;sudo apt-get install daemon&lt;/li&gt;
&lt;li&gt;wget -O /tmp/hudson.deb &lt;a class="linkification-ext" href="http://hudson-ci.org/latest/debian/hudson.deb" title="Linkification: http://hudson-ci.org/latest/debian/hudson.deb"&gt;http://hudson-ci.org/latest/debian/hudson.deb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;sudo dpkg --install /tmp/hudson.deb&lt;/li&gt;
&lt;li&gt;This will add /etc/apt/sources.list.d/hudson.list which means apt will now keep things up to date&lt;/li&gt;
&lt;li&gt;sudo apt-get update&lt;/li&gt;
&lt;li&gt;sudo apt-get install hudson &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
You can now got to http://[hub ip]:8080/ and Hudson will be up and running.&lt;br /&gt;
&lt;br /&gt;
In Hudson:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Manage Hudson -&amp;gt; Manage Plugins -&amp;gt; Advance&lt;/li&gt;
&lt;li&gt;Click "Check Now" in bottom right corner&lt;/li&gt;
&lt;li&gt;From the Updates page install any plugins that need to be updated&lt;/li&gt;
&lt;li&gt;From the Available Plugins in page select Selenium Plugin which has the description of "This plugin turns your Hudson cluster into a Selenium Grid cluster"&lt;/li&gt;
&lt;li&gt;Install it&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Hudson is now responsible for running the Selenium Grid Hub and you can see it at http://[hub ip]:4444/console you can also see a new item on the Hudson menu for Selenium Grid and this will show you that your Remote Control nodes have hooked up.&lt;br /&gt;
&lt;br /&gt;
So now we will make a job that runs the example build in parallel so we can see it run on the nodes.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I set up a Free Style Project&lt;/li&gt;
&lt;li&gt;I gave it a custom workspace of /home/selenium/selenium-grid-1.0.8 this is where I unzipped things in &lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;I'm just executing shell command of ant run-demo-in-parallel&lt;/li&gt;
&lt;li&gt;Save that and from the dash board click build and watch the screen on your nodes&lt;/li&gt;
&lt;li&gt;You will see the browsers pop up on the nodes and do stuff. Like &lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1&lt;/a&gt; the tests will fail &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
The Series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1 - Getting Started &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-2-getting-hudson-to.html"&gt;Part 2 - Getting Hudson to run the tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-3-integrating.html"&gt;Part 3 - Integrating Selenium Python tests with Hudson and having them run in parallel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2011/01/selenium-grid-part-4-how-to-get.html"&gt;Part 4 - How to get Multiple Browsers and Operating Systems working&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Upcoming ideas for the series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Putting the test suite in SVN and running from there&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
References:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://hudson-ci.org/debian/"&gt;http://hudson-ci.org/debian/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.hudson-ci.org/display/HUDSON/Selenium+Plugin"&gt;http://wiki.hudson-ci.org/display/HUDSON/Selenium+Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.infostretch.com/?p=397"&gt;http://blog.infostretch.com/?p=397&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-8289222279278709381?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5IW4FtRnP0Keps7MdHSVUD4kIFc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5IW4FtRnP0Keps7MdHSVUD4kIFc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5IW4FtRnP0Keps7MdHSVUD4kIFc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5IW4FtRnP0Keps7MdHSVUD4kIFc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/-tMUysAK4FA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/8289222279278709381/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=8289222279278709381" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/8289222279278709381?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/8289222279278709381?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/-tMUysAK4FA/selenium-grid-part-2-getting-hudson-to.html" title="Selenium Grid Part 2 - Getting Hudson to run the tests" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2010/07/selenium-grid-part-2-getting-hudson-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ANSHg6eyp7ImA9Wx9XE0g.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3467888717363548949</id><published>2010-07-11T12:59:00.004+12:00</published><updated>2011-01-07T11:09:59.613+13:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-07T11:09:59.613+13:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="selenium" /><title>Selenium Grid Part 1 – Getting Started</title><content type="html">I have been looking at &lt;a href="http://selenium-grid.seleniumhq.org/"&gt;Selenium Grid&lt;/a&gt; which is a tool that allows distributed multi platform and multi browser testing. I have found it is a bit like &lt;a href="http://grinder.sourceforge.net/"&gt;The Grinder&lt;/a&gt; and &lt;a href="http://blog.karit.geek.nz/2009/08/missing-grinder-3-getting-started-guide.html"&gt;the How To guides&lt;/a&gt; seem to miss something, so I going to write about my initial set up and writing in hope it will help others get up and going with what looks like a really useful tool.&lt;br /&gt;
&lt;br /&gt;
My initial setup will involve three Ubuntu VMs. One Ubuntu Server running the hub and two Ubuntu Desktops acting as the nodes. They were set up using the &lt;a href="http://www.vmware.com/products/player/"&gt;VMWare Player&lt;/a&gt; creation tool that does all the work for and installs VMWare Tools and hides most of the install prompts for to help speed the roll out. Then I changed the APT details to use my internal APT Mirror and updated, I also changed the time zone to be New Zealand and installed an SSH server. Everything else I have done the VMs will be list below as it will count as getting Selenium Grid up and running.&lt;br /&gt;
&lt;br /&gt;
Install some things that are needed on all of the machines (sun-java6-jdk is the Canonical Partner repository):&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;sudo apt-get install unzip sun-java6-jdk ant ant-optional&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
I rebooted the systems after this so all the updates could apply and the PATHS all get updated.&lt;br /&gt;
&lt;br /&gt;
On all of the machines download Selenium Grid (&lt;a class="linkification-ext" href="http://selenium-grid.seleniumhq.org/download.html" title="Linkification: http://selenium-grid.seleniumhq.org/download.html"&gt;http://selenium-grid.seleniumhq.org/download.html&lt;/a&gt;) and extract it&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;wget &lt;a class="linkification-ext" href="http://release.seleniumhq.org/selenium-grid/selenium-grid-1.0.8-bin.zip" title="Linkification: http://release.seleniumhq.org/selenium-grid/selenium-grid-1.0.8-bin.zip"&gt;http://release.seleniumhq.org/selenium-grid/selenium-grid-1.0.8-bin.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;unzip selenium-grid-1.0.8-bin.zip&lt;/li&gt;
&lt;li&gt;cd selenium-grid-1.0.8/&lt;/li&gt;
&lt;li&gt;ant sanity-check&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The ant sanity-check will check that everything is installed correctly&lt;br /&gt;
&lt;br /&gt;
On the hub machine start the hub&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;ant launch-hub&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Give it a little bit to start up and then go to the following URL and you can check that it is all up and running by looking at http://&lt;hub-ip&gt;[hub ip]:4444/console&lt;/hub-ip&gt;&lt;br /&gt;
&lt;br /&gt;
On each of the nodes run the following command to start the remote controls, you will have to do this from a terminal on the desktop, so it knows where the display is so can run your browser.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;ant -Dport=5555 -Dhost=[node ip]&lt;node ip=""&gt; -DhubURL=http://&lt;/node&gt;[hub ip]&lt;node ip=""&gt;&lt;hub ip=""&gt;:4444/ launch-remote-control&lt;/hub&gt;&lt;/node&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Have a look at http://[hub ip]&lt;hub-ip&gt;:4444/console and you should see your two nodes are connected.&lt;br /&gt;
&lt;br /&gt;
On your desktop from the selenium-grid-1.0.8 directory run the following (you will need the JDK and Ant on this machine as well)&lt;/hub-ip&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;ant run-demo-in-parallel&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
On both of the desktops you will see Firefox open up a do stuff. It does fail as I believe Google has changed their site since the example tests were written. But you can see everything opening up and running the tests in parallel over the two desktops.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html"&gt;Part 1 - Getting Started &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-2-getting-hudson-to.html"&gt;Part 2 - Getting Hudson to run the tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2010/07/selenium-grid-part-3-integrating.html"&gt;Part 3 - Integrating Selenium Python tests with Hudson and having them run in parallel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2011/01/selenium-grid-part-4-how-to-get.html"&gt;Part 4 - How to get Multiple Browsers and Operating Systems working&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Upcoming ideas for the series:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Putting the test suite in SVN and running from there&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
References&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://selenium-grid.seleniumhq.org/get_started.html"&gt;http://selenium-grid.seleniumhq.org/get_started.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://selenium-grid.seleniumhq.org/run_the_demo.html"&gt;http://selenium-grid.seleniumhq.org/run_the_demo.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3467888717363548949?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sgj0s-ZHmZf4JQ15qm2dwpRaYFA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sgj0s-ZHmZf4JQ15qm2dwpRaYFA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sgj0s-ZHmZf4JQ15qm2dwpRaYFA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sgj0s-ZHmZf4JQ15qm2dwpRaYFA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/kgDz7Ds01Y8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3467888717363548949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3467888717363548949" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3467888717363548949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3467888717363548949?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/kgDz7Ds01Y8/selenium-grid-part-1-getting-started.html" title="Selenium Grid Part 1 – Getting Started" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2010/07/selenium-grid-part-1-getting-started.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4AQX85fip7ImA9Wx9XE0g.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3345958804204739353</id><published>2010-07-08T20:36:00.001+12:00</published><updated>2011-01-07T11:29:00.126+13:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-07T11:29:00.126+13:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="selenium" /><title>Selenium Connecting to New Windows</title><content type="html">I have been evaluating &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; as of late. One thing I was having issues with was connecting to new windows opened with target="_blank" link using the selectWindow function. It wasn't working and a looked high and low for information on why I could not connect to the newly opened window. I couldn't find anything helpful. Even got no replies to my question on the &lt;a href="http://groups.google.com/group/selenium-users/browse_thread/thread/d1fa1082fe8b05e6"&gt;email list&lt;/a&gt;. I was finally poking around and found out that selectWindow just won't work in &lt;a href="http://seleniumhq.org/projects/ide/"&gt;Selenium IDE&lt;/a&gt; and that you need to use &lt;a href="http://seleniumhq.org/projects/remote-control/"&gt;Selenium RC&lt;/a&gt; or &lt;a href="http://selenium-grid.seleniumhq.org/"&gt;Selenium Grid&lt;/a&gt;. So hopefully this blog post will help people who have the same issue as I had figure out how to get this working. I guess I'm not the only one who has done their first investigation and evaluation of how Selenium works using the Selenium IDE before moving on RC and Grid. Also while I was using RC and the Grid I was using Python files rather than the default HTML that IDE uses. Below you can see the files of my example case it will also close the window and reconnect with the original launching window.&lt;br /&gt;
&lt;br /&gt;
Python Test Script:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;from selenium import selenium
import unittest, time, re

class test_link_to_blank(unittest.TestCase):
    def setUp(self):
        self.verificationErrors = []
        self.selenium = selenium("localhost", 4444, "*chrome", "&lt;a class="linkification-ext" href="file:///D:/code/selenium/sandpit/new-window/base-page-blank.html" title="Linkification: file:///D:/code/selenium/sandpit/new-window/base-page-blank.html"&gt;file:///D:/code/selenium/sandpit/new-window/base-page-blank.html&lt;/a&gt;")
        self.selenium.start()
    
    def test_test_link_to_blank(self):
        sel = self.selenium
        sel.open("&lt;a class="linkification-ext" href="file:///D:/code/selenium/sandpit/new-window/base-page-blank.html" title="Linkification: file:///D:/code/selenium/sandpit/new-window/base-page-blank.html"&gt;file:///D:/code/selenium/sandpit/new-window/base-page-blank.html&lt;/a&gt;")
        self.assertEqual("Base Page Blank", sel.get_title())
        try: self.failUnless(sel.is_text_present("Base Page Blank"))
        except AssertionError, e: self.verificationErrors.append(str(e))
        sel.click("link=Link")
        sel.select_window("title=Pop Up Window")
        self.assertEqual("Pop Up Window", sel.get_title())
        try: self.failUnless(sel.is_text_present("Pop Up Window"))
        except AssertionError, e: self.verificationErrors.append(str(e))
        sel.close()
        sel.select_window("null")
        self.assertEqual("Base Page Blank", sel.get_title())
        try: self.failUnless(sel.is_text_present("Base Page Blank"))
        except AssertionError, e: self.verificationErrors.append(str(e))
    
    def tearDown(self):
        self.selenium.stop()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
base-page-blank.html:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Base Page Blank&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;p&amp;gt;Base Page Blank&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;a href="popup.html" target="_blank"&amp;gt;Link&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
popup.html:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Pop Up Window&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;p&amp;gt;Pop Up Window&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3345958804204739353?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WVJO3MIDnQma1tJJbS9xd__wXp4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WVJO3MIDnQma1tJJbS9xd__wXp4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WVJO3MIDnQma1tJJbS9xd__wXp4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WVJO3MIDnQma1tJJbS9xd__wXp4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/eCgcuqoAXD4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3345958804204739353/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3345958804204739353" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3345958804204739353?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3345958804204739353?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/eCgcuqoAXD4/selenium-connecting-to-new-windows.html" title="Selenium Connecting to New Windows" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>6</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2010/07/selenium-connecting-to-new-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBR3o_eyp7ImA9WxFbEU8.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-2150003348902813672</id><published>2010-07-03T13:22:00.001+12:00</published><updated>2010-07-03T13:22:36.443+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-03T13:22:36.443+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Videoing Testing</title><content type="html">A little while back I went on &lt;a href="http://www.satisfice.com/blog/"&gt;James Bach's&lt;/a&gt; &lt;a href="http://www.satisfice.com/seminars.shtml"&gt;Rapid Software Testing Course&lt;/a&gt; run via &lt;a href="http://www.softed.co.nz/Courses/Rapid-Software-Testing.aspx"&gt;SoftEd&lt;/a&gt; here in Wellington. One thing he mentioned and I took away is recording what testing you do. He said he went as far as recording everything with video camera. This is helpful as it records what you are doing and can see the chain of events leading up to a problem. Hard disks are getting cheap these days and can store many hours worth of video. I haven't gone as far as recording everything I do yet. What I have started to do instead of spending time copying and pasting screen shots (though &lt;a href="http://sourceforge.net/projects/lightscreen/"&gt;Lightscreen&lt;/a&gt; helps a load with taking screen shots) is just record the whole reproduction case. By the time you have taken individual screen shots and written the steps that you have performed and tried to explain what the defective behaviour looks like I find that it is quicker just to record a video and attached that to the defect than taking screen shots and writing it up. I have also found the "I can't reproduce it" comments decrease as well. On Ubuntu I use &lt;a href="http://recordmydesktop.sourceforge.net/"&gt;gtk-recordMyDesktop&lt;/a&gt; and on Windows I use &lt;a href="http://sourceforge.net/projects/camstudio/"&gt;CamStudio&lt;/a&gt; (the old Open Source on Soureforge). Give it a go I have found it extremely worthwhile seeing the screen recording tools are free.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-2150003348902813672?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Tf8YkR1o0YujOQoDfLxMwV_pen0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Tf8YkR1o0YujOQoDfLxMwV_pen0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Tf8YkR1o0YujOQoDfLxMwV_pen0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Tf8YkR1o0YujOQoDfLxMwV_pen0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/xw7zW2HhroU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/2150003348902813672/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=2150003348902813672" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/2150003348902813672?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/2150003348902813672?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/xw7zW2HhroU/little-while-back-i-went-on-james-bachs.html" title="Videoing Testing" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2010/07/little-while-back-i-went-on-james-bachs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcERX0zeyp7ImA9WxFUFUQ.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-7737373166762905371</id><published>2010-06-27T12:03:00.000+12:00</published><updated>2010-06-27T12:03:24.383+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-27T12:03:24.383+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>CITCON NZ 2010</title><content type="html">This weekend I spent time at &lt;a href="http://citconf.com/wiki/index.php?title=Main_Page#CITCON_ANZ_2010_Wellington"&gt;CITCON NZ 2010&lt;/a&gt; (Its pronounced kitcon rather than citcon). It is an &lt;a href="http://en.wikipedia.org/wiki/Open_space_conference"&gt;Open Spaces Conference&lt;/a&gt; on Continuous Integration. I really enjoyed it and depending on the location will look at going to it again next year. I now have a lot of ideas and links to research. I will look at writing up some more blog posts at what once I have digested and thought about this more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-7737373166762905371?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_zlhOfCKopfsJqdaUUn7LoHJUY8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_zlhOfCKopfsJqdaUUn7LoHJUY8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_zlhOfCKopfsJqdaUUn7LoHJUY8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_zlhOfCKopfsJqdaUUn7LoHJUY8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/LzcvFCfoB48" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/7737373166762905371/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=7737373166762905371" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/7737373166762905371?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/7737373166762905371?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/LzcvFCfoB48/citcon-nz-2010.html" title="CITCON NZ 2010" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2010/06/citcon-nz-2010.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4HQX85eSp7ImA9WxFUFUQ.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-5564316903563491261</id><published>2010-06-27T12:02:00.000+12:00</published><updated>2010-06-27T12:02:10.121+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-27T12:02:10.121+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="me" /><title>New Blog</title><content type="html">A while back I set up a new blog &lt;a href="http://mytwocents.karit.geek.nz/"&gt;Dave's Two Cents&lt;/a&gt; it where I write all sorts of things that don't fit this blog's main focus which is software testing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-5564316903563491261?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PXi-yEDkwlvcwQxdirLzSLkNAu4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PXi-yEDkwlvcwQxdirLzSLkNAu4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PXi-yEDkwlvcwQxdirLzSLkNAu4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PXi-yEDkwlvcwQxdirLzSLkNAu4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/YWEt2aakqBk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/5564316903563491261/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=5564316903563491261" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5564316903563491261?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5564316903563491261?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/YWEt2aakqBk/new-blog.html" title="New Blog" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2010/06/new-blog.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4DQnw4eip7ImA9WxNbGEg.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3896585505806011056</id><published>2009-11-22T13:47:00.001+13:00</published><updated>2009-11-22T13:49:33.232+13:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-22T13:49:33.232+13:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Testing at University</title><content type="html">I did Computer Science while I was at University. Thinking back to my time there I think the only testing covered was about five minutes and introduced the idea of white box and black box testing. Being a tester I think that there should be more testing in University. Sure the majority of people doing Computer Science are going to get into the development but even so developers need to test as well.&lt;br /&gt;&lt;br /&gt;The first I ever heard about JUnit and Unit Testing was when I was in the industry. So basically all the developers coming out of University have to learn about Unit Testing when they start working and then they learn all about it, so there Unit Tests mightn't be the best coverage or there may be some resistance to doing it as they haven never seen as part of "coding" before. Though when they start seeing continuous integration catching bugs and they personally start seeing their unit test catching things and that last time they did something similar was caught by the test team and went through the defect tracking system etc which everyone can see.&lt;br /&gt;&lt;br /&gt;There will be the argument that Computer Science is there to teach Computer Science not Professional Software Development. What I say to that is how many people doing Computer Science go on to become Computer Scientists and how many go on to do work in Software Development?&lt;br /&gt;&lt;br /&gt;Also could it help the students and lecturers? Maybe in first year when assignments are very directed  do this, do that, do a while loop, do a for loop etc. giving the students the JUnit tests and have them write their code to match that. This will also make marking very easy as it will be run the Unit Tests and see if they pass or not.&lt;br /&gt;&lt;br /&gt;Also later on when students are implementing algorithms to aid the understanding of what they are doing in lectures could get them to write unit tests to help show that they understand the code they are writing and where they were trying to get to with the code they are writing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3896585505806011056?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/L66Iah71HObRV6pOuAhxVRoBvO0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L66Iah71HObRV6pOuAhxVRoBvO0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/L66Iah71HObRV6pOuAhxVRoBvO0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L66Iah71HObRV6pOuAhxVRoBvO0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/fd9mnfQK9fU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3896585505806011056/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3896585505806011056" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3896585505806011056?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3896585505806011056?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/fd9mnfQK9fU/testing-at-university.html" title="Testing at University" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/11/testing-at-university.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMESH09eCp7ImA9WxNSFk0.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-8474256708744784976</id><published>2009-08-30T15:31:00.002+12:00</published><updated>2009-08-30T15:36:49.360+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-30T15:36:49.360+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Getting soapUI Test Cases to check Databases</title><content type="html">I have done some investigating of how to connect to a Database and query to ensure that the data from the SOAP call in soapUI has made it all the way to the DB.&lt;br /&gt;&lt;br /&gt;Firstly ensure you have&lt;a href="http://www.soapui.org/userguide/jdbcDriversLinks.html"&gt; downloaded the relevant JDBC driver jar file&lt;/a&gt; and placed it in $SOAPUI_HOME/bin/ext and then restarted soapUI as it only seems to grab the file on restart.&lt;br /&gt;&lt;br /&gt;Below is a simple &lt;a href="http://en.wikipedia.org/wiki/Groovy_%28programming_language%29"&gt;Groovy&lt;/a&gt; which Have put in as a test step which will go to the database and check if the you want is there. It will need some additions like the addition of a where clause I would guess. If the count or data for that matter is right it will assert true or false as applicable and show up in results.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 95%;"&gt;&lt;code&gt;import groovy.sql.Sql&lt;br /&gt;def ERROR_MSG = "The count is not 1"&lt;br /&gt;sql = Sql.newInstance("jdbc:mysql://localhost:3306/demo", "demo", "password", "com.mysql.jdbc.Driver")&lt;br /&gt;row = sql.firstRow("SELECT count(*) count FROM foo")&lt;br /&gt;log.info("Count: ${row.count}")&lt;br /&gt;assert (1 == row.count):ERROR_MSG&lt;br /&gt;sql.close()&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Also remember before running these test ensure that the database is truncated or your SQL takes into account only to look the results that you want it to look at not ones from earlier runs. If you are testing automatically with &lt;a href="http://blog.karit.geek.nz/2009/08/using-soapui-to-do-testing-as-part-of.html"&gt;Maven&lt;/a&gt; you could get Maven to do the cleaning up and prep work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-8474256708744784976?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6ETXXRlCnh_FftnRWoNVSw3Uzoc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6ETXXRlCnh_FftnRWoNVSw3Uzoc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6ETXXRlCnh_FftnRWoNVSw3Uzoc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6ETXXRlCnh_FftnRWoNVSw3Uzoc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/eC09UZvdbcE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/8474256708744784976/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=8474256708744784976" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/8474256708744784976?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/8474256708744784976?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/eC09UZvdbcE/getting-soapui-test-cases-to-check.html" title="Getting soapUI Test Cases to check Databases" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/08/getting-soapui-test-cases-to-check.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUHRHg6eyp7ImA9WxNSFUU.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-6005631987153738788</id><published>2009-08-30T11:20:00.003+12:00</published><updated>2009-08-30T11:23:55.613+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-30T11:23:55.613+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Using soapUI to do testing as part of a Maven2 build</title><content type="html">&lt;a href="http://www.soapui.org/"&gt;soapUI&lt;/a&gt; has a &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt; plugin. soapUI has a &lt;a href="http://www.soapui.org/plugin/maven2/index.html"&gt;Maven getting started guide&lt;/a&gt; and Maven has a &lt;a href="http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html"&gt;Maven getting started guide&lt;/a&gt;. Well I thought I would have a go at joining them together, so I can a Maven script automatically run my soapUI tests and output a jUnit compatible results file.&lt;br /&gt;&lt;br /&gt;Pre Reqs:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Maven 2 installed&lt;/li&gt;&lt;li&gt;soapUI with a project that already has some tests setup&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Setup a new project. This will create you a new project in a new directory called app. To do this run "mvn archetype:create -DgroupId=nz.geek.karit.app -DartifactId=app"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;To pom.xml add:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 95%"&gt;&lt;code&gt;&amp;lt;!--Add the repository for where Maven can find the soapUI Plugin--&amp;gt;&lt;br /&gt;&amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;   &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;eviwarePluginRepository&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;url&amp;gt;http://www.eviware.com/repository/maven2/&amp;lt;/url&amp;gt;&lt;br /&gt;   &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;&amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt;&amp;lt;build&amp;gt;&lt;br /&gt;&amp;lt;plugins&amp;gt;&lt;br /&gt;  &amp;lt;plugin&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;eviware&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;maven-soapui-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;!--This is the version of soapUI to grab from plugin repo--&amp;gt;&lt;br /&gt;  &amp;lt;!--At the time of writing the 3.0.1 plugin had not been created--&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;2.5.1&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;configuration&amp;gt;&lt;br /&gt;    &amp;lt;!--The location of your soapUI setting file--&amp;gt;&lt;br /&gt;    &amp;lt;projectFile&amp;gt;/home/test/test.xml&amp;lt;/projectFile&amp;gt;&lt;br /&gt;    &amp;lt;!--Where to place the output of the run--&amp;gt;&lt;br /&gt;    &amp;lt;outputFolder&amp;gt;/home/test/output/&amp;lt;/outputFolder&amp;gt;&lt;br /&gt;    &amp;lt;!--Make the jUnit results file--&amp;gt;&lt;br /&gt;    &amp;lt;junitReport&amp;gt;true&amp;lt;/junitReport&amp;gt;&lt;br /&gt;  &amp;lt;/configuration&amp;gt;&lt;br /&gt;  &amp;lt;executions&amp;gt;&lt;br /&gt;    &amp;lt;execution&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;soapUI&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;!--Run as part of the test phase in the Maven lifecycle--&amp;gt;&lt;br /&gt;      &amp;lt;phase&amp;gt;test&amp;lt;/phase&amp;gt;&lt;br /&gt;      &amp;lt;goals&amp;gt;&lt;br /&gt;        &amp;lt;!--Run the test phase of eviware:maven-soapui-plugin--&amp;gt;&lt;br /&gt;        &amp;lt;goal&amp;gt;test&amp;lt;/goal&amp;gt;&lt;br /&gt;      &amp;lt;/goals&amp;gt;&lt;br /&gt;    &amp;lt;/execution&amp;gt;&lt;br /&gt;  &amp;lt;/executions&amp;gt;&lt;br /&gt;  &amp;lt;/plugin&amp;gt;&lt;br /&gt;&amp;lt;/plugins&amp;gt;&lt;br /&gt;&amp;lt;/build&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You can now run the soapUI tests by calling "mvn eviware:maven-soapui-plugin:test"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It will also run as part of Maven with "mvn test" for example&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;For all the different properties you can set see: &lt;a href="http://www.soapui.org/plugin/maven2/properties.html%20"&gt;http://www.soapui.org/plugin/maven2/properties.html &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Along with running the test you can also run the loadtests and start the mock web service all from Maven. You can do this by calling a goal other than test. For the details see:&lt;a href="http://www.soapui.org/plugin/maven2/properties.html%20"&gt; http://www.soapui.org/plugin/maven2/goals.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My full pom.xml:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 95%"&gt;&lt;code&gt;&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;  xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;nz.geek.karit.app&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;app&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;name&amp;gt;app&amp;lt;/name&amp;gt;&lt;br /&gt;  &amp;lt;url&amp;gt;http://maven.apache.org&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;dependencies&amp;gt;&lt;br /&gt;    &amp;lt;dependency&amp;gt;&lt;br /&gt;      &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;&lt;br /&gt;      &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;3.8.1&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;    &amp;lt;/dependency&amp;gt;&lt;br /&gt;  &amp;lt;/dependencies&amp;gt;&lt;br /&gt;&amp;lt;!--Add the repository for where Maven can find the soapUI Plugin--&amp;gt;&lt;br /&gt;&amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;   &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;eviwarePluginRepository&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;url&amp;gt;http://www.eviware.com/repository/maven2/&amp;lt;/url&amp;gt;&lt;br /&gt;   &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;&amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt;&amp;lt;build&amp;gt;&lt;br /&gt;&amp;lt;plugins&amp;gt;&lt;br /&gt;  &amp;lt;plugin&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;eviware&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;maven-soapui-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;!--This is the version of soapUI to grab from plugin repo--&amp;gt;&lt;br /&gt;  &amp;lt;!--At the time of writing the 3.0.1 plugin had not been created--&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;2.5.1&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;configuration&amp;gt;&lt;br /&gt;    &amp;lt;!--The location of your soapUI setting file--&amp;gt;&lt;br /&gt;    &amp;lt;projectFile&amp;gt;/home/test/test.xml&amp;lt;/projectFile&amp;gt;&lt;br /&gt;    &amp;lt;!--Where to place the output of the run--&amp;gt;&lt;br /&gt;    &amp;lt;outputFolder&amp;gt;/home/test/output/&amp;lt;/outputFolder&amp;gt;&lt;br /&gt;    &amp;lt;!--Make the jUnit results file--&amp;gt;&lt;br /&gt;    &amp;lt;junitReport&amp;gt;true&amp;lt;/junitReport&amp;gt;&lt;br /&gt;  &amp;lt;/configuration&amp;gt;&lt;br /&gt;  &amp;lt;executions&amp;gt;&lt;br /&gt;    &amp;lt;execution&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;soapUI&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;!--Run as part of the test phase in the Maven lifecycle--&amp;gt;&lt;br /&gt;      &amp;lt;phase&amp;gt;test&amp;lt;/phase&amp;gt;&lt;br /&gt;      &amp;lt;goals&amp;gt;&lt;br /&gt;        &amp;lt;!--Run the test phase of eviware:maven-soapui-plugin--&amp;gt;&lt;br /&gt;        &amp;lt;goal&amp;gt;test&amp;lt;/goal&amp;gt;&lt;br /&gt;      &amp;lt;/goals&amp;gt;&lt;br /&gt;    &amp;lt;/execution&amp;gt;&lt;br /&gt;  &amp;lt;/executions&amp;gt;&lt;br /&gt;  &amp;lt;/plugin&amp;gt;&lt;br /&gt;&amp;lt;/plugins&amp;gt;&lt;br /&gt;&amp;lt;/build&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-6005631987153738788?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tDFtrydBFvZVk5JrFp0ok38oSgY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tDFtrydBFvZVk5JrFp0ok38oSgY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tDFtrydBFvZVk5JrFp0ok38oSgY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tDFtrydBFvZVk5JrFp0ok38oSgY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/FZQil7xS3wo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/6005631987153738788/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=6005631987153738788" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/6005631987153738788?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/6005631987153738788?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/FZQil7xS3wo/using-soapui-to-do-testing-as-part-of.html" title="Using soapUI to do testing as part of a Maven2 build" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/08/using-soapui-to-do-testing-as-part-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEMQHczfyp7ImA9WxNSEE0.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-5393542487906506887</id><published>2009-08-23T18:24:00.000+12:00</published><updated>2009-08-23T18:24:41.987+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-23T18:24:41.987+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>The Missing Grinder 3 Getting Started Guide</title><content type="html">&lt;p&gt;I have been looking at &lt;a href="http://grinder.sourceforge.net/"&gt;The Grinder&lt;/a&gt; to see what it is like at &lt;a href="http://grinder.sourceforge.net/g3/features.html"&gt;performance testing&lt;/a&gt;. Though I found the &lt;a href="http://grinder.sourceforge.net/g3/getting-started.html"&gt;getting started section&lt;/a&gt; to cover the tool but it didn't really cover the the I want to click here, here and here and have it just request a page from my web server, so hopefully this will get you past that. I have always found the first five minutes with a tool the complicated ones and need enough to get going and over that first hurdle.&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
Pre Reqs:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A web server that you have permission to test with. For me it is localhost and running on port 80.&lt;/li&gt;
&lt;li&gt;I am doing this on Ubuntu doing something similar on Windows should do the trick.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The steps:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Download &lt;a href="http://sourceforge.net/projects/grinder/"&gt;The Grinder 3&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Unzip it. I unzipped it to /home/test/Desktop/grinder-3.2 &lt;/li&gt;
&lt;li&gt;Create a new directory /home/test/Desktop/grinder-3.2/demo. All files created, edited etc should be in here.&lt;/li&gt;
&lt;li&gt;Create a new file in demo called grinder.properties I copied the below from the examples directory and changed the grinder.script to simple.py &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;grinder.properties: &lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;#
# Sample grinder.properties
#
#
# The properties can be specified in three ways.
#  - In the console. A properties file in the distribution directory
#    can be selected in the console.
#  - As a Java system property in the command line used to start the
#    agent. (e.g. java -Dgrinder.threads=20 net.grinder.Grinder).
#  - In an agent properties file. A local properties file named
#    "grinder.properties" can be placed in the working directory of
#    each agent, or a different file name passed as an agent command
#    line argument.
#
# Properties present in a console selected file take precedence over
# agent command line properties, which in turn override those in
# an agent properties file.
#
# Any line which starts with a ; (semi-colon) or a # (hash) is a
# comment and is ignored. In this example we will use a # for
# commentary and a ; for parts of the config file that you may wish to
# enable
#
# Please refer to
# http://net.grinder.sourceforge.net/g3/properties.html for further
# documentation.


#
# Commonly used properties
#

# The file name of the script to run.
#
# Relative paths are evaluated from the directory containing the
# properties file. The default is "grinder.py".
grinder.script = simple.py

# The number of worker processes each agent should start. The default
# is 1.
grinder.processes = 1

# The number of worker threads each worker process should start. The
# default is 1.
grinder.threads = 1

# The number of runs each worker process will perform. When using the
# console this is usually set to 0, meaning "run until the console
# sneds a stop or reset signal". The default is 1.
grinder.runs = 0

# The IP address or host name that the agent and worker processes use
# to contact the console. The default is all the network interfaces
# of the local machine.
; grinder.consoleHost = consolehost

# The IP port that the agent and worker processes use to contact the
# console. Defaults to 6372.
; grinder.consolePort



#
# Less frequently used properties
#


### Logging ###

# The directory in which worker process logs should be created. If not
# specified, the agent's working directory is used.
grinder.logDirectory = log

# The number of archived logs from previous runs that should be kept.
# The default is 1.
grinder.numberOfOldLogs = 2

# Overrides the "host" string used in log filenames and logs. The
# default is the host name of the machine running the agent.
; grinder.hostID = myagent

# Set to false to disable the logging of output and error steams for
# worker processes. You might want to use this to reduce the overhead
# of running a client thread. The default is true.
; grinder.logProcessStreams = false


### Script sleep time ####

# The maximum time in milliseconds that each thread waits before
# starting. Unlike the sleep times specified in scripts, this is
# varied according to a flat random distribution. The actual sleep
# time will be a random value between 0 and the specified value.
# Affected by grinder.sleepTimeFactor, but not
# grinder.sleepTimeVariation. The default is 0ms.
; grinder.initialSleepTime=500

# Apply a factor to all the sleep times you've specified, either
# through a property of in a script. Setting this to 0.1 would run the
# script ten times as fast. The default is 1.
; grinder.sleepTimeFactor=0.01

# The Grinder varies the sleep times specified in scripts according to
# a Normal distribution. This property specifies a fractional range
# within which nearly all (99.75%) of the times will lie. E.g., if the
# sleep time is specified as 1000 and the sleepTimeVariation is set to
# 0.1, then 99.75% of the actual sleep times will be between 900 and
# 1100 milliseconds. The default is 0.2.
; grinder.sleepTimeVariation=0.005


### Worker process control ###

# If set, the agent will ramp up the number of worker processes,
# starting the number specified every
# grinder.processesIncrementInterval milliseconds. The upper limit is
# set by grinder.processes. The default is to start all worker
# processes together.
; grinder.processIncrement = 1

# Used in conjunction with grinder.processIncrement, this property
# sets the interval in milliseconds at which the agent starts new
# worker processes. The value is in milliseconds. The default is 60000
# ms.
; grinder.processIncrementInterval = 10000

# Used in conjunction with grinder.processIncrement, this property
# sets the initial number of worker processes to start. The default is
# the value of grinder.processIncrement.
; process.initialProcesses = 1

# The maximum length of time in milliseconds that each worker process
# should run for. grinder.duration can be specified in conjunction
# with grinder.runs, in which case the worker processes will terminate
# if either the duration time or the number of runs is exceeded. The
# default is to run forever.
; grinder.duration = 60000

# If set to true, the agent process spawns engines in threads rather
# than processes, using special class loaders to isolate the engines.
# This allows the engine to be easily run in a debugger. This is
# primarily a tool for debugging The Grinder engine, but it might also
# be useful to advanced users. The default is false.
; grinder.debug.singleprocess = true


### Java ###

# Use an alternate JVM for worker processes. The default is "java" so
# you do not need to specify this if java is in your PATH.
; grinder.jvm = /opt/jrockit/jrockit-R27.5.0-jdk1.5.0_14/bin/java

# Use to adjust the classpath used for the worker process JVMs.
# Anything specified here will be prepended to the classpath used to
# start the Grinder processes.
; grinder.jvm.classpath = /tmp/myjar.jar

# Additional arguments to worker process JVMs.
; grinder.jvm.arguments = -Dpython.cachedir=/tmp


### Console communications ###

# (See above for console address properties).

# If you are not using the console, and don't want the agent to try to
# contact it, set grinder.useConsole = false. The default is true.
; grinder.useConsole = false

# The period at which each process sends updates to the console. This
# also controls the frequency at which the data files are flushed.
# The default is 500 ms.
; grinder.reportToConsole.interval = 100


### Statistics ###

# Set to false to disable reporting of timing information to the
# console; other statistics are still reported. See
# http://grinder.sourceforge.net/faq.html#timing for why you might
# want to do this. The default is true.
; grinder.reportTimesToConsole = false

# If set to true, System.nanoTime() is used for measuring time instead
# of System.currentTimeMills(). The Grinder will still report times in
# milliseconds. The precision of these methods depends on the JVM
# implementation and the operating system. Setting to true requires
# J2SE 5 or later. The default is false.
; grinder.useNanoTime = true
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Following the bit at the very end of &lt;a href="http://grinder.sourceforge.net/g3/getting-started.html#howtostart"&gt;getting started guide&lt;/a&gt; setup the three .sh scripts (setGrinderEnv.sh, startAgent.sh, startConsole.sh) as outlined and place them in the demo directory. I changed them to run to use bash instead of ksh as have bash installed not ksh. &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;setGrinderEnv.sh: &lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;#!/bin/bash
GRINDERPATH=/home/test/Desktop/grinder-3.2/
GRINDERPROPERTIES=/home/test/Desktop/grinder-3.2/demo/grinder.properties
CLASSPATH=$GRINDERPATH/lib/grinder.jar:$CLASSPATH
#How I found it
#ls -l `which java`
#The above gave me: /usr/bin/java -&amp;gt; /etc/alternatives/java
#ls -l /etc/alternatives/java
#Which gave me: /etc/alternatives/java -&amp;gt; /usr/lib/jvm/java-6-sun/jre/bin/java
JAVA_HOME=/usr/lib/jvm/java-6-sun/jre/
PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH PATH GRINDERPROPERTIES
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;startConsole.sh:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;#!/bin/bash
. ./setGrinderEnv.sh
java -cp $CLASSPATH net.grinder.Console
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;startAgent.sh:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;#!/bin/bash
. ./setGrinderEnv.sh
java -cp $CLASSPATH net.grinder.Grinder $GRINDERPROPERTIES
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Make the four .sh scripts executable chmod +x *.sh&lt;/li&gt;
&lt;li&gt;Run ./startConsole.sh&lt;/li&gt;
&lt;li&gt;Run ./startAgent.sh&lt;/li&gt;
&lt;li&gt;In the Grinder Console under the Processes tab it shows that the agent has connected to the console &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_6VUo2CP8Uzg/SpDcoWRZS5I/AAAAAAAAAHU/5yxOgSeyNI0/s1600-h/grinder-connected-agent.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_6VUo2CP8Uzg/SpDcoWRZS5I/AAAAAAAAAHU/5yxOgSeyNI0/s400/grinder-connected-agent.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt; &lt;/li&gt;
&lt;li&gt;Create a new file called simple.py and place the following in it:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;simple.py: &lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest

test1 = Test(1, "Request resource")
request1 = test1.wrap(HTTPRequest())

class TestRunner:
    def __call__(self):
        result = request1.GET("http://localhost:80/")
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;In the script tab select simple.py and click the send changed file to worker processes button &lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDeTURKz7I/AAAAAAAAAHc/OOZ-hXFV384/s1600-h/grinder-send-updated-script.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDeTURKz7I/AAAAAAAAAHc/OOZ-hXFV384/s400/grinder-send-updated-script.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;I found that the console could not upload the files to the agent because one of the threads died with a "Java.lang.OutOfMemoryError : Java heap space" error. To get around this in startConsole.sh I added -Xmx1024m to the java command like the below&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;startConsole.sh:&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 95%;"&gt;&lt;code&gt;#!/bin/bash
. ./setGrinderEnv.sh
java -Xmx1024m -cp $CLASSPATH net.grinder.Console
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;So turn the agent and console off. And then start the console and the agent&lt;/li&gt;
&lt;li&gt;Click the start processes button&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDfFgNhQaI/AAAAAAAAAHk/VW7qoBTVV8U/s1600-h/grinder-start-processes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDfFgNhQaI/AAAAAAAAAHk/VW7qoBTVV8U/s400/grinder-start-processes.png" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Yay you are now testing against your web server&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&amp;nbsp;&lt;a href="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDfNeUG_tI/AAAAAAAAAHs/_Ttt6AP8Z8I/s1600-h/grinder-working-away.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDfNeUG_tI/AAAAAAAAAHs/_Ttt6AP8Z8I/s400/grinder-working-away.png" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;When you are done click the stop button and you can have a look at the results&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&amp;nbsp;&lt;a href="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDfUjllcNI/AAAAAAAAAH0/0-LgSKCVheA/s1600-h/grinder-results.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_6VUo2CP8Uzg/SpDfUjllcNI/AAAAAAAAAH0/0-LgSKCVheA/s400/grinder-results.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;So there you go the Missing Grinder Getting Started Guide.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;p&gt;Where to from here? Well you can have multiple agents, talk more than just HTTP (look in the examples directory for JDBC, JMS, SMTP, etc) and record TCP streams via a proxy.&lt;/p&gt;&lt;p&gt;Something I found out later. The reason I was getting the heap of space was that the log directory was one of the directories which was trying to be synced up the agents and this was too large so it crashed console. I will have to figure out how to make it save the logs somewhere else.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-5393542487906506887?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zbbbDMK-w3QDPt9RfE6em0B-ELM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zbbbDMK-w3QDPt9RfE6em0B-ELM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zbbbDMK-w3QDPt9RfE6em0B-ELM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zbbbDMK-w3QDPt9RfE6em0B-ELM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/3jtK2xbefXE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/5393542487906506887/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=5393542487906506887" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5393542487906506887?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5393542487906506887?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/3jtK2xbefXE/missing-grinder-3-getting-started-guide.html" title="The Missing Grinder 3 Getting Started Guide" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_6VUo2CP8Uzg/SpDcoWRZS5I/AAAAAAAAAHU/5yxOgSeyNI0/s72-c/grinder-connected-agent.png" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/08/missing-grinder-3-getting-started-guide.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8CQn88cSp7ImA9WxNTFEw.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-221107287171774031</id><published>2009-08-16T21:23:00.002+12:00</published><updated>2009-08-16T21:27:43.179+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-16T21:27:43.179+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="totb" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Testing on the Bog - Pushing the Boundaries</title><content type="html">&lt;a href="http://files.karit.geek.nz/totb/totb-boundaries.pdf"&gt;PDF version&lt;/a&gt; for placing in your office.&lt;br /&gt;&lt;a href="http://pdfreaders.org/" target="_blank"&gt;&lt;img src="http://pdfreaders.org/graphics/pdfreaders-free.png" alt="pdfreaders.org" border="0" height="33" width="112" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What is &lt;a href="http://blog.karit.geek.nz/2009/07/introducing-testing-on-bog.html"&gt;Testing on the Bog?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Code has “if” statements in it. When testing you need to check that the different conditions of the if statement. Lets take the following code snippet&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 95%"&gt;&lt;code&gt;if input_date &amp;lt;= current_date:&lt;br /&gt;    echo 'Date not in the future'&lt;br /&gt;else:&lt;br /&gt;   echo 'Date in the future'&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The obvious values to test is a date less than or equal to today and one in the future. Test with 2009-08-08 and 2009-08-29 would give you 100% statement and branch coverage when you get your coverage statistics from your unit tests. Well that was easy wasn't it?&lt;br /&gt;&lt;br /&gt;“High Code Coverage” ≠ “Well tested Code”&lt;br /&gt;&lt;br /&gt;Firstly it is “&lt;=” so both the “&lt;” and the “=” need to be tested separately. Also mentioned in the previous &lt;a href="http://blog.karit.geek.nz/2009/07/testing-on-bog-testing-dates-and-times.html"&gt;Testing on the Bog&lt;/a&gt; dates can be complicated beast as well.&lt;br /&gt;&lt;br /&gt;So looking at the clear boundaries to test there are also the not so obvious ones. An example of this could be:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Time is often stored as an integer and only formated in the interface layer, so can you put in a date which so big that it wraps the integer around and it becomes less than the current date? And the flip so negative this get confused as well?&lt;/li&gt;&lt;/ul&gt;The explicit boundaries, which are normally documented as functional requirements, are generally ok to find it is the other ones, which may be non functional requirements or just not documented at all, that aren't obvious which will catch you out some of the time. It is impossible to think of every boundary along the way but just remember you have to look beyond of the obvious ones. Some of these may seem a bit crazy but what users will input into a system can some of the time be very bizzare.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-221107287171774031?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/097Da15oxOo0MxkoNrTc2ajP288/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/097Da15oxOo0MxkoNrTc2ajP288/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/097Da15oxOo0MxkoNrTc2ajP288/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/097Da15oxOo0MxkoNrTc2ajP288/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/NMO2QDdwIq0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/221107287171774031/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=221107287171774031" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/221107287171774031?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/221107287171774031?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/NMO2QDdwIq0/testing-on-bog-pushing-boundaries.html" title="Testing on the Bog - Pushing the Boundaries" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/08/testing-on-bog-pushing-boundaries.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cAQnc9eip7ImA9WxNTFE0.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-5057657432379708638</id><published>2009-08-16T19:49:00.001+12:00</published><updated>2009-08-16T19:50:43.962+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-16T19:50:43.962+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="methodology" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Rigour in Testing</title><content type="html">This week I went to a presentation by &lt;a href="http://www.satisfice.com/"&gt;James Bach&lt;/a&gt; on &lt;a href="http://www.nzcs.org.nz/events/wellington/60-Wellington_Test_Professionals_Network_presents_James_Bach_-_The_Myths_of_Rigor"&gt;the Myths of Rigour&lt;/a&gt; at the Wellington Testing Professional Network Presentation.&lt;br /&gt;&lt;br /&gt;The biggest thing that I took away/had reafrimed was that rigour/process should not be blindly followed. The person executing the process needs to understand why they are doing what they are doing. If something is just being blindly followed aspects of it may be missed as instructions only cover what the instruction writer knows to write down there is a lot of steps that are implied or just done because not doing them would be stupid or not mean things would work right, so the writer doesn't think to write them down. If the background knowledge is there and the understanding of the process is there these implied steps should be piked up naturally and issues will be detected better. Also part of a tester personal attributes should be inquisitive and personally want to have an understanding an a in depth knowledge of how things work and why they work that way. Else you might as well just believe the developer when they say yes it is tested and work fines.&lt;br /&gt;&lt;br /&gt;If you just follow a process how do you know if the output you are producing are correct or are helpful? This can be for testing itself but also for the documentation that surrounds testing. There are templates which say a test plan should look like X and a test case should look like Y. But if you don't know the why behind all the headings is it helpful? Also an organisation's test plan template may be 25 pages sure fine when on a project where have multiple testers and is going to six months plus of testing work, but what about when one person needs to do some testing that is only going to take a couple of days to complete? Is this 25 page template useful? If you don't understand it you will have to just fill it all out and it is going to take longer than the testing is going to take. If you understand this, one would hope that you can only fill out the sections that make sense and quickly explain why you haven't filled in some of the sections seeing they are not applicable to what you need to do.&lt;br /&gt;&lt;br /&gt;One example I have seen where someone who understands something forgets to teach all the basics along the way. I was giving some business users some help with some basic SQL queries. They were saying SQL was hard and they just didn't understand what they were doing. They said that the other person had spent a day with them teaching them SQL they knew about selects, update, inserts, deletes, wheres and joins. So I was a little perplexed that they were having issues with a SELECT * FROM foo WHERE bar = foobar. But after some talking with them found out they didn't actually really know what a database really was and what tables were. After taking a step back and saying a table is like a spreadsheet with columns and rows and a where was like a filter. That a database was a collection of tables and a basic of joins using a person spreadsheet and a address spreadsheet, which could be of type street or postal they were away running.&lt;br /&gt;&lt;br /&gt;Coming back to the rigour aspect I go back to my time at university. Seeing I did honours there I spent a lot involved in academic rigour. One of the big things with that type of rigour was that someone with a similar background should be able to follow your method and reach the same results. They mightn't draw the same conclusions from the results but the results themselves should be the same. So this aspect of rigour is applicable to what we do in the software testing world. Our testing of systems should be repeatable by people other than ourself and repeatability comes into great importance with regression testing and test automation especially when it is being run every night or on every check in. Even when it is automated the person receiving the result needs to be able understand the process even do it manually, so that they can fully understand the results and draw accurate conclusions from it all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-5057657432379708638?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0U8uUJymcjMY8v_Fry1JWWdpSpI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0U8uUJymcjMY8v_Fry1JWWdpSpI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0U8uUJymcjMY8v_Fry1JWWdpSpI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0U8uUJymcjMY8v_Fry1JWWdpSpI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/ytBGRCTZO3Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/5057657432379708638/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=5057657432379708638" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5057657432379708638?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5057657432379708638?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/ytBGRCTZO3Q/rigour-in-testing.html" title="Rigour in Testing" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/08/rigour-in-testing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEMSXg_cSp7ImA9WxJbFUs.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3102745610034728265</id><published>2009-07-26T10:55:00.001+12:00</published><updated>2009-07-26T10:58:08.649+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-26T10:58:08.649+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="mantis" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><title>Experiences with Mantis 1.2 - Part 2 – Setting up User Roles</title><content type="html">I wanted to set up some basic roles so different users could have different permissions. The roles I wanted were:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Viewer&lt;/li&gt;&lt;li&gt;Client&lt;/li&gt;&lt;li&gt;Developer&lt;/li&gt;&lt;li&gt;Tester&lt;/li&gt;&lt;li&gt;Administrator&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In config_inc.php I added:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 95%;"&gt;&lt;code&gt;    $g_access_levels_enum_string = '10:viewer, 20:client, 30:developer, 40:tester, 90:administrator';&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I had to assign strings to these values. Seeing I only speak English I only edited the English strings files. In lang/strings_english.txt I edited it to read:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 95%;"&gt;&lt;code&gt;$s_access_levels_enum_string = '10:viewer,20:client,30:developer,40:tester,90:administrator';&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the roles have been created and you can now create new users who have those roles&lt;br /&gt;&lt;br /&gt;Past Experiences with Mantis 1.2:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.karit.geek.nz/2009/07/experiences-with-mantis-12-part-1.html"&gt;Part 1 - The Install&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3102745610034728265?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_steQlET7cJmSq_IJ7ruOi-SqO0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_steQlET7cJmSq_IJ7ruOi-SqO0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_steQlET7cJmSq_IJ7ruOi-SqO0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_steQlET7cJmSq_IJ7ruOi-SqO0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/ze9ckAZSVMI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3102745610034728265/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3102745610034728265" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3102745610034728265?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3102745610034728265?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/ze9ckAZSVMI/experiences-with-mantis-12-part-2.html" title="Experiences with Mantis 1.2 - Part 2 – Setting up User Roles" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/07/experiences-with-mantis-12-part-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcFRXo8fyp7ImA9WxNTE0w.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-2472480642820476531</id><published>2009-07-25T16:37:00.001+12:00</published><updated>2009-08-15T16:53:34.477+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-15T16:53:34.477+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><title>The Great Firewall of New Zealand</title><content type="html">Firstly need to say that child pornography is bad and should be stopped.&lt;br /&gt;&lt;br /&gt;Secondly sorry for this not being on testing but felt I needed to say something.&lt;br /&gt;&lt;br /&gt;Here in NZ the &lt;a href="http://www.dia.govt.nz/"&gt;DIA&lt;/a&gt; is setting up a system akin to the &lt;a href="http://en.wikipedia.org/wiki/Great_firewall_of_china"&gt;Great Firewall of China&lt;/a&gt;. The DIA is setting a system up to screen out &lt;a href="http://www.theregister.co.uk/2009/07/15/big_nz_blocklist/"&gt;child pornography&lt;/a&gt;. There is nothing wrong with this as it should be stopped.&lt;br /&gt;&lt;br /&gt;What I see wrong:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;This is being implemented under the radar without any legislation governing it bounds and scope. With the infrastructure in place it is very easy just to add a new site in here or there &lt;/li&gt;&lt;li&gt;There is no formal tribunal and process to get sites unblocked&lt;/li&gt;&lt;li&gt;DIA are deciding what is in and out, not NZ's Chief Censor. This being the case there is nothing stopping the of blocking other sites.&lt;/li&gt;&lt;li&gt;It may slow sites down as if there is an IP hit the request goes via DIA'a infrastructure to decide if the URL is ok. I am guessing all Google's IPs will be placed in the check list as Google has their cached version service.&lt;/li&gt;&lt;li&gt;They are not publishing a list of blocked sites, as they clam it will be a list of sites to visit for people who are sick and want to have a look. As a NZ citizen I would like to know what sites my Government is blocking. Look at the Chief Censor they provide a list of everything they have rated along with their ratings and there is a process to get them re-evaluated.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Also I don't think it will work that well as from what I know about the Movie, TV and Music piracy scenes HTTP plays almost no role, as people don't download things from a HTTP server they all use other methods. &lt;a href="http://en.wikipedia.org/wiki/BitTorrent_%28protocol%29"&gt;Bittorrent&lt;/a&gt; for example generally uses HTTP for its trackers but can also use &lt;a href="http://en.wikipedia.org/wiki/Distributed_hash_table"&gt;DHT&lt;/a&gt;. Then there is also &lt;a href="http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29"&gt;Tor&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Freenet"&gt;Freenet&lt;/a&gt;  and &lt;a href="http://en.wikipedia.org/wiki/Onion_Routing"&gt;Onion Routing&lt;/a&gt; which can disguise and hide the traffic until it is somewhere else in the world. Then there is encryption and &lt;a href="http://en.wikipedia.org/wiki/Steganography"&gt;stenography&lt;/a&gt;. There is also old school basic things like &lt;a href="http://en.wikipedia.org/wiki/NNTP"&gt;NNTP&lt;/a&gt; which will store and distribute it al around the world.&lt;br /&gt;&lt;br /&gt;This being the case it I feel this web filtering is giving the naïve some warm fussies that the government is trying to stamp Child Pornography out. When it really won't do all that much and places a internet filter in NZ's internet infrastructure that has not legislation governing it and can also be used by the government to stamp out free speech that it doesn't like. So NZ is now no better than China when it comes to the internet and one step closer to fasicit regime where the government controls everything and stamps out free speech and free choice.&lt;br /&gt;&lt;br /&gt;More Info:&lt;br /&gt;&lt;a href="http://thomasbeagle.net/2009/07/09/nz-internet-filtering-faq/"&gt;General FAQs&lt;/a&gt;&lt;br /&gt;&lt;a href="http://thomasbeagle.net/2009/07/12/nz-internet-filtering-technical-faq/"&gt;Technical FAQs&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-2472480642820476531?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/e3nWQ6-zs-4eaVgh1CWIJc4n3V4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e3nWQ6-zs-4eaVgh1CWIJc4n3V4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/e3nWQ6-zs-4eaVgh1CWIJc4n3V4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e3nWQ6-zs-4eaVgh1CWIJc4n3V4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/I0pFoh-5Wzs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/2472480642820476531/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=2472480642820476531" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/2472480642820476531?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/2472480642820476531?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/I0pFoh-5Wzs/great-firewall-of-new-zealand.html" title="The Great Firewall of New Zealand" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/08/great-firewall-of-new-zealand.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQHQn45eyp7ImA9WxJbFUs.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3153889161573514358</id><published>2009-07-12T17:08:00.003+12:00</published><updated>2009-07-26T11:58:53.023+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-26T11:58:53.023+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="totb" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Testing on the Bog - Testing Dates and Times</title><content type="html">&lt;a href="http://files.karit.geek.nz/totb/totb-datetime.pdf"&gt;PDF version&lt;/a&gt; for placing in your office.&lt;br /&gt;&lt;a href="http://pdfreaders.org/" target="_blank"&gt;&lt;img src="http://pdfreaders.org/graphics/pdfreaders-free.png" alt="pdfreaders.org" border="0" height="33" width="112" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What is &lt;a href="http://blog.karit.geek.nz/2009/07/introducing-testing-on-bog.html"&gt;Testing on the Bog?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The handling of dates and times is one area that commonly has issues when to comes to testing. This Testing on the Bog will give you some ideas when it comes to testing dates and times in your application, this doesn't tell you how to do it, as you need to know what your application should be doing in these situations.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Date Formats&lt;/span&gt; - Most of the world uses Day then Month while the US for example uses Month then Day. Then there is also the ISO8601 format for dates. Does the application format correct, accept input correctly, store and convert correctly? Does it reject input when expected?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Two Digit Years&lt;/span&gt; - This was the whole issue around Y2k problem. When the application is faced with a two digit does it do something sensible with it? Does it store correct by adding 19 or 20 to the front or does it add 00? If you roll your clock forwards is it still adding the century correctly?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Daylight Saving&lt;/span&gt; - Does the application handle the short day and the long day correctly? In the long day can you tell the difference between the first hour and the second hour that is doubled up? For example ':' maybe used for the first hour and ';' is used for the second hour e.g. 02:59 is followed by 02;00.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Daylight Saving Dates&lt;/span&gt; - Does your application use the correct library for figuring out the start and end dates? This is particularly important if the local rules have been recently changed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Time Zones&lt;/span&gt; - Are Time Zones stored? Does convert correctly? When no Time Zone is given does it correctly figure out what time zone it should be? Transitions in and out of Day Light Savings Time Zones. If you manually ask the system (e.g. via SQL) to convert the time zone will it? If you manually force a date to be inserted with a Time Zone which is different the the default does the application do the correct thing with it?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Leap Years&lt;/span&gt; - Firstly remember the rule is "Every year divisible by 4 expect those divisible by 100 unless it is also divisible by 400" 1900 was not a leap year yet 2000 was. Do things work as expected in this day? Date range calculations? Is 365 hard coded anywhere for calculations?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Leap Seconds&lt;/span&gt; - Leap seconds happen every so often and result in an extra second being added to the day (and in theory a second may also be removed). So the valid range of seconds in a minute is 59 - 61. A leap second minute goes x:59. x:60, y:00. Can the application display a minute with 61 seconds? What happens if you insert a time with 60 as the value of seconds? What happens with a transaction submitted at 61? Does the application assume there are always 86400 seconds in a day?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Intervals&lt;/span&gt; - With Leap Years, Leap Seconds and Daylight Savings do intervals take these into account correctly?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Year 2038 Problem&lt;/span&gt; - At 2038-01-19T03:14:07Z the 32bit counter which has been counting the number of seconds since 1970-01-01T00:00:00Z will roll over to a negative integer which may produce date/times in the past.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3153889161573514358?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/c0SqLBzbyNVNPiInm0cMi7SuUZk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c0SqLBzbyNVNPiInm0cMi7SuUZk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/c0SqLBzbyNVNPiInm0cMi7SuUZk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c0SqLBzbyNVNPiInm0cMi7SuUZk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/32Sy-R69grg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3153889161573514358/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3153889161573514358" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3153889161573514358?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3153889161573514358?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/32Sy-R69grg/testing-on-bog-testing-dates-and-times.html" title="Testing on the Bog - Testing Dates and Times" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/07/testing-on-bog-testing-dates-and-times.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AGRX86eSp7ImA9WxJUE0o.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-5015721910169655001</id><published>2009-07-12T17:02:00.004+12:00</published><updated>2009-07-12T17:15:24.111+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-12T17:15:24.111+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="totb" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Introducing Testing on the Bog</title><content type="html">I would like to introduce everyone to &lt;a href="http://blog.karit.geek.nz/search/label/totb"&gt;Testing on the Bog&lt;/a&gt; (TotB). TotB pays homage to &lt;a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html"&gt;Google's Testing on the Toilet&lt;/a&gt;. Seeing &lt;a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html"&gt;TotT&lt;/a&gt; isn't producing a new one each week and I am running out of past episodes to place the toilet doors, I thought I would have a go a writing some. My background is different so will of course approach Testing from a different angle. Hopefully you do find these interesting and useful. Do provide me with feedback on these and if you are using them at your company. Also I would like to say that if anyone would like to contribute one or maybe just a topic idea please do feel free to get in touch. I can't promise these will be produced weekly but I will try and publish as often as I can.&lt;br /&gt;&lt;br /&gt;I will be posting the &lt;a href="http://blog.karit.geek.nz/2009/07/testing-on-bog-testing-dates-and-times.html"&gt;first installation&lt;/a&gt; very soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-5015721910169655001?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/N0HieYOhpkif40NZ8J-Gt8nRbIg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N0HieYOhpkif40NZ8J-Gt8nRbIg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/N0HieYOhpkif40NZ8J-Gt8nRbIg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N0HieYOhpkif40NZ8J-Gt8nRbIg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/VaMON0FtHnI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/5015721910169655001/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=5015721910169655001" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5015721910169655001?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5015721910169655001?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/VaMON0FtHnI/introducing-testing-on-bog.html" title="Introducing Testing on the Bog" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/07/introducing-testing-on-bog.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMNSHg7eyp7ImA9WxJUEko.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-5109096991929100775</id><published>2009-07-11T14:14:00.001+12:00</published><updated>2009-07-11T14:14:59.603+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-11T14:14:59.603+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="mantis" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><title>Experiences with Mantis 1.2 - Part 1 -  The Install</title><content type="html">I have bee looking at different defect tracking systems and I am liking the look of &lt;a href="http://www.mantisbt.org/"&gt;Mantis Bugtracking System&lt;/a&gt;. I have experimented with the 1.1.x version and liked it. I have only used on virtual machine at home, so I have never used it in anger so to speak. Seeing 1.2 of Mantis is now at a Release Candidate stage I thought I would have another look at it. What I plan to is to write a series of blog posts as I get it set up in a demo form.&lt;br /&gt;&lt;br /&gt;So Part 1 the install. Put &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;  on a a VM and made sure that &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt;, &lt;a href="http://www.mysql.com/"&gt;mySQL&lt;/a&gt; and &lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt; were installed. Then just downloaded Mantis and placed it in /var/www/mantis and fired up a web browser to point at it. Comes up with a install page just type in the database connection details and is installed in a matter of seconds. Totally painless and simple.&lt;br /&gt;&lt;br /&gt;What I plan to do:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Set up some different user roles&lt;/li&gt;&lt;li&gt;Set up some custom statuses&lt;/li&gt;&lt;li&gt;Set up a customer work flow&lt;/li&gt;&lt;li&gt;Set up multiple clients so internal people (I work at an IT vendor company) can see more than clients and clients can only see things related to them and not other clients.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-5109096991929100775?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aFjldHdZBj1kQIO9gZXtsunkcmg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aFjldHdZBj1kQIO9gZXtsunkcmg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aFjldHdZBj1kQIO9gZXtsunkcmg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aFjldHdZBj1kQIO9gZXtsunkcmg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/v2RcbhVnJf0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/5109096991929100775/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=5109096991929100775" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5109096991929100775?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/5109096991929100775?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/v2RcbhVnJf0/experiences-with-mantis-12-part-1.html" title="Experiences with Mantis 1.2 - Part 1 -  The Install" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/07/experiences-with-mantis-12-part-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYASHs5eyp7ImA9WxJVGEo.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-7872397120167269034</id><published>2009-07-05T16:36:00.001+12:00</published><updated>2009-07-06T23:02:29.523+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-06T23:02:29.523+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="methodology" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Full Risk Based SDLC</title><content type="html">In the testing sphere there is a lot about Risk Based Testing and methods about how to go about it. I have had a quick look on Google (it may be that I am just blind) but there doesn't seem to be much in the way of a similar thing for development.&lt;br /&gt;&lt;br /&gt;The development side does have different things like pair programming, code reviews, code coverage, etc which are expensive to run all the time but could using the same data coming out from the Risk Based Testing data gathering sessions to gear their development. They may also place a a higher weighting/bias to the ones with a higher development risk due to complexity for instance. An example could be:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Low Risk&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Unit Tests with 95% branch and statement coverage&lt;/li&gt;&lt;li&gt;Static analysis using something like &lt;a href="http://sonar.codehaus.org/features/"&gt;Sonar&lt;/a&gt; for complexity, copy and paste and coding standards&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Medium Risk&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Everything in Low Risk plus&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A code review by a peer&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;High Risk&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Everything in Low Risk plus&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pair Programming&lt;/li&gt;&lt;li&gt;A code review by the tech lead&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;That way with Risk Based Development (RBD) and Risk Based Testing (RBT) the whole SDLC can be Risk Based. With Development and Test both using the Risk Data gathered the time spent gathering the data would be easier to justify as it will be used twice and should develop a better end product as the riskier areas of the product are better developed and tested.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-7872397120167269034?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VQxlYsQGghJqwWfiDt3gdVDSNP0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VQxlYsQGghJqwWfiDt3gdVDSNP0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VQxlYsQGghJqwWfiDt3gdVDSNP0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VQxlYsQGghJqwWfiDt3gdVDSNP0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/aTquFYvarjs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/7872397120167269034/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=7872397120167269034" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/7872397120167269034?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/7872397120167269034?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/aTquFYvarjs/full-risk-based-sdlc.html" title="Full Risk Based SDLC" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/07/full-risk-based-sdlc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QBSXg9eyp7ImA9WxJXGU4.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-456467533532435933</id><published>2009-06-13T22:20:00.002+12:00</published><updated>2009-06-14T10:15:58.663+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-14T10:15:58.663+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="methodology" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Explaining your testing and what you do</title><content type="html">&lt;a href="http://www.satisfice.com/"&gt;James Bach&lt;/a&gt; has a blog post &lt;a href="http://www.satisfice.com/blog/archives/310"&gt;Putting Subtitles to Testing&lt;/a&gt; which has an &lt;a href="http://www.youtube.com/watch?v=Vy0I2SB5OLo"&gt;accompanying video&lt;/a&gt;. The video is of James and Jon Bach testing an &lt;a href="http://www.amazon.com/Staples-12438-us-cc-Talking-BUTTON/dp/B000JMXXU8"&gt;Easy Button&lt;/a&gt;  and in the video they sub titles along the way explaining the type of testing they were doing.&lt;br /&gt;&lt;br /&gt;The point they make at the end of the video is about reporting what you are doing as a tester and that you need to practise putting what you do into words. This can come particularity important if you are a tester like and deal mostly in testing things which don't have a GUI. As if you have to explain to someone what testing you have done with a GUI they will often find it easier to understand what you have done as they visualise or see the GUI. If you start talking about DBs, SOAP, Web Services, CSVs, etc they have more difficulty in understanding what you have done with your time. This also becomes more apparent when you are not working 100% from test scripts as you can't just say I execute these scripts. When you are doing more exploratory testing explaining what you have done is more apparent. &lt;a href="http://blog.karit.geek.nz/2009/05/how-i-track-my-session-notes.html"&gt;Session notes&lt;/a&gt; which we write during our testing make sense to us and cover everything so if there are defects we can  go back and remember the full chain of events leading up to noticing the issue. While watching the video and the sub titles staying a high level (Requirements Analysis, Stress Testing, etc) can still be very informative.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-456467533532435933?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/avtnBVOahhfYm9Ccg_A2DOXKStY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/avtnBVOahhfYm9Ccg_A2DOXKStY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/avtnBVOahhfYm9Ccg_A2DOXKStY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/avtnBVOahhfYm9Ccg_A2DOXKStY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/asgWd3fervE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/456467533532435933/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=456467533532435933" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/456467533532435933?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/456467533532435933?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/asgWd3fervE/explaining-your-testing-and-what-you-do.html" title="Explaining your testing and what you do" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/06/explaining-your-testing-and-what-you-do.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkABQXcyfip7ImA9WxJXGEg.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3477972907987780735</id><published>2009-06-13T14:02:00.001+12:00</published><updated>2009-06-13T14:05:50.996+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-13T14:05:50.996+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="links" /><title>Card Walls - Mingle</title><content type="html">Well I have mentioned the idea of digital card walls in two previous posts (&lt;a href="http://blog.karit.geek.nz/2009/05/can-defect-tracking-systems-be-more.html"&gt;Can defect tracking systems be more helpful?&lt;/a&gt; and &lt;a href="http://blog.karit.geek.nz/2009/04/visual-representation-of-defect-queues.html"&gt;Visual Representation of Defect Queues&lt;/a&gt;) and well apparently I am not the first to think about it. &lt;a href="http://studios.thoughtworks.com/mingle-agile-project-management"&gt;Thought Works has a product called Mingle&lt;/a&gt; which does the Agile Card Wall along with a Defect Tracking one. Unfortunately Mingle isn't Free or Open Source so doubt I will spend any more time looking at it unless I get a budget to spend on tools, which is something I don't see any time soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3477972907987780735?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QFCJJc49mY7X8UPErPpb4lMaonc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QFCJJc49mY7X8UPErPpb4lMaonc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QFCJJc49mY7X8UPErPpb4lMaonc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QFCJJc49mY7X8UPErPpb4lMaonc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/qRq4iBsbgQM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3477972907987780735/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3477972907987780735" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3477972907987780735?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3477972907987780735?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/qRq4iBsbgQM/card-walls-mingle.html" title="Card Walls - Mingle" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/06/card-walls-mingle.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkINRXoycSp7ImA9WxJUEko.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-739239443133739043</id><published>2009-06-13T11:57:00.005+12:00</published><updated>2009-07-11T14:16:34.499+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-11T14:16:34.499+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="automation" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Spawner 1.6</title><content type="html">I have talked about &lt;a href="http://spawner.sourceforge.net/"&gt;Spawner&lt;/a&gt; before &lt;a href="http://blog.karit.geek.nz/2009/01/database-population-tool.html"&gt;here&lt;/a&gt;, &lt;a href="http://blog.karit.geek.nz/2009/05/populating-databases-with-random-data.html"&gt;here&lt;/a&gt; and &lt;a href="http://blog.karit.geek.nz/2009/05/spawner-revisited.html"&gt;here&lt;/a&gt;.  Well version 1.6 of this useful database population tool is out, what it adds is a masked string which lets you make strings up how you like. For instance lets you make bank account numbers, IR numbers or phone numbers (outside of US ones) which is a handy feature to have.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-739239443133739043?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qf2aYOZHlZzGGpZGWPyRI4di-y0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qf2aYOZHlZzGGpZGWPyRI4di-y0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qf2aYOZHlZzGGpZGWPyRI4di-y0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qf2aYOZHlZzGGpZGWPyRI4di-y0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/jofmHNE34rI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/739239443133739043/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=739239443133739043" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/739239443133739043?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/739239443133739043?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/jofmHNE34rI/spawner-16.html" title="Spawner 1.6" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/06/spawner-16.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cMQ389eyp7ImA9WxJQGE4.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-1019453025197832028</id><published>2009-06-01T17:35:00.006+12:00</published><updated>2009-06-01T18:51:22.163+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-01T18:51:22.163+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="methodology" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Risk Based Testing</title><content type="html">Last week I went to Matt Mansell's &lt;a href="http://www.nzcs.org.nz/events/wellington/39-TPN_Wellington_What_are_the_Risks_of_Risk_Based_Testing"&gt;“What are the Risks of Risk Based Testing?”&lt;/a&gt; presentation at the Wellington TPN. This left me doing some thinking about it. I first came across Risk Based Testing at &lt;a href="http://www.softed.com/stanz/"&gt;STANZ 2008&lt;/a&gt; and from then I like the idea of it, but I am personally yet to put it into practise or join a project which is using it.&lt;br /&gt;&lt;br /&gt;What is good about Risk Based Testing is we all know testing everything is impossible given the budgets and time frames of most projects. Risk based testing gives you a framework which you can use to prioritise your testing. This needs to balanced with teaching the customer that descoping via risk base testing means that things may NOT be tested, but the customer has prioritised them lower therefore if they break in production it is less of an issue. This will also help get the testers back in the correct position in that they provide information about making the go live decision rather than making the go live decision themselves. Which means you can be more pragmatic and no longer need to be the king/queen of quality as your butt isn't on the line as you didn't make the decision to go live or not. Which helps the the common situation where congratulate dev if it goes well and blame test if it doesn't go so well.&lt;br /&gt;&lt;br /&gt;From what I have heard about risk base testing it really needs to be started early (&lt;a href="http://blog.karit.geek.nz/2009/05/testing-of-requirements-is-always-good.html"&gt;see my previous blog post&lt;/a&gt;). As at that time the client reps doing the specifications are still around and most likely still having enough time to spend time helping to do come up with the risks and ranking of them. There is no magic number for the number of risks that are optimal though may at least need to place them into some type of tree structure, so can give different levels to different audiences. Something like &lt;a href="http://freemind.sourceforge.net/"&gt;FreeMind&lt;/a&gt; may come in handy about here for recording the risks which get brainstormed during the meeting of all the stakeholders. The risks for Risk Base testing are a subset of the whole project's risks and focus on the quality related ones which are to be mitigated through testing of the deliverable. All the requirements should have one or more risks associated with them.&lt;br /&gt;&lt;br /&gt;A requirement's first risk is does it work or not work? Then all the test cases focus on testing risks rather than requirements. This does cause a bit of an issue as most test management systems link requirements with test cases rather than requirements having risks and risks having test cases.&lt;br /&gt;&lt;br /&gt;Before this presentation with risk base testing I had the idea of started at the highest risk and then just work your way down the list. But this isn't the only way, as Matt presented the idea of making sure you touch all the risks but not necessarily use all the test cases. For example lets say that you have three test iterations and there are 100 test cases for each of your high, medium and low risks, so 300 test cases in total.&lt;br /&gt;&lt;table&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Iteration&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;High (# of Test Cases)&lt;/td&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;35&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Medium (# of Test Cases)&lt;/td&gt;&lt;td&gt;35&lt;/td&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Low (# of Test Cases)&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;70&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;This assumes that 15 test cases will test all of you risks in one particular risk level. What this gives you is coverage that every iteration you have touched all of your risks so should have found any show stoppers and also if need to stop before all three iterations you can demonstrate in the nice table what you have and have not done which can help the customer make their mind up on if they want to go live now or go live later. This does mean that you are leveling running some of your test cases for the high risks to the very end, so they may get dropped. There is no magic bullet proof vest, there are always drawbacks to one method or another of how to test the risks, but there are different ways to explain it to the customer to better understand your approach for doing it.&lt;br /&gt;&lt;br /&gt;Risk base testing may also be used for how to divide up the testing work. For instance it may be decided the testers do the high risks while the client testers work on the low risks. If this happens the test team needs to own the process and also have control over the client testers. This is so if for instance the client testers get called away to do their day job and thus things are not tested properly it generally still gets blamed on the test team for not doing their job properly. If the test team can own the whole testing process and if that happens raise a flag and either do it themselves or get some type of time extension, so that the product does not ship at a standard lower than expected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-1019453025197832028?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XNlWp-P7GQnNnaUMARG1fuVU1rc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XNlWp-P7GQnNnaUMARG1fuVU1rc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XNlWp-P7GQnNnaUMARG1fuVU1rc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XNlWp-P7GQnNnaUMARG1fuVU1rc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/yAOPM-WWmyg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/1019453025197832028/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=1019453025197832028" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/1019453025197832028?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/1019453025197832028?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/yAOPM-WWmyg/risk-based-testing.html" title="Risk Based Testing" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/06/risk-based-testing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YEQn88cSp7ImA9WxJQGE4.&quot;"><id>tag:blogger.com,1999:blog-6540851071252152964.post-3005886883471211779</id><published>2009-05-24T17:52:00.007+12:00</published><updated>2009-06-01T18:51:43.179+12:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-01T18:51:43.179+12:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="methodology" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Testing of Requirements... Is always a good thing™</title><content type="html">I was having a read of &lt;a href="http://www.softed.com/Resources/Docs/Impact-of-Requirements-issues-on-Testing.pdf"&gt;The Impact of Requirements issues on Testing&lt;/a&gt; which is on the &lt;a href="http://www.softed.com/Resources/"&gt;SoftEd Resources&lt;/a&gt; page. It says that 40% of software errors come from requirements errors. It would tend to agree with this as on the whole as it there is possibility for ambiguity and ambiguity leads to the business thinking it should do X, the developer codes Y and the tester tests it assuming it will do Z. Which leads to the standard inclusion of:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_6VUo2CP8Uzg/ShjhKra8NZI/AAAAAAAAAFU/2w3vWACXVIs/s1600-h/PM_Build_Swing.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_6VUo2CP8Uzg/ShjhKra8NZI/AAAAAAAAAFU/2w3vWACXVIs/s400/PM_Build_Swing.gif" alt="" id="BLOGGER_PHOTO_ID_5339264931818386834" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm sure everyone has seen this picture before, it is the standard diagram indicating misunderstandings in requirements.&lt;br /&gt;&lt;br /&gt;What I see the problem is that testers only get involved when it is time to the output from development. This is always the case and I doubt it will really change until the client can understand spending time and money on testers to be engaged from day zero of the project and test every output along the way before going onto the next stage in the project life cycle. For example the project requirements are normally only signed off by the client. This isn't always the best as the the client doesn't always understand the technology fully and they described it to the BAs so they are can fill in the gaps and ambiguity without thinking about it. Having testers involved at this stage would bring in a viewpoint from people who have been involved in requirements gathering and also bring the testing viewpoint to things and looking for holes and defects.&lt;br /&gt;&lt;br /&gt;Why I don't think this will fly without a lot of re-education?:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Testing will slow it down&lt;/li&gt;&lt;li&gt;This will require people so therefore require more money to be spent&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;But I personally think these are false realities:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It may lengthen the time for requirements gathering, but the overall project will be less. As picking up these errors before development will mean that some pieces will not have to be redesigned. redeveloped and retested. This is the whole the sooner in the cycle you detect a defect the cheaper it is to fix. Though usually it is only looked at with Unit Test vs. System Test vs. User Acceptance Test vs. Production.&lt;/li&gt;&lt;li&gt;The second point of needed more people and therefore money is linked into what I just said above. You will just be spreading the testing effort out over the project and will hopefully make the time spent testing the requirements back by spending less time retesting.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;What is needed? Re-education in that life cycles should have test team involvement the whole way through the project not just post development. This will need to be taught in project management courses and made part of the methodologies used. Some of the Agiles are better at this as the test team is at the kick off meetings etc. and everyone is co-located so ambiguity can be sorted out quickly without needing to schedule meetings etc. Though seeing Agile doesn't scale to larger projects it would be good if some how some of these aspects could be worked into methodologies for the larger projects to use.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6540851071252152964-3005886883471211779?l=blog.karit.geek.nz' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KoMGm7d9cQuVlHT98uMM-XulsYk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KoMGm7d9cQuVlHT98uMM-XulsYk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KoMGm7d9cQuVlHT98uMM-XulsYk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KoMGm7d9cQuVlHT98uMM-XulsYk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/geek/UdDW/~4/BdIcJcviJII" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.karit.geek.nz/feeds/3005886883471211779/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6540851071252152964&amp;postID=3005886883471211779" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3005886883471211779?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6540851071252152964/posts/default/3005886883471211779?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/geek/UdDW/~3/BdIcJcviJII/testing-of-requirements-is-always-good.html" title="Testing of Requirements... Is always a good thing™" /><author><name>Karit</name><uri>http://www.blogger.com/profile/15634464642072373130</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_6VUo2CP8Uzg/SZeMzwQeMRI/AAAAAAAAACU/9R0gXxm8V2g/S220/karit_southpark.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_6VUo2CP8Uzg/ShjhKra8NZI/AAAAAAAAAFU/2w3vWACXVIs/s72-c/PM_Build_Swing.gif" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.karit.geek.nz/2009/05/testing-of-requirements-is-always-good.html</feedburner:origLink></entry></feed>

