<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>VirtualChaos - Nadeem's blog &#187; Agile</title>
	<atom:link href="http://www.virtualchaos.co.uk/blog/tag/agile/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.virtualchaos.co.uk/blog</link>
	<description>I thought what I'd do was, I'd pretend I was one of those deaf mutes ... or should I?</description>
	<lastBuildDate>Thu, 29 Jul 2010 12:11:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Test-Driven JavaScript Development with JsUnit</title>
		<link>http://www.virtualchaos.co.uk/blog/2008/09/20/test-driven-javascript-development-with-jsunit/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2008/09/20/test-driven-javascript-development-with-jsunit/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 16:01:20 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Talis]]></category>
		<category><![CDATA[test-driven-development]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/?p=469</guid>
		<description><![CDATA[The last time I used JsUnit was when I first joined Talis. At the time my colleague Ian Davis asked me to write a JavaScript client library for one of our platform API&#8217;s to make it easy for developers to perform bibliographic searches. It wasn&#8217;t a particularly difficult task and I did it relatively easily. [...]]]></description>
			<content:encoded><![CDATA[<p>The last time I used <a href="http://www.jsunit.net/">JsUnit</a> was when I first joined Talis. At the time my colleague <a href="http://iandavis.com/">Ian Davis</a> asked me to write a JavaScript client library for one of our platform API&#8217;s to make it easy for developers to perform bibliographic searches. It wasn&#8217;t a particularly difficult task and I did it relatively easily. It was around the same time that <a href="http://www.dynamicorange.com/blog/">Rob</a> was extolling the virtues of <a href="http://en.wikipedia.org/wiki/Test-driven_development">Test Driven Development</a> to me, and to try to prove his point we agreed to do an experiment:  he asked me to set aside the library I had written and to see if I could develop the library again using test driven development. It meant I had to figure out how to unit test JavaScript, and thats when I found JsUnit. I did the exercise again and even I was impressed with the results. By having to think about the tests first, and design the interface to the library as I wrote each test it evolved very differently to my original solution. Consequently it was also far superior.</p>
<p>Anyway fast forward two and half years and I find myself in a similar situation. We have only just begun to start writing bits of JavaScript code based around prototype.js to help us create richer user experiences in our products if we detect that JavaScript is enabled in the browser. This now means I want to ensure that we are using the same rigour when writing these bits of code as we do in all other parts of the application &#8211; just because its JavaScript and executed inside the browser this doesn&#8217;t mean it shouldn&#8217;t be tested.</p>
<p>I&#8217;ve just spent the morning getting JsUnit installed and figuring out how to get it to run as part of a continuous integration process, as well as thinking about how to write tests for some slightly different scenarios. Here&#8217;s what I&#8217;ve discovered today:</p>
<p><strong>Installing JsUnit</strong></p>
<p>Couldn&#8217;t be easier &#8230; go to <a href="http://www.jsunit.net/">www.jsunit.net</a> and download the latest distribution, and extract into a folder on your system somewhere, lets say<br />
<code>/jsunit</code> for now. The distribution contains both the standard test runner as well as jsunit server which you will need it if you want to hook it into an ant build.</p>
<p><strong>Writing Tests</strong></p>
<p>In JsUnit we place our tests in a HTML Test Page which is the equivalent of a Test Class, this test page must have a script reference to the <strong>jsUnitCore.js</strong> so the test runner knows its a test. So lets work through a simple example. Let&#8217;s say we want to write a function that returns the result of adding two parameters together. The Test Page for this might look like this:</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;html<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;head<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;title<span class="re2">&gt;</span></span></span>Test Page for add(value1, value2)<span class="sc3"><span class="re1">&lt;/title<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;javascript&quot;</span> <span class="re0">src</span>=<span class="st0">&quot;/jsunit/app/jsUnitCore.js&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;javascript&quot;</span> <span class="re0">src</span>=<span class="st0">&quot;scripts/addValues.js&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;/head<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;body<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;javascript&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; function testAddWithTwoValidArguments() {</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals(&quot;2 add 3 is 5&quot;, 5, add(2,3) );</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;/body<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;/html<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>For now lets save this file to <code>/my-jsunit-tests/addTest.html</code></p>
<p>To run the test you need to point your browser at the following local url:</p>
<p><code>file:///jsunit/testRunner.html?testPage=/my-jsunit-tests/addTest.html</code></p>
<p>The test will not run since we haven&#8217;t defined the add function. Let&#8217;s do that (very crudely):</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> add<span class="br0">&#40;</span>param1, param2<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> param1 + param2;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Now if you go to that URL it will run the test and report that it passed. Excellent, we&#8217;ve written a simple test in JavaScript. Now lets extend this a little, lets say I want to write something more complicated like a piece of JavaScript that uses <a href="http://www.prototypejs.org/">Prototype.js</a> to update the DOM of a page. Is this possible? Can I do that test first?  It turns out that you can &#8230; </p>
<p>Lets say we have a div on the page called &#8216;tableOfContents&#8217; and we want to use Prototype.js to dynamically inject a link onto the page that says [show] and lets say we want to write a function that will toggle this link to say [hide] when the user clicks on it, this link will also set the visible state of the table of contents itself which for now we&#8217;ll say is just an ordered list (OL). Our test page is going to be slightly more complex &#8230;</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;html<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;head<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;title<span class="re2">&gt;</span></span></span>Test Page for multiplyAndAddFive(value1, value2)<span class="sc3"><span class="re1">&lt;/title<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;javascript&quot;</span> <span class="re0">src</span>=<span class="st0">&quot;/jsunit/app/jsUnitCore.js&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;javascript&quot;</span> <span class="re0">src</span>=<span class="st0">&quot;scripts/prototype/prototype-1.6.0.2.js&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;javascript&quot;</span> <span class="re0">src</span>=<span class="st0">&quot;scripts/tableOfContents.js&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;/head<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;body<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;div</span> <span class="re0">id</span>=<span class="st0">&quot;tableOfContents&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;h2</span> <span class="re0">id</span>=<span class="st0">&quot;tableOfContentsHeader&quot;</span><span class="re2">&gt;</span></span>Table of contents<span class="sc3"><span class="re1">&lt;/h2<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ol</span> <span class="re0">id</span>=<span class="st0">&quot;list-toc&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/ol<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/div<span class="re2">&gt;</span></span></span> &nbsp; &nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;javascript&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; function testTOC()</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; {</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; var title = $(&#8217;lnkToggleTOC&#8217;).title;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals(&quot;should be Show the table of contents&quot;, &quot;Show the table of contents&quot;, title); </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; toggleTableOfContents();</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; var title = $(&#8217;lnkToggleTOC&#8217;).title;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals(&quot;should be Hide the table of contents&quot;, &quot;Hide the table of contents&quot;, title);</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;/body<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/html<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>There are some differences in this test. Firstly the html contains some markup, that I&#8217;m using as the containers for my table of contents. The table of contents has a header and the contents in the form of an empty ordered list. Now I know that I want the javascript to execute when the page is loaded, so I&#8217;ve written this test to assume that the script will run and will inject and element called &#8216;linkToggleToc&#8217; which is the show/hide link next to the heading. Therefore the first line of the test uses prototype.js element selector notation to set a local variable called title to the value of the title of the element that has the id &#8216;linkToggleToc&#8217;. If the script failes to execute then this element will not be present and the subsequent assert will fail. If the assert succeeds, then we call the toggleTableOfContents function and then repeat the same evaluation only now we are checking to see if the link has been changed.</p>
<p>The code for tableOfContents.js is as follows:</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">Event.<span class="me1">observe</span><span class="br0">&#40;</span>window, <span class="st0">&#8216;load&#8217;</span>, injectTOCLinks<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">var</span> titleShowTOC = <span class="st0">&#8216;Show the table of contents&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">var</span> titleHideTOC = <span class="st0">&#8216;Hide the table of contents&#8217;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> injectTOCLinks<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#8216;list-toc&#8217;</span><span class="br0">&#41;</span>.<span class="me1">hide</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#8216;tableOfContentsHeader&#8217;</span><span class="br0">&#41;</span>.<span class="me1">style</span>.<span class="me1">display</span> = <span class="st0">&#8216;inline&#8217;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> elShowHideLink = <span class="kw2">new</span> Element<span class="br0">&#40;</span><span class="st0">&#8216;a&#8217;</span>, <span class="br0">&#123;</span> <span class="st0">&#8216;id&#8217;</span>: <span class="st0">&#8216;lnkToggleTOC&#8217;</span>, <span class="st0">&#8216;href&#8217;</span>: <span class="st0">&#8216;javascript:toggleTableOfContents()&#8217;</span>, <span class="st0">&#8216;title&#8217;</span>: titleShowTOC, <span class="st0">&#8216;class&#8217;</span>: <span class="st0">&#8216;ctr&#8217;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>.<span class="me1">update</span><span class="br0">&#40;</span><span class="st0">&quot;[show]&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#8216;tableOfContentsHeader&#8217;</span><span class="br0">&#41;</span>.<span class="me1">insert</span><span class="br0">&#40;</span><span class="br0">&#123;</span><span class="st0">&#8216;after&#8217;</span>:elShowHideLink<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> toggleTableOfContents<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> toc = $<span class="br0">&#40;</span><span class="st0">&#8216;list-toc&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>toc.<span class="me1">visible</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; toc.<span class="me1">hide</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#8216;lnkToggleTOC&#8217;</span><span class="br0">&#41;</span>.<span class="me1">update</span><span class="br0">&#40;</span><span class="st0">&#8216;[show]&#8216;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#8216;lnkToggleTOC&#8217;</span><span class="br0">&#41;</span>.<span class="me1">title</span> = titleShowTOC;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; toc.<span class="me1">show</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#8216;lnkToggleTOC&#8217;</span><span class="br0">&#41;</span>.<span class="me1">update</span><span class="br0">&#40;</span><span class="st0">&#8216;[hide]&#8216;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#8216;lnkToggleTOC&#8217;</span><span class="br0">&#41;</span>.<span class="me1">title</span> = titleHideTOC;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Now if we run this test in the same way we executed the previous test it will pass. I accept that this example is a bit contrived since I know it already works and I&#8217;ve skimmed over some of the details around it. The point I&#8217;m trying to make though is that you can write unit tests for pretty much any kind of JavaScript you need to write, even tests for scripts that do dom manipulation, or make AjaxRequests etc.</p>
<p><strong>Setting up the JsUnit server so you can run it in a build</strong></p>
<p>JsUnit ships with its own ant build file that requires some additional configuration before you can run the server. The top of the build file contains a number of properties that need to be set, here&#8217;s what you set them to ( using the paths that I&#8217;ve been using in the above example)</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;project</span> <span class="re0">name</span>=<span class="st0">&quot;JsUnit&quot;</span> <span class="re0">default</span>=<span class="st0">&quot;create_distribution&quot;</span> <span class="re0">basedir</span>=<span class="st0">&quot;.&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;browserFileNames&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;/usr/bin/firefox-2&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">id</span>=<span class="st0">&quot;closeBrowsersAfterTestRuns&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;closeBrowsersAfterTestRuns&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;false&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">id</span>=<span class="st0">&quot;ignoreUnresponsiveRemoteMachines&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;ignoreUnresponsiveRemoteMachines&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;true&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">id</span>=<span class="st0">&quot;logsDirectory&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;logsDirectory&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;/my-jsunit-tests/results/&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">id</span>=<span class="st0">&quot;port&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;port&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;9001&quot;</span> &nbsp;<span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">id</span>=<span class="st0">&quot;remoteMachineURLs&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;remoteMachineURLs&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">id</span>=<span class="st0">&quot;timeoutSeconds&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;timeoutSeconds&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;60&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;property</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">id</span>=<span class="st0">&quot;url&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;url&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">value</span>=<span class="st0">&quot;file:///jsunit/testRunner.html?testPage=/my-jsunit-tests/tocTest.html&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/project<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>
You can then type the following command in the root of the jsunit distribution to launch the jsunit server, executes the test, and outputs a test results log file, formatted just like JUnit, and reports that the build was either successful or not if the test fails. </p>
<p><pre>
  ant standalone_test
</pre>
</p>
<p>Remember that in this example I&#8217;ve used a simple Test Page, however JsUnit, like any XUnit framework allows you to specify Test Suites, which is how you would run multiple Test Pages. Also the parameters in the build file woudn&#8217;t be hardcoded in you continuous integration process but would rather be passed in, and you would want to call it from your projects main ant build file &#8230; all of which is pretty simple to configure, once you know what is you want to do and what&#8217;s possible.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/javascript" rel="tag">javascript</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>, <a class="tag_technorati" href="http://technorati.com/tag/test-driven-development" rel="tag">test-driven-development</a>, <a class="tag_technorati" href="http://technorati.com/tag/unit-testing" rel="tag">unit-testing</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2008/09/20/test-driven-javascript-development-with-jsunit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Human Aspects of Agile Software Engineering</title>
		<link>http://www.virtualchaos.co.uk/blog/2008/03/22/human-aspects-of-agile-software-engineering/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2008/03/22/human-aspects-of-agile-software-engineering/#comments</comments>
		<pubDate>Sat, 22 Mar 2008 12:51:53 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[techtalk]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2008/03/22/human-aspects-of-agile-software-engineering/</guid>
		<description><![CDATA[



This is a very interesting way of looking at Agile. The talk is a based on an assumption &#8211; that the people involved in software development processes deserve more attention. I agree with the many of the points made in the talk, particularly around the intangible nature of the software we build. Which is one [...]]]></description>
			<content:encoded><![CDATA[<p align="center">
<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/mAX2G-RogAk&#038;hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/mAX2G-RogAk&#038;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>
</p>
<p>
This is a very interesting way of looking at Agile. The talk is a based on an assumption &#8211; that the people involved in software development processes deserve more attention. I agree with the many of the points made in the talk, particularly around the intangible nature of the software we build. Which is one of the reasons we are still, as an industry, trying to discover the best practises, and a true sense of engineering discipline.
</p>
<p>Its well worth watching this talk, especially to get a different perspective on Agile, focusing on the social and cognitive effects. She used the Prisoners Dilemma to illustrate some of these points and to be honest I had never thought of Software Engineering in those terms, yet as a metaphor it fits so very well, </p>
<blockquote><p>
in software engineering this is reflected in the fact that software is an intangible product so sometimes we cannot verify that our colleagues behave in the same way &#8230; so what Agile software development does is it banishes the inability to verify that co-operation is reciprocated, by increasing the process transparency, in such a way it banishes the working assumption of the prisoners dilemma.
</p></blockquote>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/techtalk" rel="tag">techtalk</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2008/03/22/human-aspects-of-agile-software-engineering/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Automated Testing Patterns and Smells</title>
		<link>http://www.virtualchaos.co.uk/blog/2008/03/09/automated-testing-patterns-and-smells/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2008/03/09/automated-testing-patterns-and-smells/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 18:05:42 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Talis]]></category>
		<category><![CDATA[unit-testing]]></category>
		<category><![CDATA[xp]]></category>
		<category><![CDATA[xunit]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2008/03/09/automated-testing-patterns-and-smells/</guid>
		<description><![CDATA[  
Wonderful tech talk by Gerard Meszaros who is a consultant specialising in agile development processes. In this particular presentation Gerard describes a number of common problems encountered when writing and running automated unit and functional tests. He describes these problems as &#8220;test smells&#8221;, and talks about their root causes. He also suggests possible [...]]]></description>
			<content:encoded><![CDATA[<p align="center"> <object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/Pq6LHFM4JvE"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/Pq6LHFM4JvE" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object> </p>
<p>Wonderful tech talk by Gerard Meszaros who is a consultant specialising in agile development processes. In this particular presentation Gerard describes a number of common problems encountered when writing and running automated unit and functional tests. He describes these problems as &#8220;test smells&#8221;, and talks about their root causes. He also suggests possible solutions which he expresses as design patterns for testing. While many of the practices he talks about are directly actionable by developers or testers, it&#8217;s important to realise that many also require action from a supportive manager and/or system architect in order to be really achievable.</p>
<p>We use many flavours of xUnit test frameworks in our development group at Talis, and we generally follow a Test First development approach, I found this talk beneficial because many of the issues that Gerard talks about are problems we have encountered and I don&#8217;t doubt every development group out there, including ours, can benefit from the insight&#8217;s he provides.</p>
<p>The material he uses in his talk and many of the examples are from his book <a href="http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Addison-Wesley/dp/0131495054">xUnit Test Patterns: Refactoring Test Code</a>, which I&#8217;m certainly going to order.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>, <a class="tag_technorati" href="http://technorati.com/tag/Testing" rel="tag">Testing</a>, <a class="tag_technorati" href="http://technorati.com/tag/unit-testing" rel="tag">unit-testing</a>, <a class="tag_technorati" href="http://technorati.com/tag/xp" rel="tag">xp</a>, <a class="tag_technorati" href="http://technorati.com/tag/xunit" rel="tag">xunit</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2008/03/09/automated-testing-patterns-and-smells/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Holding a Program in One&#8217;s Head</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/08/25/holding-a-program-in-ones-head/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/08/25/holding-a-program-in-ones-head/#comments</comments>
		<pubDate>Sat, 25 Aug 2007 18:26:08 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[essay]]></category>
		<category><![CDATA[paul-graham]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/08/25/holding-a-program-in-ones-head/</guid>
		<description><![CDATA[from an excellent new essay by Paul Graham &#8230; 


Good programmers manage to get a lot done anyway. But often it requires practically an act of rebellion against the organizations that employ them. Perhaps it will help to understand that the way programmers behave is driven by the demands of the work they do. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>from an <a href="http://www.paulgraham.com/head.html">excellent new essay by Paul Graham</a> &#8230; </p>
<p>
<blockquote>
Good programmers manage to get a lot done anyway. But often it requires practically an act of rebellion against the organizations that employ them. Perhaps it will help to understand that the way programmers behave is driven by the demands of the work they do. It&#8217;s not because they&#8217;re irresponsible that they work in long binges during which they blow off all other obligations, plunge straight into programming instead of writing specs first, and rewrite code that already works. It&#8217;s not because they&#8217;re unfriendly that they prefer to work alone, or growl at people who pop their head in the door to say hello. This apparently random collection of annoying habits has a single explanation: the power of holding a program in one&#8217;s head.<br />
<br/><br />
Whether or not understanding this can help large organizations, it can certainly help their competitors. The weakest point in big companies is that they don&#8217;t let individual programmers do great work. So if you&#8217;re a little startup, this is the place to attack them. Take on the kind of problems that have to be solved in one big brain.
</p></blockquote>
<p>so very true &#8230; !</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/essay" rel="tag">essay</a>, <a class="tag_technorati" href="http://technorati.com/tag/paul-graham" rel="tag">paul-graham</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/08/25/holding-a-program-in-ones-head/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Automated regression testing and CI with Selenium PHP</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/08/11/automated-regression-testing-and-ci-with-selenium-php/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/08/11/automated-regression-testing-and-ci-with-selenium-php/#comments</comments>
		<pubDate>Sat, 11 Aug 2007 16:06:31 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[selenium]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/08/11/automated-regression-testing-and-ci-with-selenium-php/</guid>
		<description><![CDATA[I&#8217;ve been doing some work this iteration on getting Selenium RC integrated into our build process so we can run a suite of automated functional regression tests&#160;against our&#160;application on each build. The application I&#8217;m working on is written in PHP, normally when you use Selenium IDE to record a test script it saves it as [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing some work this iteration on getting <a href="http://www.openqa.org/selenium-rc/">Selenium RC</a> integrated into our build process so we can run a suite of automated functional regression tests&nbsp;against our&nbsp;application on each build. The application I&#8217;m working on is written in PHP, normally when you use Selenium IDE to record a test script it saves it as a HTML file. </p>
<p>For example a simple test script that goes to Google and verifies that the text &#8220;Search:&#8221; is present on the screen and the title of the page is &#8220;iGoogle&#8221; looks like this:</p>
<p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;html<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;head<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;meta</span> <span class="re0">http-equiv</span>=<span class="st0">&quot;Content-Type&quot;</span> <span class="re0">content</span>=<span class="st0">&quot;text/html; charset=UTF-8&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;title<span class="re2">&gt;</span></span></span>New Test<span class="sc3"><span class="re1">&lt;/title<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/head<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;body<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;table</span> <span class="re0">cellpadding</span>=<span class="st0">&quot;1&quot;</span> <span class="re0">cellspacing</span>=<span class="st0">&quot;1&quot;</span> <span class="re0">border</span>=<span class="st0">&quot;1&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;thead<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;tr<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;td</span> <span class="re0">rowspan</span>=<span class="st0">&quot;1&quot;</span> <span class="re0">colspan</span>=<span class="st0">&quot;3&quot;</span><span class="re2">&gt;</span></span>New Test<span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;/tr<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/thead<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;tbody<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;tr<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span>open<span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span>/ig?hl=en<span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/tr<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;tr<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span>verifyTextPresent<span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span>Search:<span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/tr<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;tr<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span>assertTitle<span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span>iGoogle<span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;td<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;/td<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/tr<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/tbody<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;/table<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/body<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;/html<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>You can choose to export the script in several other languages, including PHP, in which case the test script it produces looks like this:</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span> <span class="st0">&#8216;Testing/Selenium.php&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span> <span class="st0">&#8216;PHPUnit/Framework/TestCase.php&#8217;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">class</span> Example <span class="kw2">extends</span> PHPUnit_Framework_TestCase</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">function</span> setUp<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">selenium</span> = <span class="kw2">new</span> Testing_Selenium<span class="br0">&#40;</span><span class="st0">&quot;*firefox&quot;</span>, <span class="st0">&quot;http://localhost:4444/&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$result</span> = <span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="kw2">function</span> tearDown<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">stop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="kw2">function</span> testMyTestCase<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">open</span><span class="br0">&#40;</span><span class="st0">&quot;/ig?hl=en&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; try </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">assertTrue</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">isTextPresent</span><span class="br0">&#40;</span><span class="st0">&quot;Search:&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; catch <span class="br0">&#40;</span>PHPUnit_Framework_AssertionFailedError <span class="re0">$e</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_push"><span class="kw3">array_push</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span>, <span class="re0">$e</span>-&gt;<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; try</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">assertEquals</span><span class="br0">&#40;</span><span class="st0">&quot;iGoogle&quot;</span>, <span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">getTitle</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; catch <span class="br0">&#40;</span>PHPUnit_Framework_AssertionFailedError <span class="re0">$e</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_push"><span class="kw3">array_push</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span>, <span class="re0">$e</span>-&gt;<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>The Export produces a valid PHPUnit test case that uses the <a href="http://www.openqa.org/selenium-rc/php.html">Selenium PHP Client Driver(Selenium.php)</a>. Whilst the script is valid and will run you do need add a little more to it before the test will correctly report errors. As it stands all errors captured during the test are added to an array called verificationErrors, by catching the assertion Exceptions that are thrown when an assert fails, in other words if you ran this test as it is, and it did fail you wouldn&#8217;t know! To correct this we need to do two things. Firstly, each assert needs to have a message added to it which will printed out in the test report if the assert fails. Secondly we need to modify the tearDown method so that once a test has run, it checks the verificationErrors array, and if any failures have occurred, fails the test. After making these changes the PHP test script looks like this:
</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span> <span class="st0">&#8216;Testing/Selenium.php&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span> <span class="st0">&#8216;PHPUnit/Framework/TestCase.php&#8217;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">class</span> GoogleHomePageTest <span class="kw2">extends</span> PHPUnit_Framework_TestCase</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">function</span> setUp<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">selenium</span> = <span class="kw2">new</span> Testing_Selenium<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;*firefox&quot;</span>, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;http://localhost:4444/&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$result</span> = <span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">function</span> tearDown<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">stop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span><span class="br0">&#41;</span> &gt; <span class="nu0">0</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;VERIFICATION ERRORS:&quot;</span> . <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">$this</span>-&gt;<span class="me1">fail</span><span class="br0">&#40;</span><a href="http://www.php.net/implode"><span class="kw3">implode</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\n</span>&quot;</span>,<span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">function</span> testGoogleHomePage<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">open</span><span class="br0">&#40;</span><span class="st0">&quot;/ig?hl=en&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; try </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">assertTrue</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">isTextPresent</span><span class="br0">&#40;</span><span class="st0">&quot;Search:&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;The string Search: was not found&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; catch <span class="br0">&#40;</span>PHPUnit_Framework_AssertionFailedError <span class="re0">$e</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_push"><span class="kw3">array_push</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span>, <span class="re0">$e</span>-&gt;<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; try</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">assertEquals</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;iGoogle&quot;</span>, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">$this</span>-&gt;<span class="me1">selenium</span>-&gt;<span class="me1">getTitle</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;The page title did not match iGoogle.&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; catch <span class="br0">&#40;</span>PHPUnit_Framework_AssertionFailedError <span class="re0">$e</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_push"><span class="kw3">array_push</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">verificationErrors</span>, <span class="re0">$e</span>-&gt;<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>
Obviously, I have also given the PHP Class  and test function slightly more meaningful names. Now you have a PHP Unit Test case that will use the Selenium PHP Client Driver with Selenium Remote Control to launch a browser, go to the specified URL, and test a couple of assertions. If any of those assertions fail, the tearDown method fails the test &#8230; pretty cool, right?
</p>
<p>
Well now it get&#8217;s better. Because the Selenium Client Driver has a published api which is pretty easy to follow, there&#8217;s no reason why you can&#8217;t just write test cases without using Selenium IDE &#8230; for those who want to you could even incorporate this into a TDD process. But for all this to hang together we need to be able to run a build, on a Continuous Integration server which checks out the code, runs unit tests and selenium regression tests against that code line, and only if all tests succeed passes the build.
</p>
<p>
We are currently using <a href="http://ant.apache.org/">ANT</a>, and <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a> to handle our CI/Automated build process. When running the automated suite of tests we need to ensure that the Selenium Remote Control server is also running which creates some complications. The Selenium Remote Control server takes several arguments which can also include the location of a test suite of html based selenium tests &#8211; which is really nice because the server will start, execute those tests and then end. Unfortunately you can&#8217;t invoke the server and pass it the location of a PHP based test suite. This means you need to find a way to start up the server, then run your tests, and once they are complete, shut the selenium server down.
</p>
<p>
He are the ANT targets that I have written to achieve this, if anyone can think of better ways of doing this I&#8217;d welcome any feedback or suggestions, to run this example you&#8217;d simply enter the command &#8220;ant selenium&#8221; :
</p>
<p><div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;selenium&quot;</span> <span class="re0">depends</span>=<span class="st0">&quot;clean, init&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Run the Selenium tests&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;parallel<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;antcall</span> <span class="re0">target</span>=<span class="st0">&quot;StartRCServer&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;antcall</span> <span class="re0">target</span>=<span class="st0">&quot;RunSeleniumTests&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;/parallel<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;StartRCServer&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Start the Selenium RC server&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="sc3"><span class="re1">&lt;java</span> <span class="re0">jar</span>=<span class="st0">&quot;dependencies/SeleniumRC/lib/selenium-server.jar&quot;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">fork</span>=<span class="st0">&quot;true&quot;</span> <span class="re0">failonerror</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;jvmarg</span> <span class="re0">value</span>=<span class="st0">&quot;-Dhttp.proxyHost=host.domain.com&quot;</span><span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;jvmarg</span> <span class="re0">value</span>=<span class="st0">&quot;-Dhttp.proxyPort=80&quot;</span><span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;/java<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;RunSeleniumTests&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;RunAllSeleniumTests&quot;</span><span class="re2">&gt;</span></span> &nbsp; &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;sleep</span> <span class="re0">milliseconds</span>=<span class="st0">&quot;2000&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;echo</span> <span class="re0">message</span>=<span class="st0">&quot;======================================&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="sc3"><span class="re1">&lt;echo</span> <span class="re0">message</span>=<span class="st0">&quot;Running Selenium Regression Test Suite&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;echo</span> <span class="re0">message</span>=<span class="st0">&quot;======================================&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;exec</span> <span class="re0">executable</span>=<span class="st0">&quot;php&quot;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">failonerror</span>=<span class="st0">&quot;false&quot;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">dir</span>=<span class="st0">&quot;test/seleniumtests/regressiontests/&quot;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">resultproperty</span>=<span class="st0">&quot;regError&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;arg</span> <span class="re0">line</span>=<span class="st0">&quot;../../../dependencies/PHPUnit/TextUI/Command.php &#8211;log-xml ../../../doc/SeleniumTestReports/RegressionTests/TestReport.xml AllRegressionTests&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;/exec<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;get</span> <span class="re0">taskname</span>=<span class="st0">&quot;selenium-shutdown&quot;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">src</span>=<span class="st0">&quot;http://localhost:4444/selenium-server/driver/?cmd=shutDown&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">dest</span>=<span class="st0">&quot;result.txt&quot;</span> <span class="re0">ignoreerrors</span>=<span class="st0">&quot;true&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;condition</span> <span class="re0">property</span>=<span class="st0">&quot;regressionTest.err&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;or<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;equals</span> arg1=<span class="st0">&quot;1&quot;</span> arg2=<span class="st0">&quot;${regError}&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;equals</span> arg1=<span class="st0">&quot;2&quot;</span> arg2=<span class="st0">&quot;${regError}&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/or<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;/condition<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;fail</span> <span class="re0">if</span>=<span class="st0">&quot;regressionTest.err&quot;</span> <span class="re0">message</span>=<span class="st0">&quot;ERROR: Selenium Regression Tests Failed&quot;</span> <span class="re2">/&gt;</span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>
A couple of notes, the reason I have to use a conditional check at the end of the selenium target is because, if the exec task that runs the PHP tests was set to failonerror=true then the build would never reach the next line which shuts the Selenium RC server down. To ensure that always happens I have to set the exec to failonerror=false, but this means I have to check what the result was from the exec. Which if successful will return 0, if test failures exist will return 1, and if there were any errors (preventing a test to be exectuted ) will return 2. Hence the conditional check sets regressionTest.err if either of these latter two conditions are true.
</p>
<p>
Also in order to start up the server, which could take up to a second, but can&#8217;t be sure precisely how long. I have to use the Ant Parallel task, which calls the task to start the server and the task to run the tests at the same time. The task to run the tests has a 2 second sleep in it, which should be more than enough time to allow the server to start. This all kind of feels a little clunky, but at the moment it does work very well.
</p>
<p>
In a nutshell, thats how you integrate PHP based Automated Selenium Regression tests into a continuous build.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Continuous+Integration" rel="tag">Continuous Integration</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/PHP" rel="tag">PHP</a>, <a class="tag_technorati" href="http://technorati.com/tag/selenium" rel="tag">selenium</a>, <a class="tag_technorati" href="http://technorati.com/tag/Testing" rel="tag">Testing</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/08/11/automated-regression-testing-and-ci-with-selenium-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Continuous Integration with PHP</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/07/02/continuous-integration-with-php/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/07/02/continuous-integration-with-php/#comments</comments>
		<pubDate>Mon, 02 Jul 2007 22:02:16 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[Talis]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/07/02/continuous-integration-with-php/</guid>
		<description><![CDATA[
I&#8217;m in the process of setting up a continuous integration environment for a new PHP project I&#8217;m starting. On our previous project, which was Java based, we used the following tools to support similar requirements on that project in order to allow us to implement the project using a test driven approach and automate build [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;m in the process of setting up a continuous integration environment for a new PHP project I&#8217;m starting. On our previous project, which was Java based, we used the following tools to support similar requirements on that project in order to allow us to implement the project using a test driven approach and automate build generation:</p>
<ul>
<li><a href="http://cruisecontrol.sourceforge.net/">Cruise Control</a> &#8211; For setting up a Continuous Build process.</li>
<li><a href="http://ant.apache.org/">Ant</a> &#8211; A Java based build tool.</li>
<li><a href="http://www.junit.org/index.htm">JUnit</a> &#8211; A Java Based xunit testing framework</li>
<li><a href="http://pmd.sourceforge.net/">PMD</a> &#8211; A tool that checks for common coding standards violations.</li>
<li><a href="http://cobertura.sourceforge.net/">Corbetura</a> &#8211; A Java based code coverage too that calculates the percentage of code accessed by unit tests</li>
</ul>
<p>
I&#8217;ve managed to set up an analogous process for our PHP project using the following tools:</p>
<ul>
<li><a href="http://cruisecontrol.sourceforge.net/">Cruise Control</a> &#8211; For setting up a Continuous Build process.</li>
<li><a href="http://ant.apache.org/">Ant</a> &#8211; A Java based build tool.</li>
<li><a href="http://www.phpunit.de/">PHPUnit</a> &#8211; An Xunit testing framework for PHP</li>
<li><a href="http://pear.php.net/package/PHP_CodeSniffer">PHP_CodeSniffer</a> &#8211; A PHP tool that checks for common coding standards violations.</li>
<li><a href="http://xdebug.org/">Xdebug</a> &#8211; Debugging tool, which when combined with PHPUnit, can provide Code Coverage Metrics</li>
</ul>
<p>
It seems to work quite well, here&#8217;s the relatively simple ant build script that controls it all.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">?&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;project</span> <span class="re0">default</span>=<span class="st0">&quot;all&quot;</span> <span class="re0">name</span>=<span class="st0">&quot;DummyProject&quot;</span> <span class="re0">basedir</span>=<span class="st0">&quot;.&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;all&quot;</span> <span class="re0">depends</span>=<span class="st0">&quot;clean, init, test, sniff&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;clean&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;delete</span> <span class="re0">dir</span>=<span class="st0">&quot;doc/CodeCoverage&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;delete</span> <span class="re0">dir</span>=<span class="st0">&quot;doc/UnitTestReport&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;init&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mkdir</span> <span class="re0">dir</span>=<span class="st0">&quot;doc/CodeCoverage&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mkdir</span> <span class="re0">dir</span>=<span class="st0">&quot;doc/UnitTestReport&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;test&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Run PHPUnit tests&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;exec</span> <span class="re0">dir</span>=<span class="st0">&quot;./&quot;</span> <span class="re0">executable</span>=<span class="st0">&quot;TestRunner.bat&quot;</span> <span class="re0">failonerror</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/exec<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;sniff&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;exec</span> <span class="re0">dir</span>=<span class="st0">&quot;./&quot;</span> <span class="re0">executable</span>=<span class="st0">&quot;Sniffer.bat&quot;</span> <span class="re0">failonerror</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/exec<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;/project<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>I&#8217;m currently running this on a windows machine although it&#8217;s trivial to change it work in an *ix based environment which I&#8217;ll probably configure in the next day or so. I had a couple of problems installing PHP_CodeSniffer  although it was because I hadn&#8217;t installed PEAR properly. If you have any problems installing PHP_CodeSniffer under Windows then follow these instructions:</p>
<p>
To install PEAR under windows do the following, which assumes you have PHP5.2x installed in c:\php :</p>
<pre>
  cd c:\\php
  go-pear.bat
</pre>
<p>The interactive installer presents you with some options, if you follow the defaults you should be fine.<br />
Once PEAR has installed you can install PHP_CodeSniffer like this:</p>
<pre>
  cd c:\\php
  pear install PHP_CodeSniffer-beta
</pre>
<p>This will download the PHP_CodeSniffer package and install into into your php/PEAR folder.</p>
<p>Once this is done you can check to see if it has installed by calling phpcs with -h flag which will produce the following:</p>
<pre>
C:\\php>phpcs -h
Usage: phpcs [-nlvi] [--report=<report>] [--standard=<standard>]
    [--generator=<generator>] [--extensions=<extensions>] <file> ...
        -n           Do not print warnings
        -l           Local directory only, no recursion
        -v[v][v]     Print verbose output
        -i           Show a list of installed coding standards
        --help       Print this help message
        --version    Print version information
        <file>       One or more files and/or directories to check
        <extensions> A comma separated list of file extensions to check
                     (only valid if checking a directory)
        <standard>   The name of the coding standard to use
        <generator>  The name of a doc genertor to use
                     (forces doc generation instead of checking)
        <report>     Print either the "full" or "summary" report
</pre>
<p>Now try it out &#8230;</p>
<pre>
C:\\php>phpcs C:\\Projects\\dummyproject\\test\\

FILE: C:\\Projects\\dummyproject\\test\\AllTests.php
--------------------------------------------------------------------------------
FOUND 7 ERROR(S) AND 0 WARNING(S) AFFECTING 7 LINE(S)
--------------------------------------------------------------------------------
  1 | ERROR | End of line character is invalid; expected "\n" but found "\r\n"
  2 | ERROR | Missing file doc comment
  3 | ERROR | Constants must be uppercase; expected 'PHPUNIT_MAIN_METHOD' but
    |       | found 'PHPUnit_MAIN_METHOD'
 12 | ERROR | Missing class doc comment
 14 | ERROR | Missing function doc comment
 19 | ERROR | Missing function doc comment
 30 | ERROR | Constants must be uppercase; expected PHPUNIT_MAIN_METHOD but
    |       | found PHPUnit_MAIN_METHOD
--------------------------------------------------------------------------------
</pre>
<p>Check the documentation for what the various command line switches do, but you can generate summary reports as well on an entire directory tree:</p>
<pre>
C:\\php>phpcs --report=summary --standard=Squiz C:\\Projects\\dummyproject\\test\\

PHP CODE SNIFFER REPORT SUMMARY
--------------------------------------------------------------------------------
FILE                                                            ERRORS  WARNINGS
--------------------------------------------------------------------------------
C:\\Projects\\dummyproject\\test\\AllTests.php                  24      0
C:\\Projects\\dummyproject\\test\\NodeTest.php                  10      0
C:\\Projects\\dummyproject\\test\\NodeTypeTest.php              11      0
--------------------------------------------------------------------------------
A TOTAL OF 45 ERROR(S) AND 0 WARNING(S) WERE FOUND IN 3 FILE(S)
--------------------------------------------------------------------------------
</pre>
</p>
<p> &#8230; </p>
<p>Overall I&#8217;m quite happy with this set up which for the most part was pretty straight forward. I have no doubt it will evolve over time but I think it&#8217;s a good foundation on which to build upon.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Continuous+Integration" rel="tag">Continuous Integration</a>, <a class="tag_technorati" href="http://technorati.com/tag/PEAR" rel="tag">PEAR</a>, <a class="tag_technorati" href="http://technorati.com/tag/PHP" rel="tag">PHP</a>, <a class="tag_technorati" href="http://technorati.com/tag/phpunit" rel="tag">phpunit</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/07/02/continuous-integration-with-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Greeks vs Romans. Adaptive vs Plain-Driven development.</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/06/25/greeks-vs-romans-adaptive-vs-plain-driven-development/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/06/25/greeks-vs-romans-adaptive-vs-plain-driven-development/#comments</comments>
		<pubDate>Mon, 25 Jun 2007 21:55:16 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[adaptive-development]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[plain-driven-development]]></category>
		<category><![CDATA[software-engineering]]></category>
		<category><![CDATA[Talis]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/06/25/greeks-vs-romans-adaptive-vs-plain-driven-development/</guid>
		<description><![CDATA[Came across this wonderful essay over at Hacknot today. The essay starts off by decrying this assertion made by Raghavendra Rao Loka, in February&#8217;s 2007 edition of IEEE Software:
&#8220;Writing and maintaining software are not engineering activities. So it&#8217;s not clear why we call software development software engineering.&#8221;

The author of the essay goes onto offer a [...]]]></description>
			<content:encoded><![CDATA[<p>Came across <a href="http://www.hacknot.info/hacknot/action/showEntry?eid=95">this wonderful essay</a> over at Hacknot today. The essay starts off by decrying this assertion made by Raghavendra Rao Loka, in February&#8217;s 2007 edition of IEEE Software:</p>
<blockquote><p>&#8220;Writing and maintaining software are not engineering activities. So it&#8217;s not clear why we call software development software engineering.&#8221;</p>
</blockquote>
<p>The author of the essay goes onto offer a brief rebuttal of this this based on some comments by Steve McConnell, and pointed out quite rightly in my opinion that:</p>
<p>
<blockquote>Software development is slowly and surely moving its way out of the mire of superstition and belief into the realm of empiricism and reason. The transition closely parallels those already made in other disciplines, such as medicine&#8217;s evolution from witchcraft into medical science.</p></blockquote>
<p>What I found really insightful though was how the author likened these two views ( Loka vs McConnell ) to another conflict:</p>
<p>
<blockquote>These two represent the age-old conflict between the engineers and the artists, the sciences and the humanities. In the software development domain, some have previously characterized it as the battle between the Greeks and the Romans.</p></blockquote>
<p>He then&nbsp;applies this same metaphor to the wider issue of adaptive&nbsp;vs the&nbsp;plain-driven approaches to software development and in doing so offers an interesting perspective on the two schools of thought:</p>
<p>
<blockquote>By now you will probably have recognized the analogue between the cultural divide separating the Greeks and Romans and the methodological divide between adaptive and plan-driven approaches to software development.</p>
<p>We can think of the Greeks as representative of Agile Methods. The focus is upon loosely coordinated individuals whose talent and passion combine to produce great artefacts of creativity. Any organizational shortcomings the team might experience are overcome by the cleverness and skilful adaptivity of the contributors.</p>
<p>Alternatively, we can consider the Romans as representative of plan driven methods, in which the carefully engineered and executed efforts of competent and well educated practitioners combine to produce works of great size and complexity. The shortcomings of any of the individuals involved are overcome by the systematic methods and peer review structure within which they work.</p></blockquote>
<p>It&#8217;s a wonderful analogy that I think illustrates some of the differences between the two approaches in a way that most practitioners would readily understand and perhaps even agree with.&nbsp;Which is the right approach? I guess it depends on you, your project but most importantly the kind of people you have in your team. I have certainly&nbsp;<a href="http://www.virtualchaos.co.uk/blog/tag/agile/">spent a considerable amount of time</a> extolling what I believe are the virtues of the agile methodology on this blog.</p>
<p>I spent several years working in a very&nbsp;Roman-esque organisation and I&#8217;d probably argue that the <em>competent </em>and <em>well educated</em> practitioners in such organisations rarely&nbsp;fit&nbsp;either of those terms.&nbsp;Probably because the very nature of such&nbsp;systems require&nbsp;those working within that confine to accept a certain level of conformity.&nbsp;Consequently&nbsp;individual flair, creativity or even imagination are less important than the uniformity that such&nbsp;organisations require &#8211; a sort of fill-in-the-blanks approach to development where your responsible for only those small pieces assigned to you, and whether you necessarily know what the bigger picture is or even understand it&nbsp;isn&#8217;t important because some more <em>senior</em> in the team who assigns you your tasks does know. This often results in developers feeling disaffected&nbsp;or perhaps less likely to feel any sense of personal ownership or even responsibility, because they know they aren&#8217;t in a position to be responsible for anything.</p>
<p>I do find myself agreeing that part of what makes agile teams successful is this notion of <em>heroics</em> on the part of individuals. It does work well&nbsp;when you have talented individuals who can work together&nbsp;in a reasonably small scale. How well does that scales up? &#8230; I can&#8217;t personally answer that question?&nbsp;&nbsp;I&#8217;ve read plenty of accounts and listened to the likes of <a href="http://www.ambysoft.com/">Scott Ambler</a> explain <a href="http://www.ddj.com/dept/architect/184415491?cid=Ambysoft">how agile can work</a> on large scale projects. I must admit I&#8217;m not sure if I&#8217;m convinced of this. &#8230; but that&#8217;s only because of my earlier point that this decision needs, in part, to be based on the type of people you have your in team. </p>
<p>Our development group at Talis is quite small,at the moment no more than&nbsp;20 people &#8211; and it&#8217;s not for a lack of trying, were constantly trying to recruit people but we look specifically for skilled developers who could fit into the culture that we have. Individuals who are self motivated, self learners who&nbsp;take a great deal of personal pride in what they do, take responsibility and also want to have a sense of ownership over what they are building. As a result we tend to be quite jealous of who we let into the team, but again that&#8217;s probably something that is unique to our little group and says&nbsp;more about us than the Agile process.</p>
<p>I do find myself partly agreeing with the conclusion the author of the essay makes:</p>
<blockquote><p>I favour a development method that is predominantly Greek, with sufficient Roman thrown in to keep things under control and prevent needless wheel spinning. The Greeks are a great bunch of guys, but they tend to put too much emphasis on individual heroics, and pay too little attention to the needs of the maintenance programmers that will following in their path. The Romans are a little stuffy and formal, but they really know how to keep things under control and keep your project running smoothly and predictably</p>
</blockquote>
<p>&nbsp;I don&#8217;t agree that, in&nbsp;terms of software development, &nbsp;the Roman approach was ever truly able to <em>keep things under control</em> or necessarily <em>running smoothly</em> even <em>predictably</em>.&nbsp;If it was we wouldn&#8217;t have so many examples of failed projects that went over budget, went over time and totally failed to deliver what the customer actually wanted.</p>
<p>I personally do prefer a predominantly Greek approach and&nbsp;I do&nbsp;see methodologies such as SCRUM imposing the right level of Roman-esque control and structure to keep the project moving along smoothly and predictably, with the added bonus that the customer actually gets what they want.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/adaptive-development" rel="tag">adaptive-development</a>, <a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/plain-driven-development" rel="tag">plain-driven-development</a>, <a class="tag_technorati" href="http://technorati.com/tag/software-engineering" rel="tag">software-engineering</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/06/25/greeks-vs-romans-adaptive-vs-plain-driven-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spikes, PHP and a Platform that just works</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/05/25/spikes-php-and-a-platform-that-just-works/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/05/25/spikes-php-and-a-platform-that-just-works/#comments</comments>
		<pubDate>Fri, 25 May 2007 21:02:00 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[platform]]></category>
		<category><![CDATA[Talis]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/05/25/spikes-php-and-a-platform-that-just-works/</guid>
		<description><![CDATA[I&#8217;ve had a pretty good week. I&#8217;ve been totally engrossed in a project I&#8217;ve been working on since getting back from Xtech last week. Essentially I&#8217;ve been working on a spike with Andrew and Hardeep to extend the functionality in our Project Cenote concept car.
The purpose of the spike was two fold. Firstly to try [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had a pretty good week. I&#8217;ve been totally engrossed in a project I&#8217;ve been working on since getting back from <a href="http://2007.xtech.org/">Xtech</a> last week. Essentially I&#8217;ve been working on a spike with <a href="http://www.aztecmonkey.com">Andrew</a> and Hardeep to extend the functionality in our <a href="http://cenote.talis.com">Project Cenote</a> concept car.</p>
<p>The purpose of the spike was two fold. Firstly to try to better understand how to build a funky new set of features into Cenote, and secondly to allow the members of the team become familiar with and experiment with some technologies that they aren&#8217;t familiar with.</p>
<p>In fact it felt quite good leaving work today, having gotten to the point where the little prototype is pretty much feature complete. What&#8217;s really impressed me isn&#8217;t necessarily what it does (which is cool!), but the speed with which we&#8217;ve been able to put it all together. The spike was timeboxed to two weeks, but the reality is that the bulk of the implementation has actually been completed within the last few days. It&#8217;s by no means a production system it&#8217;s just enough to hopefully facilitate some of the discussions we hope to have both internally and externally &#8230; much like the first release of Cenote, <a href="http://http:/www.talis.com/tdn/cenote/">which we Open Sourced recently</a>.</p>
<p>The original version of Cenote was a read only application that allowed users to search for books and then mashed up the results with data held in various stores in the <a href="http://www.talis.com/platform/index.shtml">Talis Platform</a> as well as external sources such as Amazon in order to provide users with some pretty useful information.  This spike extends the original version by allowing users to use that data to create and share some really useful things.</p>
<p>I think there&#8217;s some important reasons why we have been able to put this together so quickly. The technology stack has been kept very simple &#8211; its just an application built in <a href="http://www.php.net">PHP5</a>, running under <a href="http://httpd.apache.org/">Apache 2</a>. Furthermore the application is built upon our <a href="http://www.talis.com/platform/index.shtml">Talis Platform</a> which is constantly evolving and becoming more and more powerful. I&#8217;m not saying that just as someone who has worked on building that platform, I&#8217;m actually saying that as someone who has been using and consuming it&#8217;s services primarily to build applications with it.</p>
<p>When <a href="http://www.dynamicorange.com/blog/">Rob</a> and I originally wrote Cenote, we were both impressed at how easily we were able to use the platform, as it was then, to put together a cool looking application in the space of a couple of days. If that impressed me at the time, then I&#8217;m doubly impressed at how simple it&#8217;s been to create an application that supports creation, deletion and updating of data.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/platform" rel="tag">platform</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/05/25/spikes-php-and-a-platform-that-just-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Role of Testing and QA in Agile Software Development</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/05/08/the-role-of-testing-and-qa-in-agile-software-development/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/05/08/the-role-of-testing-and-qa-in-agile-software-development/#comments</comments>
		<pubDate>Tue, 08 May 2007 23:14:45 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/05/08/the-role-of-testing-and-qa-in-agile-software-development/</guid>
		<description><![CDATA[In our development group at Talis We&#8217;ve been thinking a lot about how to test more effectively in an agile environment. One of my colleagues, sent me a link to this excellent talk by Scott Ambler which examines the Role of Testing and QA in Agile Software Development.
Much of the talk is really an introduction [...]]]></description>
			<content:encoded><![CDATA[<p>In our development group at Talis We&#8217;ve been thinking a lot about how to test more effectively in an agile environment. One of my colleagues, sent me a link to this excellent talk by Scott Ambler which examines the <a href="http://www.infoq.com/presentations/role-of-testing-in-agile-scott-ambler">Role of Testing and QA in Agile Software Development</a>.</p>
<p>Much of the talk is really an introduction to Agile Development which is beneficial to listen to because Scott dispels some of the myths around agile, and offers his own views on best practises using some examples. It does get a bit heated around the 45 minute mark when he&#8217;s discussing Database Refactoring, some of the people in the audience were struggling with the idea he was presenting which I felt was fairly simple. If you really want to skip all that try to forward to the 50 minute mark where he starts talking about sandboxes. What I will say is that if your having difficulty getting Agile accepted into your organisation then this might be a video you want to show your managers since it covers all the major issues and benefits.</p>
<p>Here&#8217;s some of the tips he has with regard to testing and improving quality:</p>
<ul>
<li>Do Test Driven Development, the unit tests are the detailed design, they force developers to think about the design. Call it <em>Just-in-time design</em>.</li>
<li>Use Continuous Integration to build and run unit tests on each check-in to trunk.</li>
<li>Acceptance Tests are primary artefacts. Don&#8217;t bother with a requirements document simply maintain the acceptance test since the reality is that all testing teams will do is take that requirement and copy it into an acceptance test, so why introduce a traceability issue when you don&#8217;t need it. <a href="http://www.agilemodeling.com/essays/singleSourceInformation.htm">http://www.agilemodeling.com/essays/singleSourceInformation.htm</a></li>
<li>Use Standards and Guidelines to help ensure teams are creating consistent artefacts.</li>
<li>Code Reviews and Inspections are not a best practise. They are used  to compensate for people working alone, not sharing their work, not communicating, poor teamwork, and poor collaboration. <em>Guru checks output</em> is an anti-pattern. Working together, pairing, good communication, teamwork should negate the need for code reviews and inspections.</li>
<li>Short feedback loop is extremely important. The faster you can get testing results and feedback from stakeholders the better.</li>
<li>Testers need to be flexible, willing to pick up new skills, need to be able to work with others. They need to be generalising specialists. The trend that is emerging in agile or the emerging belief is that there is no need for <em>traditional</em> testers.</li>
</ul>
<p>Scott is a passionate speaker and very convincing, some of the points he makes are quite controversial yet hard to ignore &#8211; especially his argument that traditional testers are becoming less necessary. I&#8217;m not sure I agree with all his views yet he has succeeded in forcing me to challenge my own views which I need to mull over and for that reason alone watching his talk has been invaluable.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Continuous+Integration" rel="tag">Continuous Integration</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/Technology" rel="tag">Technology</a>, <a class="tag_technorati" href="http://technorati.com/tag/Testing" rel="tag">Testing</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/05/08/the-role-of-testing-and-qa-in-agile-software-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>End of sprint, SCRUM and why I&#8217;m feeling so good</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/04/28/end-of-sprint-scrum-and-why-im-feeling-so-good/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/04/28/end-of-sprint-scrum-and-why-im-feeling-so-good/#comments</comments>
		<pubDate>Sat, 28 Apr 2007 09:33:15 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Talis]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/04/28/end-of-sprint-scrum-and-why-im-feeling-so-good/</guid>
		<description><![CDATA[We&#8217;ve just reached the end of our eighth sprint on the project I&#8217;ve been working on. On Monday we&#8217;ll be doing our end of sprint demonstrations to customers as well as internally to the rest of the company and I have to say I&#8217;m feeling quite good about it. It&#8217;s a lovely day today feel [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve just reached the end of our eighth sprint on the project I&#8217;ve been working on. On Monday we&#8217;ll be doing our end of sprint demonstrations to customers as well as internally to the rest of the company and I have to say I&#8217;m feeling quite good about it. It&#8217;s a lovely day today feel like I need to chill (or as <a href="http://www.dynamicorange.com/blog/">Rob </a>suggested &#8211; maybe I need to get a life <img src='http://www.virtualchaos.co.uk/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  )  anyway I&#8217;ve been sitting here reflecting on this month and there&#8217;s a few things I want to talk about.</p>
<p>I&#8217;m fairly new to the <a href="http://en.wikipedia.org/wiki/Scrum_(development)">SCRUM</a> methodology, in fact this is the first project I&#8217;ve worked on that formally uses it. Our development group here at <a href="http://www.talis.com">Talis </a>has adopted the SCRUM process across all of our current projects with what I feel has been a great deal of success.</p>
<p>For me personally the transition from traditional waterfall approaches to agile methodologies has been a revelation in many ways. Before joining Talis I&#8217;d spent a number of years developing software based on traditional waterfall methodologies. What was frustrating with these traditional approaches was that you&#8217;d spend months capturing and documenting requirements, you&#8217;d then spend a while analysing these requirements and then designing your software product, before implementing it and then testing it. Any changes to the requirements invariably meant going through a process of <em>change impact analysis </em>and then going through the whole process again (for the changed requirements), which naturally increases the cost to the customer.</p>
<p>A side effect of which, from the perspective of the customer, was that changing requirements during the project was a bad idea, because of the extra costs it would incur. A consequence of this is that customers would often take delivery of systems which after a couple of years of development, don&#8217;t actually satisfy the requirements that they now have. These same customers would then <em>have</em> to take out a maintenance contract with the vendor to get the systems updated to satisfy their new requirements.</p>
<p>From a developers point of view, I often found this to be very demoralising, you knew you you were building something the customer didn&#8217;t really want, but the software house you work for wants to do that because they have a signed off requirements document and contract that guarantee&#8217;s them more money if the customer changes their mind. I often found that when we reached the end of a project, the delivery of that software to the customer was a very and nervous and stressful time. The customer at this point has not necessarily had any visibility of the product so there&#8217;s usually a couple of months when your organisation is trying to get them to accept the product &#8211; which invariably led to arguments over the interpretation of requirements &#8211; and sometimes scary looking meetings between lawyers from both sides.</p>
<p>There was always something very wrong with it.</p>
<p>Since joining Talis, and transitioning to agile methodologies I can finally see why it was so wrong, and why agile, and in this case SCRUM, work so well.</p>
<p>For one thing, I&#8217;m not nervous about the end of sprint demonstrations. <img src='http://www.virtualchaos.co.uk/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  The customers have been involved all along, they&#8217;ve been using the system, constantly providing feedback, constantly letting us know what were doing well, and what we need to improve on.</p>
<p>Our <a href="http://en.wikipedia.org/wiki/Scrum_%28development%29#Sprint">sprints</a> have been four weeks long, which means at the beginning of the sprint we agree which stories we are going to implement based on what the customers have asked us for, these can be new stories that have been identified, or stories from the backlog. The customers have an idea, from previous sprints, what our velocity is &#8211; in other words they, and we, know how much work we can get done in a sprint so when we pick the stories for the sprint we ensure we don&#8217;t exceed that limit. This keeps things realistic. Any story that doesn&#8217;t get scheduled in for the sprint because it was deemed less of a priority than the stories that are selected gets added to a backlog.</p>
<p>This iterative cycle is great! For one thing customer&#8217;s are encouraged to change their minds, to change their requirements, because they then have to prioritise whether that change is more important than the other items on the backlog. They are empowered to choose what means the most to them, and that&#8217;s what we give them ! The customer doesn&#8217;t feel like the enemy, but an integral part of the team, and for me that&#8217;s vital.</p>
<p>As a developer it feels great to know that your customers like your product &#8230; and why shouldn&#8217;t they, they&#8217;ve been involved every step of the way, they&#8217;ve been using it every step of the way.</p>
<p>I&#8217;ve only been here at Talis for ten months, and in that time I&#8217;ve had to constantly re-examine and re-evaluate not only what I think it means to be a good software developer but pretty much every facet of the process of building services and products for customers. For me it&#8217;s been an amazing journey of discovery and I&#8217;m pretty certain it&#8217;s going to continue to be for a very long time.</p>
<p>The really wonderful thing though is that in our development group I&#8217;m surrounded by a team of people who believe passionately that it&#8217;s the journey and how we deal with it that defines us, and not the destination. So we are constantly looking for ways to improve, that in itself can be inspiring.<br />
So yeah &#8230; I feel good!</p>
<p>Our development group is always looking for talented developers who share our ethos and could fit into the culture we have here. If you&#8217;d like to be a part of this journey then <a href="http://www.talis.com/about/careers.shtml">get in touch with us</a>. Some of us, including myself,  will be at <a href="http://2007.xtech.org/public/news">XTECH 2007</a> next month, so if your attending the conference come and have a chat with us.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/Personal" rel="tag">Personal</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/04/28/end-of-sprint-scrum-and-why-im-feeling-so-good/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why software sucks</title>
		<link>http://www.virtualchaos.co.uk/blog/2007/01/05/why-software-sucks/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2007/01/05/why-software-sucks/#comments</comments>
		<pubDate>Fri, 05 Jan 2007 21:05:45 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Talis]]></category>
		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2007/01/05/why-software-sucks/</guid>
		<description><![CDATA[Over on slashdot theres an excellent little article and debate around the issue of why software sucks. The slashdot article points to this news story on the Fox News Network.  that discusses the book by David Platt entitled &#8220;Why software sucks &#8230;. and what you can do about it&#8220;. I haven&#8217;t read the book [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://developers.slashdot.org/article.pl?sid=07/01/05/1841216&#038;from=rss">Over on slashdot</a> theres an excellent little article and debate around the issue of why software sucks. The slashdot article points to this <a href="http://www.foxnews.com/story/0,2933,241578,00.html">news story on the Fox News Network.</a>  that discusses the book by David Platt entitled &#8220;<a href="http://www.amazon.com/Why-Software-Sucks-What-About/dp/0321466756/sr=8-1/qid=1168030869/ref=pd_bbs_sr_1/104-1689003-0739140?ie=UTF8&#038;s=books">Why software sucks &#8230;. and what you can do about it</a>&#8220;. I haven&#8217;t read the book yet but I&#8217;ve added it to my <em>things to read list</em>. The debate on slashdot though is actually quite interesting and worth reading in its own right. What interests me is how some of the sentiments echoed in the articles and discussions resonate around my earlier views that <a href="http://www.virtualchaos.co.uk/blog/2006/12/05/programmers-are-generally-bad-at-user-interface-design/">programmers arent usability experts</a>, and until we start developing software centred around the user &#8230; software will continue to suck.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Books" rel="tag">Books</a>, <a class="tag_technorati" href="http://technorati.com/tag/Development" rel="tag">Development</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>, <a class="tag_technorati" href="http://technorati.com/tag/Usability" rel="tag">Usability</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2007/01/05/why-software-sucks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code reviews at Google with Mondrian</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/12/16/code-reviews-at-google-with-mondrian/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/12/16/code-reviews-at-google-with-mondrian/#comments</comments>
		<pubDate>Sat, 16 Dec 2006 15:02:45 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Tech Talk]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/12/16/code-reviews-at-google-with-mondrian/</guid>
		<description><![CDATA[Another excellent Tech Talk. Our development group at Talis has been experimenting with different ways to carry out code reviews and I think its safe to say were still trying to find what works best for us.
I think this tech talk is very relevant not just to the discussions were having internally, but to any [...]]]></description>
			<content:encoded><![CDATA[<p>Another excellent Tech Talk. Our development group at Talis has been experimenting with different ways to carry out code reviews and I think its safe to say were still trying to find what works best for us.</p>
<p>I think <a href="http://video.google.com/videoplay?docid=-8502904076440714866&#038;q=type%3Agoogle+engEDU">this tech talk</a> is very relevant not just to the discussions were having internally, but to any organisation that is serious about wanting to ensure that they are developing great, maintainable software.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Google" rel="tag">Google</a>, <a class="tag_technorati" href="http://technorati.com/tag/Tech+Talk" rel="tag">Tech Talk</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/12/16/code-reviews-at-google-with-mondrian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scrum &#8211; the Google-y way</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/12/16/scrum-the-google-y-way/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/12/16/scrum-the-google-y-way/#comments</comments>
		<pubDate>Sat, 16 Dec 2006 14:39:47 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Tech Talk]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/12/16/scrum-the-google-y-way/</guid>
		<description><![CDATA[A great tech talk detailing how Google have been using Scrum, the lessons they&#8217;ve learnt and some new things scrum teams should try out.

	Agile, Google, Tech Talk
]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://video.google.com/videoplay?docid=8795214308797356840&#038;q=type%3Agoogle+engEDU">great tech talk</a> detailing how Google have been using Scrum, the lessons they&#8217;ve learnt and some new things scrum teams should try out.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Google" rel="tag">Google</a>, <a class="tag_technorati" href="http://technorati.com/tag/Tech+Talk" rel="tag">Tech Talk</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/12/16/scrum-the-google-y-way/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ea_spouse : profit at the cost of human dignity</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/12/16/ea_spouse-profit-at-the-cost-of-human-dignity/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/12/16/ea_spouse-profit-at-the-cost-of-human-dignity/#comments</comments>
		<pubDate>Sat, 16 Dec 2006 14:15:27 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Talis]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/12/16/ea_spouse-profit-at-the-cost-of-human-dignity/</guid>
		<description><![CDATA[My copy of The Best Software Writing I &#8211; selected and introduced by Joel Spolsky arrived the day before yesterday. I finally managed to start reading it last night after getting back from a truly magical evening at the Chinese State Circus. The book is a collection of essays/posts on online blogs that Spolsky has [...]]]></description>
			<content:encoded><![CDATA[<p>My copy of <a href="http://www.amazon.com/Best-Software-Writing-Selected-Introduced/dp/1590595009">The Best Software Writing I &#8211; selected and introduced by Joel Spolsky</a> arrived the day before yesterday. I finally managed to start reading it last night after getting back from a truly magical evening at the <a href="http://www.bbc.co.uk/birmingham/content/articles/2006/12/13/chinese_state_circus_06_feature.shtml">Chinese State Circus</a>. The book is a collection of essays/posts on online blogs that Spolsky has brought together as examples of simple goodle writing that engages the reader and captivates them. Spolsky introduces each essay with his own take on the subject matter. The essay I chose to read first was entitled EA &#8211; The Human Story. Anyone who knows me, knows I play several online games (most FPS ones), and I have a great interest in the gaming industry in terms of the products and technologies that they produce.</p>
<p>It&#8217;s safe to say that I was not expecting to be moved quite as much as I was by this account, which you can read online in its entirety over at <a href="http://ea-spouse.livejournal.com/">http://ea-spouse.livejournal.com/</a>. Before I go any further I will say this, I believe that ANYONE working in the software industry or in human resources, in fact everyone should read the essay.</p>
<p>It&#8217;s written by the spouse of an Electronic Arts employee who wrote this under the anonymous moniker <em>ea_spouse</em>, she chose to remain anonymous because in her own words she has &#8220;<em>no illusions about what the consequences would be for my family if I was explicit</em>&#8220;. Her account dramatically made the world aware of the shocking sweatshop-like labor practises at EA. It&#8217;s important to point out that this account was originally written in 2004 and since it was first published the controversy it generated has led to class action law suits against EA, as well a shedding light on what appears to be a commen trend within the gaming industry.</p>
<p>She describes what her family has to endure as her spouse is forced to work in excess of 85 hours a week for months on end, or in her own words:</p>
<blockquote><p>Every step of the way, the project remained on schedule. Crunching neither accelerated this nor slowed it down; its effect on the actual product was not measurable. The extended hours were deliberate and planned; the management knew what they were doing as they did it. The love of my life comes home late at night complaining of a headache that will not go away and a chronically upset stomach, and my happy supportive smile is running out</p></blockquote>
<p>It&#8217;s a heart wrenching expose that both captivates and evokes an extremely emotional response in you as you read it. As she laments the forced hours without any overtime or compensation, or even time off for employees you cant help but feel sickened. I had to put the book down and walk away for a moment when she wrote:</p>
<blockquote><p>&#8220;If they don&#8217;t like it, they can work someplace else.&#8221; Put up or shut up and leave: this is the core of EA&#8217;s Human Resources policy. The concept of ethics or compassion or even intelligence with regard to getting the most out of one&#8217;s workforce never enters the equation:</p></blockquote>
<p>Like anyone in the software industry you accept that you do have to work long hours sometimes as deadlines begin to loom, most of the developers that I have known dont mind this, but commonsense alone should tell us that this should always be the exception &#8211; never the norm. Ultimately it&#8217;s un-sustainable. We&#8217;re all human beings, we have lives outside of our work, other interests to persue, other dreams to achieve. ea_spouse ends her account with this &#8230;</p>
<blockquote><p>&#8230;when you keep our husbands and wives and children in the office for ninety hours a week, sending them home exhausted and numb and frustrated with their lives, it&#8217;s not just them you&#8217;re hurting, but everyone around them, everyone who loves them? When you make your profit calculations and your cost analyses, you know that a great measure of that cost is being paid in raw human dignity, right?</p></blockquote>
<p>Before joining Talis I used to work for an organisation, where I did clock up close to 70 hours a week for sustained periods. Of course no-one actually forces you, your just left to wander if you want the stigma of being labelled <em>not a team player</em>. I can only comment from my own perspective but I have no doubt that much of the apathy, cynicism and even contempt I had for the industry was a product of just how soul destroying it is to wake up, go to work, come home, sleep for a little and then wake up and go to work again. Your depressed, your constantly tired, your irratable, you become less and less attentive &#8230; to the point where you dont even sense someone running up behind you with a lead bar!</p>
<p>But what doesnt kill you, generally makes you stronger &#8230; at least thats something I try to believe. As I Read ea_spouse&#8217;s account, and thought about my own experiences as a developer working extended hours for sustained periods, I was immediatly able to contrast that with what things are like now.</p>
<p>For me Talis is a very different kind of environment to work in as a developer. I dont know whether its because we&#8217;ve embraced agile methodologies that are based around the principle of sustainable iterations of work, or whether its because the people I work with and work for genuinley care about the wellbeing of every member of the team. Or as I suspect its probably a combination of both. Our iterations in Skywalk are weekly, the small team on average completes around 15 units of work per week (our velocity &#8211; dont ask me to define what our units represent &#8230; I always quote my estimates in donuts! <img src='http://www.virtualchaos.co.uk/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ), but I recall how our programme lead reacted a few months ago when the team over a couple of iterations  averaged twice to three times that figure.</p>
<p>Our programme lead on skywalk, <a href="http://iandavis.com/blog">Ian Davis</a>, is probably one of the finest programme mangers I have ever worked with. Probably because he doesnt think of himself as a programme manager. He&#8217;s extremely goal driven and yet a humanist who puts the well being of his team before anything else. As a team leader he&#8217;s a <a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/sr=8-1/qid=1166277143/ref=pd_bbs_sr_1/102-3850960-5008160?ie=UTF8&#038;s=books">pragmatist</a>,  but it&#8217;s his charm and his passion that has helped bring together bunch of talented geeks and focused them into a team in every sense of the word. Anyway a few months back our velocity shot up, we were coming to the end of the development on a research prototype we call, Cenote, we wanted to have the piece up and running so <a href="http://paulmiller.typepad.com/thinking_about_the_future/">Paul</a> could show off some of our achievements at a conference in Canada. There wasnt a real requirement for the prototype to be made available, it was always a nice to have. But the team wanted to showcase its work, we take a great deal of pride in what we do. Ian was on vacation and in his absence we simply plowed on got it all done and delivered. When he came back and checked our velocity, he was appreciative yet told us that he didnt want us to make a habit of that because it wasnt sustainable. He then planned our next iteration to be around half our normal average velocity on the grounds that he wanted to make sure we all got a bit of rest. I&#8217;d never known a programme manager to react like that &#8230; or for a company to let him.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Books" rel="tag">Books</a>, <a class="tag_technorati" href="http://technorati.com/tag/Personal" rel="tag">Personal</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/12/16/ea_spouse-profit-at-the-cost-of-human-dignity/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Outsourcing developers abroad &#8230; Do people still really think its a good idea?</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/12/13/outsourcing-developers-abroad-is-it-really-a-good-idea/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/12/13/outsourcing-developers-abroad-is-it-really-a-good-idea/#comments</comments>
		<pubDate>Wed, 13 Dec 2006 10:06:53 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/12/13/outsourcing-developers-abroad-is-it-really-a-good-idea/</guid>
		<description><![CDATA[Had an interesting evening went to the gym and ran into an old friend I&#8217;ve not seen in a few years. We sparred for a bit (its a guy thing &#8230; guess we wanted to see which of us had improved the most since our last &#8230; encounter &#8230; it was me of course not [...]]]></description>
			<content:encoded><![CDATA[<p>Had an interesting evening went to the gym and ran into an old friend I&#8217;ve not seen in a few years. We sparred for a bit (its a guy thing &#8230; guess we wanted to see which of us had improved the most since our last &#8230; encounter &#8230; it was me of course not that I&#8217;m insanely competitive &#8230; honest!)</p>
<p>Anyway afterwards we went to to grab a bite to eat and catch up on what we&#8217;ve both been up to. We both work in the IT industry and love development  but we tend to have differing views on a lot of things ( Listen J were not starting the Java vs .NET argument on my blog if you do I&#8217;ll really kick your &#8230;.). Anyway J and I both used to work for the same company and the senior management of that organisation has recently announced that its going to outsource the development of some its long term projects overseas to India, citing that engineering talent over there is cheap and thus far more cost effective &#8230; but they intend to run the projects from over here. As a result my friend, like many of his colleagues are obviously worried about their futures and whether the company will want to retain their services as developers for much longer. Anyway this kind of got me thinking &#8230;</p>
<p>I&#8217;m not going to pay credence to any of those boorish, tired and lamentable arguments about how its morally wrong to take UK jobs and hand them to people overseas. The fact is we live in a global economy and we have to accept that we need to remain competitive in that economy. Besides I believe that kind of xenophobia generally tends to cloud the issue and overshadow far more important reasons as to why outsourcing is a bad idea for our industry.</p>
<p>I remember towards the tail end of the 90&#8217;s when venture capitalists where really pushing the idea of outsourcing development to places like China and India it&#8217;s cheaper, more cost effective and will help the organisations overall operational effectiveness. I&#8217;m of the opinion that this was generally because they looked at other industries where that model worked really well, I guess what they thought was if Matel can manufacture toys abroad cheaper, why cant we get software written abroad cheaper, right? Lots of large firms bought into this thinking Oracle and Hewlett Packard are just two examples of companies that followed this trend &#8230; only to slowly distance themselves after encountering the problems I touch upon below.</p>
<p>The problem though, is that writing code isn&#8217;t something you can translate into an assembly line. What I think the people pushing this type of outsourcing failed to comprehend, and seemingly still dont understand is that farming out development overseas doesn&#8217;t lead to innovation. The idea that you get a a large group of programmers together and they&#8217;ll just produce cool code &#8211; doesn&#8217;t work! I remember at university I did an elective in post-war Japanese history (wish I could tell you that I did this cos it was interesting but the truth was the lecturer was the hottest chick I&#8217;d ever &#8230;*off daydreaming*), anyway one of the things we were taught was that the japanese rebuilt their economy around their manufacturing industry, using automated methods of production and rigourous quality control. Through all of this they actually revolutionised manufacturing industry globally the effects of which are still being seen today.</p>
<p>Towards the end of the seventies and into the eighties Japanese companies tried to set up <em>software factories</em> where they basically got a shed load of developers together and tried to apply their tried and tested manufacturing experience to writing software &#8230; they failed miserably and learnt that putting loads of developers together doesn&#8217;t create innovative software. The reason is that writing software isn&#8217;t something that translates into a purely mechanical activity &#8211; like making a toy or a car. So none of their tried and tested rules applied.</p>
<p>Someone famously once said <em>every line of code is a design decision</em>, I&#8217;m struggling to remember who it was [insert clever guys name here]. But that single statement embodies for me what the real problem is with outsourcing projects abroad. You loose sight of the decisions that the developers are making as they piece together the product from your requirements. Farming out to developers overseas successfully means you have to pay meticulous attention to the details of what is being produced, and that&#8217;s damn difficult when you factor in communication problems, cultural differences and attitudes, and like it or not glaringly obvious fact that this model makes it difficult to be flexible or be able to react quickly to changes in your market place.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Personal" rel="tag">Personal</a>, <a class="tag_technorati" href="http://technorati.com/tag/Technology" rel="tag">Technology</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/12/13/outsourcing-developers-abroad-is-it-really-a-good-idea/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What does Simplicity mean when it comes to software?</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/12/11/what-does-simplicity-mean-when-it-comes-to-software/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/12/11/what-does-simplicity-mean-when-it-comes-to-software/#comments</comments>
		<pubDate>Mon, 11 Dec 2006 11:01:14 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/12/11/what-does-simplicity-mean-when-it-comes-to-software/</guid>
		<description><![CDATA[Our geek bookclub at Talis has been reading 37Signals Getting Real. It&#8217;s interesting text that contains for the most part a common sense advice with which we as a group can relate to. But one of the things thats been grating on my mind for a while now is the notion that simplicity sells, and [...]]]></description>
			<content:encoded><![CDATA[<p>Our geek bookclub at Talis has been reading <a href="https://gettingreal.37signals.com/">37Signals Getting Real</a>. It&#8217;s interesting text that contains for the most part a common sense advice with which we as a group can relate to. But one of the things thats been grating on my mind for a while now is the notion that simplicity sells, and by simplicity im referring to a <em>lack of features</em>. Unfortunatly whilst I was drafting this entry <a href="http://www.joelonsoftware.com/items/2006/12/09.html">Joel got there first</a> <img src='http://www.virtualchaos.co.uk/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ( <a href="http://windowslivewriter.spaces.live.com/">LiveWriter </a>is excellent for offline editing of blog entries, unfortunatly it doesnt stop you getting pipped to the post!)</p>
<p>Anyway its well worth reading Joel&#8217;s post, I think hes absolutely right in pointing out that <em>a lack of features</em> isnt what made the iPod or BaseCamp such a success but the fact that amongst other attributes both these products were built to correspond to a user model that resulted in a high degree of usability. To my mind the problem we face in this industry is that in order to build useable systems we need to accept that we can only do that by understanding the users mental model, we can no longer afford to build software solutions as simply the delivery of a set of discrete requirements and leave usability as something we can bolt on at the end when we&#8217;ve got the rest of the system working. We have to understand our users and put them first.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Usability" rel="tag">Usability</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/12/11/what-does-simplicity-mean-when-it-comes-to-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programmers are generally bad at user interface design?</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/12/05/programmers-are-generally-bad-at-user-interface-design/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/12/05/programmers-are-generally-bad-at-user-interface-design/#comments</comments>
		<pubDate>Tue, 05 Dec 2006 13:39:16 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Talis]]></category>
		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/12/05/programmers-are-generally-bad-at-user-interface-design/</guid>
		<description><![CDATA[Was intrigued when I read James O&#8217; Coplien latest blog entry: The interface is the Program, and it ain&#8217;t Agile. Coplien discusses, quite correctly I believe,  the fact that historically developers have tended to be very bad at building good user interfaces. Coplien discusses this in the context of Agile development groups and how [...]]]></description>
			<content:encoded><![CDATA[<p>Was intrigued when I read James O&#8217; Coplien latest blog entry: <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=187211">The interface is the Program, and it ain&#8217;t Agile</a>. Coplien discusses, quite correctly I believe,  the fact that historically developers have tended to be very bad at building good user interfaces. Coplien discusses this in the context of Agile development groups and how usability is rarely captured as a story because stories in themselves are generally short-term goals that you want to achieve in the space of an iteration or even a sprint. Therefore because Agile teams are rapidly making changes to their application its hard to be able to do the focussed studies and analysis that is required in order to gain an understanding of how useable the application your building is. Fundementally programmers are not User Interface designers &#8211; Coplien attributes this to several reasons,  which include the fact that  university courses on software engineering have often done little more than pay lip service to HCI or User Interface Design, its often a topic that undergraduates are only ever given the most basic of introductions to.</p>
<p>I want to expand a little on what Coplien has covered so well &#8230;</p>
<p>I&#8217;ve been fortunate enough to have worked closely with Alan Dix and Russell Beale, the authors of <a href="http://www.hcibook.com">Human Computer Interaction</a>. I do class myself as a developer but I have had a strong interest in HCI, and user interface design and its an area I&#8217;ve been interested in and reading around for the best part of a decade. In that time I&#8217;ve often had to work in teams where its apparent that other developers dont either understand the need for HCI, or even how to begin to think about it.</p>
<p>In my own experience this comes from the fact that programmers tend to focus on the mechanics of building an interface, getting the right framework, and then designing around the limitations of the toolset they have picked. Invariably they tend to spend tonnes of time  just focusing on getting the UI to work and this UI is designed from the perspective of satisfying the flows defined in requirements documents or design docs like Use Cases.  You can contrast this with people trying to use the user interface, who dont care how it was built, or what the limitations in the underlying technologies were, these people just want something they can use.  To me its this emphasis that seperates a working interface from a &#8220;good&#8221; user interface.   Good User Interface are designed around the user, unfortunatly most user interfaces tend to be designed around building something that satisfies a series of discrete requirements.</p>
<p>I dont think it&#8217;s fair to simply say that programmers arent capable and can&#8217;t do good UI design, the truth is that on most software projects, and in most teams, it just isnt their emphasis.</p>
<p>In order to improve things developers need to be taught the importance of user interface design. Our development group at Talis is a great example of this. As a team we know we need get better at understanding how to build user interfaces. One of the activities we undertook recently was to get everyone to read Spolsky&#8217;s <a href="http://www.amazon.co.uk/User-Interface-Design-Programmers-Spolsky/dp/1893115941/sr=11-1/qid=1165325169/ref=sr_11_1/202-6925235-0126235">User Interface Design for Programmers</a> as part of our geek book club. It&#8217;s an excellent text that introduces programmers to key concepts in user interface design.</p>
<p>However as more and more applications are being delivered over the web developers should take the time to read Jakob Nielsen&#8217;s seminal text <a href="http://www.amazon.co.uk/Designing-Web-Usability-Practice-Simplicity/dp/156205810X/sr=1-1/qid=1165325484/ref=sr_1_1/202-6925235-0126235?ie=UTF8&#038;s=books">Designing Web Usability &#8211; The practice of Simplicity</a>. Bruce Tognazzini&#8217;s <a href="http://www.amazon.co.uk/Tog-Interface-Bruce-Tognazzini/dp/0201608421/sr=11-1/qid=1165325736/ref=sr_11_1/202-6925235-0126235">TOG on Interface</a>, might be a little dated but its still an incredibly good text and has a great section on conceptual models.</p>
<p>Most importantly though: one of the things our group has realised is that User Interface Design and User Interaction Design are specialised skills, and whilst its important that developers should be encouraged to learn more about this area, its vitally important that organisations recruit people with these specialised skills into their teams. To that end Talis is openly recruiting for individuals who specialise in HCI/User Interface Design, so if you think you fit the bill and its an area your passionate about, and you&#8217;d like to work for an organisation that takes this very seriously then check out the job spec <a title="HCI Job Spec" href="http://www.talis.com/about_talis/careers/documents/HCIUserInterfacedesigner131006.doc">here</a> and send your CV along with a covering letter to <a href="mailto:team.talent@talis.com">team.talent@talis.com</a>.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>, <a class="tag_technorati" href="http://technorati.com/tag/Usability" rel="tag">Usability</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/12/05/programmers-are-generally-bad-at-user-interface-design/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Providing estimates for building software</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/12/03/providing-reliable-estimates-for-building-software/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/12/03/providing-reliable-estimates-for-building-software/#comments</comments>
		<pubDate>Sun, 03 Dec 2006 00:30:09 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Talis]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/12/03/providing-reliable-estimates-for-building-software/</guid>
		<description><![CDATA[James Shore is currently working on his book &#8211; The Art of Agile Development. For a while now Shore has been posting up pre-publication review chapters from this upcoming book. The latest section up for review covers the topic of Estimation, and its well worth reading.
This chapter really resonates with me since parts of it [...]]]></description>
			<content:encoded><![CDATA[<p>James Shore is currently working on his book &#8211; <em>The Art of Agile Development</em>. For a while now Shore has been posting up pre-publication review chapters from this upcoming book. The latest section up for review covers the topic of <a title="James Shore - Estimating" href="http://www.jamesshore.com/Agile-Book/estimating.html">Estimation</a>, and its well worth reading.</p>
<p>This chapter really resonates with me since parts of it pretty much describe the approach to estimation we follow in our development group at <a href="http://www.talis.com/">Talis</a>. We estimate how much effort it would take to complete indiviual stories. Our iterations last a week. At the beginning of each week we total up our velocity for the previous week, for example 16, and then select 16 units worth of work for the coming iteration. If we repeatedly hit our target over the course of a couple of iterations then as a group we might pick more than our velocity for the following iteration.  All the members of the development team take participate in the estimation, this ensures that everyone is &#8220;<em>bought-into</em>&#8221; the plan.  This approach leads to better communication and can help clarify requirements it also engenders greater trust within the team.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/12/03/providing-reliable-estimates-for-building-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gordon Ramsay could teach software engineers a thing or two?</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/11/30/gordon-ramsay-could-teach-software-engineers-a-thing-or-two/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/11/30/gordon-ramsay-could-teach-software-engineers-a-thing-or-two/#comments</comments>
		<pubDate>Thu, 30 Nov 2006 10:38:02 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Talis]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/11/30/gordon-ramsay-could-teach-software-engineers-a-thing-or-two/</guid>
		<description><![CDATA[Rob and I took a coffee break from refactoring some code yesterday and he asked me if I had watched Ramsay&#8217;s Kitchen Nightmares the night before, which I had! We commented on how formulaic the show is &#8211; each episode Ramsay turns up at the door of an ailing restaurant, and helps get them back [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dynamicorange.com/blog/">Rob</a> and I took a coffee break from refactoring some code yesterday and he asked me if I had watched <em>Ramsay&#8217;s Kitchen Nightmares</em> the night before, which I had! We commented on how formulaic the show is &#8211; each episode Ramsay turns up at the door of an ailing restaurant, and helps get them back on track and making money by empowering and motivating the cooks, using fresh ingredients, coming up with a simple less complicated menu, keeping management out of the kitchen and in the front where they belong, and above all putting the customer first!! Rob then said something along the lines of &#8220;<em>You know when you think about it its not too different to the problems that many other software engineering firms face</em>&#8220;.  That&#8217;s when the penny dropped &#8230;</p>
<p>As a metaphor this should sound familiar to anyone working on a large ( even not so large ) software project. Your coders are the equivalent of your kitchen brigade, guys and girls who have to deliver, without them you cant serve anything to your customers. Your ingredients are API&#8217;s, frameworks, and technologies. Your complicated menu&#8217;s are over analysed, over designed, and over complicated software architectures; and lets not forget your restaurant managers are the same as your project managers, who generally know sod all about writing code, they promise your customers everything under the sun, generally work their brigade to death to deliver to unrealistic time frames and have a penchant for blaming the coders when it all goes tits up!</p>
<p>Worst of all the customer rarely gets what he or she actually ordered, because so many software company&#8217;s still persist on following dated project management and development methodologies trying to gather requirements up front, do exhaustive analysis and design then coding, and finally delivering a system 12 months later to a customer who&#8217;s requirements have now changed.</p>
<p>Did I sound bitter then? It&#8217;s probably because I realise that I&#8217;ve spent the better part of a decade working for the kinds of software companies where this kind of thing is considered the norm. Sadly for many company&#8217;s it still is the norm!</p>
<p>So lets apply the Ramsay formula to this. How do you turn teams that are building software in the manner above around?</p>
<p><u>Firstly, you have to empower your brigade</u>. In the past I&#8217;ve worked in places where the job of most developers is simply to &#8220;fill-in-the-blanks&#8221;&#8230; in other words just implement method stubs that are generated by a design tool that the architects use. This creates hierarchical divisions within teams, and is generally extremely de-motivating. Like a cook who has given up using his imagination, has no passion, and has given up thinking creatively and has been reduced to doing little more than reheating pre-cooked frozen hash.</p>
<p>In order to empower the team, they need to OWN the code collectively. It doesn&#8217;t belong to one person, it belongs to everyone. As a team they&#8217;re passionate about it. You have to be break people out of the traditional thinking that <em>I wrote this class so people have to check with me if they want to change it! </em></p>
<p><u>We need &#8220;<em>fresh</em>&#8221; ingredients</u>. Yes we should re-use software but only if its appropriate. How many times have you worked on software projects where the architecture isn&#8217;t based on whether its the right technology or tool for the job, but is based on other factors like the company you work for has a cool licensing agreement with a vendor and wants to use their technology because they don&#8217;t have to fork out for something more appropriate? This, using a square-peg to fill a round hole approach, in variably leads to difficulties.</p>
<p><u>Have &#8220;<em>simpler menus&#8221;!</em> </u>We need to get rid of up-front complicated over-architected designs, and over analysing solutions &#8211; which are a product of old-style waterfall approaches. Teams need to be moving towards iterative, agile development methodologies. These processes <em>engage</em> the customers who are able to provide feedback on the product at the end of each iteration so this approach to developing software <em>encourages</em> customers to change their requirements if and when they want to which means that when you finally deliver &#8230; your actually giving them what they want! And this squarely <em><u>puts the customer first</u></em>!</p>
<p><u><em>Keep management out of the kitchen</em></u>. If your the kind of organisation willing to invest in bringing a smart bunch of technical people together, then trust them to do their job. They don&#8217;t need project managers standing over their shoulders asking them for an hourly update on their progress. This kind of Orwellian micro-management is culturally ingrained into some large software companies and in my opinion it is very, very damaging. It fosters resentment, encourages bullying and totally de-motivates developers because of the perpetual monkey on their backs!</p>
<p>I am so glad im not working for an organisation that suffers from these problems, and perhaps if you are then maybe you should consider a change?</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Personal" rel="tag">Personal</a>, <a class="tag_technorati" href="http://technorati.com/tag/Talis" rel="tag">Talis</a>, <a class="tag_technorati" href="http://technorati.com/tag/Technology" rel="tag">Technology</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/11/30/gordon-ramsay-could-teach-software-engineers-a-thing-or-two/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Buildix &#8211; KNOPPIX Based Linux Distro</title>
		<link>http://www.virtualchaos.co.uk/blog/2006/11/26/buildix-knoppix-based-linux-distro/</link>
		<comments>http://www.virtualchaos.co.uk/blog/2006/11/26/buildix-knoppix-based-linux-distro/#comments</comments>
		<pubDate>Sun, 26 Nov 2006 17:24:14 +0000</pubDate>
		<dc:creator>nadeem.shabir</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.virtualchaos.co.uk/blog/2006/11/26/buildix-knoppix-based-linux-distro/</guid>
		<description><![CDATA[Heard about this on a Google tech talk, its a linux distro distributed as an rpm or VM ( which I have downloaded ), it provides a pre configured install of CruiseControl, Trac and Subversion &#8230;
Martin Fowler mentions it on his site, obviously hes recommending it because of his involvement with thoughtworks. Nevertheless its a [...]]]></description>
			<content:encoded><![CDATA[<p>Heard about <a href="http://buildix.thoughtworks.com/">this</a> on a Google tech talk, its a linux distro distributed as an rpm or VM ( which I have downloaded ), it provides a pre configured install of CruiseControl, Trac and Subversion &#8230;</p>
<p>Martin Fowler mentions it on his <a href="http://www.martinfowler.com/bliki/Buildix.html">site</a>, obviously hes recommending it because of his involvement with thoughtworks. Nevertheless its a great idea, based around shortening iteration zero.</p>
<p>There&#8217;s a good <a href="http://juliansimpson.blogspot.com/2006/07/more-on-why-we-made-buildix.html">blog</a> by one of the &#8220;authors&#8221; describing why they made this, which is well worth reading.</p>
<p>I&#8217;ve found it easy to use and configure and it gives a great head start to project teams trying to get continuous integration environments set up.</p>

	<a class="tag_technorati" href="http://technorati.com/tag/Agile" rel="tag">Agile</a>, <a class="tag_technorati" href="http://technorati.com/tag/Continuous+Integration" rel="tag">Continuous Integration</a>, <a class="tag_technorati" href="http://technorati.com/tag/Linux" rel="tag">Linux</a>
]]></content:encoded>
			<wfw:commentRss>http://www.virtualchaos.co.uk/blog/2006/11/26/buildix-knoppix-based-linux-distro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
