<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;D0ICQn09fip7ImA9WhRUEEs.&quot;"><id>tag:blogger.com,1999:blog-10896391</id><updated>2012-01-20T13:19:23.366Z</updated><category term="mocks" /><category term="test coverage" /><category term="Pomodoro" /><category term="kata" /><category term="git vim" /><category term="Bdd xp-manchester" /><category term="seo-unfriendly" /><category term="macbookpro" /><category term="metaphor" /><category term="community" /><category term="rewrite" /><category term="c#" /><category term="crap code" /><category term="encryption" /><category term="TDD" /><category term="agile" /><category term="git" /><category term="survey" /><category term="self-improvement" /><category term="frustration" /><category term="code" /><category term="productivity" /><category term="recruitment" /><category term="Bdd" /><category term="rant" /><category term="xp-manchester" /><category term="assert" /><category term="abstract" /><category term="lean" /><category term="specification" /><category term="Pair-Programming" /><category term="community ddd8 conference" /><category term="refactoring" /><category term="speaking" /><category term="Metrolink" /><category term="security" /><category term="mstest" /><category term="c" /><category term="recruitment rant" /><category term="parallels" /><category term="rewrite dddsw" /><category term="msc" /><category term="xp values" /><category term="sql" /><category term="VS2010" /><category term="tilde" /><category term="elegance" /><category term="readability" /><category term="testing" /><category term="gotcha" /><category term="unit-test" /><title>Johnno's Nose</title><subtitle type="html">A blog about me and my development journey.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>47</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/JohnnosNose" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="johnnosnose" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0ICQn08eip7ImA9WhRUEEs.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-2593748322956840386</id><published>2012-01-20T13:19:00.000Z</published><updated>2012-01-20T13:19:23.372Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-20T13:19:23.372Z</app:edited><title>Metrolink: Highlights from the passenger's charter</title><content type="html">The top web search result for "Metrolink Complaints" brings back 
&lt;a href="http://www.metrolink.co.uk/pdf/Passenger_Charter_Metrolink.pdf"&gt;Passenger Charter&lt;/a&gt; last updated in 2008 it has some encouraging quotes.
All emphasis is my own.
&lt;blockquote&gt;
The vision behind the Metrolink system is to provide a safe, efficient 
environmentally friendly and reliable tram system for Greater Manchester 
that will integrate with other transport modes and fulfill the aspirations of 
the Passenger Transport Authority.
&lt;/blockquote&gt;
&lt;blockquote&gt;
Advance information on planned disruptions to service will be made
available as soon as practically possible in advance. Information will be 
prominently displayed at all stops. We will always  endeavour to  minimise
passenger disruption to services.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;b&gt;We want all passengers to have a trouble free journey&lt;/b&gt; and therefore ask 
you to consider the needs of your fellow passengers at all times. &lt;/blockquote&gt;
&lt;blockquote&gt;
We will continue to aim for improved standards of punctuality and
reliability. &lt;b&gt;We will publish our reliability and punctuality figures set against 
agreed target levels at Metrolink stops every four weeks&lt;/b&gt;. These figures will 
be independently advised every year.&lt;/blockquote&gt;
&lt;blockquote&gt;We will provide real time information about our services by means of 
public address systems and information screens.&lt;/blockquote&gt;
How many of screens actually work? 
&lt;blockquote&gt;We  recognise that passengers want to know what is happening when 
things go wrong. Our staff on trams and on the Metrolink system will help 
by providing as much information as they can to passengers. &lt;/blockquote&gt;
&lt;blockquote&gt;For comments or complaints regarding general operation, maintenance 
and cleanliness of the Metrolink system, passengers should contact 
&lt;b&gt;Stagecoach&lt;/b&gt;’s Customer Service team. For issues relating to policy, for 
example fares and future Metrolink expansion, passengers should contact 
GMPTE’s Customer Relations department.&lt;/blockquote&gt;
Note Stagecoach do not run the service anymore.
&lt;blockquote&gt;If you have a complaint, we want to find out what went wrong and put it 
right for the future.&lt;/blockquote&gt;
&lt;blockquote&gt;Senior managers carefully monitor the number and type of comments we 
receive. We will use this information to improve our service in the future. &lt;/blockquote&gt;

This is my favourite

&lt;blockquote&gt;&lt;b&gt;We do our best to give you the service you have the right to expect. Our 
aim is to provide customer satisfaction by improving our services in
response to your comments.&lt;/b&gt;&lt;/blockquote&gt;


&lt;blockquote&gt;
We will always do our best to satisfy all complaints. If you still wish to take the 
matter further you can refer it to your local Passenger Focus Group, an 
independent public body set up by the Government to protect the interests of 
Britain's rail passengers. They are funded by the Department for Transport but 
their independence is guaranteed by an act of Parliament.  They use their 
knowledge to influence decisions on behalf of rail passengers and work with the 
rail industry, other passenger groups and government to secure journey 
improvements.
The address for Passenger Focus in the area served by Metrolink is: 
Passenger Focus
9th Floor
Store Street
Manchester
M1 2RP
Tel: 0870 336 6095
Fax: 0161 244 5981&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-2593748322956840386?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0gjx9kyMB7hLyhccCXJxNQPv3TA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0gjx9kyMB7hLyhccCXJxNQPv3TA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0gjx9kyMB7hLyhccCXJxNQPv3TA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0gjx9kyMB7hLyhccCXJxNQPv3TA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/2593748322956840386/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=2593748322956840386" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/2593748322956840386?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/2593748322956840386?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2012/01/metrolink-highlights-from-passengers.html" title="Metrolink: Highlights from the passenger's charter" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Ck4FRHg9eyp7ImA9WhRVGUo.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-6227649079010905661</id><published>2012-01-18T21:42:00.002Z</published><updated>2012-01-19T11:01:55.663Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-19T11:01:55.663Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Metrolink" /><title>Manchester's Metrolink: An utter disgrace.</title><content type="html">&lt;i style="font-family: Arial, sans-serif; font-size: small;"&gt;Regular reader. Sorry not a software topic just wanted to get some thoughts out.&lt;/i&gt;&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://desmond.yfrog.com/Himg614/scaled.php?tn=0&amp;amp;server=614&amp;amp;filename=7o8pcx.jpg&amp;amp;xsize=640&amp;amp;ysize=640" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;img border="0" height="320" src="http://desmond.yfrog.com/Himg614/scaled.php?tn=0&amp;amp;server=614&amp;amp;filename=7o8pcx.jpg&amp;amp;xsize=640&amp;amp;ysize=640" width="191" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;This morning's delayed tram&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
I love public transport. It's brilliant. Instead of crawling along in rush hour traffic, getting cramp in my foot as I leave the clutch at biting point I get to have a nice walk to the local public transport stop(healthy), stare vacantly into space as I wait for my carriage to arrive (meditative) and then I take a short journey where I read my book to somewhere vaguely near my destination (educational). Then I take a further walk and I'm there(even healthier). Or that's the idea.

It's not quite working out that way. You see I use Manchester's Metrolink.&lt;br /&gt;
Metrolink is a light railway system that spans the city. When it was created it filled the need for better transport links from Bury and Altrincham to the city centre. I remember travelling on the Altrincham line for the first time. It was quick, clean and efficient. Sure there were some problems but my co-workers who used the system didn't seem to be affected too adversley. I don't know what's happened but things have got worse, much worse. I've been a commuter on the Altrincham line for 4 years and the service has degraded to such an extent that I feel that the people of Greater Manchester need answers from those who run the system.

So why do I feel angry?&lt;br /&gt;
&lt;b style="font-family: Arial, sans-serif; font-size: small;"&gt;Price hikes.&lt;/b&gt;&lt;br /&gt;
On January 3rd prices across the system were &lt;a href="http://www.bbc.co.uk/news/uk-england-manchester-11612792" target="_blank"&gt;increased on average by 6%&lt;/a&gt; &amp;nbsp;This price raise was described by the media as &lt;a href="http://menmedia.co.uk/manchestereveningnews/news/transport/public_transport/s/1469101_price-of-metrolink-tram-tickets-to-rise-by-up-to-nine-per-cent-in-new-year" target="_blank"&gt;'Inflation busting'&amp;nbsp;&lt;/a&gt;&lt;br /&gt;
This irks me on two points. I thought the point of public transport was to provide cheap, quick, links across the city to stimulate the economy, and ease the burden on the roads. What instead has happened is that by raising prices potential commuters are driven away from using the Metrolink in favour of driving or just not bothering. This price hike has been introduced at the same time as Manchester city centre&amp;nbsp;&lt;a href="http://menmedia.co.uk/manchestereveningnews/news/s/1425210_motorists-hit-by-sunday-parking-charges-for-manchester-city-centre-bays-in-1m-funding-drive-by-council-" target="_blank"&gt;begins to charge cars to park on a Sunday.&lt;/a&gt;&lt;br /&gt;
Its a 'double whammy' for Manchester residents and plays into the hands of places like the Trafford Centre which provides much better parking facilities and although there's not a Metrolink there, a reasonably efficient bus service.&lt;br /&gt;
&lt;b style="font-family: Arial, sans-serif; font-size: small;"&gt;Poor service.&lt;/b&gt;&lt;br /&gt;
Since the price increase I have made 26 commuter time journeys. Of those journeys, 6 &amp;nbsp;of them have had some form of disruption. That's 23% of my commuting journeys have had delays. In the last 2 days 100% of my journeys have been delayed. I'm writing this after spending 76 minutes on the tram (a normal jourey tkes 20 mins).&lt;br /&gt;
&lt;b style="font-family: Arial, sans-serif; font-size: small;"&gt;Tonight's Journey.&lt;/b&gt;&lt;br /&gt;
This particular journey was so farcical it beggar's belief. I was travelling from Altrincham to Piccadilly to get to an event starting at 6.30. I buy a return ticket from Altrincham (more on this later)at 17.33. As soon as I set down the driver reports over the tannoy that there is a failed vehicle in the city centre and the line is suspended. Most people leave the tram, an angry few commutters are talking to the driver. I can just hear him and I'm sure he says that we shouldn't ring up to complain because that will just tie up the people trying to sort the problem out. I chance it and decide to wait - buses from Altrincham crawl up the A56 and to be fair Metrolink normally sort it within 20 mins and I've bought a ticket. After 10 mins or so the tram then starts moving. We are informed that the service will stop at Deansgate-Castlefield&lt;br /&gt;
Altrincham is at the end of the line and just before the stop before (Navigation Road) the track becomes single file. There is signal where trams have to wait for the other to pass. Our tram pootles to there and then doesn't move for 10 mins. The driver then informs us that the he can't contact Network Rail to get the signal changed. We wait for what seems like another 10 minutes the driver then informs good news - the service will continue to Piccadilly. Unfortunately neither he or the control room can get the signal changed. Minutes pass and eventually we move. The driver apologies once again.&amp;nbsp; &lt;br /&gt;
We begin thundering up the line. Angry commuters squeeze on and off &amp;nbsp;at Timperley, Sale, Dane Road, Stretford and Old Trafford but at least the thing is moving. &amp;nbsp;We then stop just past Old Trafford. There's always a delay now between Old Trafford and Trafford Bar as the Chorlton line joins the Altrincham one. This delay seems to take longer than normal thought, it couldn't be ano... The driver comes on the tannoy. "Sorry blah ... blah... there's been a backup of all the trams trying to get through Cornbrook. We're just waiting for our turn". Fair enough. (I look at my watch its 6.30. I'm now late.) &amp;nbsp;More minutes pass, I hear something over the driver's radio about telling customers of the Eccles &amp;amp; Chorlton lines that their tickets are valid on the buses. &amp;nbsp;Phew! I'm on the Altrincham line. Driver comes back on, apparently the computer system is overloaded at Cornbrook so they can't let us move. I am now officially livid. My normal stop, Trafford Bar, is 200 yards away and Old Trafford is about 100 yards away and I am stuck on a packed tram, missing my evening event and unable to move. 18.49, 1 hour and 16 mins later I arrive at Trafford Bar. I should be in Piccadilly Gardens, 20 mins ago. Do I risk it? Can Metrolink get me 4 stops closer? I didn't want to find out.&lt;br /&gt;
&lt;b style="font-family: Arial, sans-serif; font-size: small; line-height: 18px;"&gt;Dealing with delays on the Altrincham line.&lt;/b&gt;&lt;br /&gt;
I mainly travel between Trafford Bar and Altrincham. To catch up a common tactic of Metrolink is to terminate vehicles at Timperley so they can turn around. This means that commuters who want to go to Altrincham (read most of the people remaining) have to either wait or walk. Walking takes&amp;nbsp;&lt;a href="http://maps.google.co.uk/maps?saddr=Park+Rd%2FB5165&amp;amp;daddr=Stamford+New+Rd%2FA538&amp;amp;hl=en&amp;amp;sll=53.395946,-2.343349&amp;amp;sspn=0.018143,0.045447&amp;amp;geocode=FSDhLgMdpE_c_w%3BFb-iLgMd5Szc_w&amp;amp;vpsrc=0&amp;amp;dirflg=w&amp;amp;mra=ls&amp;amp;t=m&amp;amp;z=15" target="_blank"&gt;28 mins&lt;/a&gt;. If most people are getting off at Altrincham why can't the service terminate at Navigation Road, 10 mins walk&amp;nbsp;&lt;a href="http://maps.google.co.uk/maps?saddr=Park+Rd%2FB5165&amp;amp;daddr=Stamford+New+Rd%2FA538&amp;amp;hl=en&amp;amp;sll=53.395946,-2.343349&amp;amp;sspn=0.018143,0.045447&amp;amp;geocode=FSDhLgMdpE_c_w%3BFb-iLgMd5Szc_w&amp;amp;vpsrc=0&amp;amp;dirflg=w&amp;amp;mra=ls&amp;amp;t=m&amp;amp;z=15" target="_blank"&gt;away&lt;/a&gt;?&lt;br /&gt;
There are 3 places on the line where trams get delayed.&lt;br /&gt;
1) Between Altrincham &amp;amp; Navigation Road&lt;br /&gt;
2) Between Old Trafford &amp;amp; Trafford Bar.&lt;br /&gt;
3) Between Trafford Bar &amp;amp; Cornbrook &lt;br /&gt;
Why can't trams wait in the stations for signals to change? At least then the commuters can make a decision of whether to stay on or off.
&lt;b style="font-family: Arial, sans-serif; font-size: small; line-height: 18px;"&gt;Ticket inspectors over Safety Inspectors.&lt;/b&gt;&lt;br /&gt;
In a bid to reduce the number of fare dodgers there have been an increase in the number of safety officers. At one point I've been checked 3 times on a journey. At no point have&amp;nbsp;safety&amp;nbsp;officers been there to prevent the over-crowding that occurs or been there to provide&amp;nbsp;information&amp;nbsp;when a delay happens,&lt;br /&gt;
&lt;b style="font-family: Arial, sans-serif; font-size: small; line-height: 18px;"&gt;Poor ticket flexibility&lt;/b&gt;&lt;br /&gt;
Today I wanted to buy a ticket at Altrincham from Trafford Bar (where my season pass ends) to Piccadilly. So I have 2 options. I can either get off a Trafford Bar, buy a return from there and wait for the next tram or buy a full return from Altrincham. Today I spent £4.30 and gave up at Trafford Bar.&amp;nbsp;&lt;b&gt;I actually paid twice for this journey.&lt;/b&gt;&lt;br /&gt;
&lt;b style="font-family: Arial, sans-serif; font-size: small; line-height: 18px;"&gt;What the hell is going on?&lt;/b&gt;&lt;br /&gt;
It seems to be that this transport system is reeling from one cock-up to the next. I've had one person from my team at work leave due in part to the Metrolink commute. His train/tram season ticket was&amp;nbsp;accepted by most inspectors but then he got slapped with a £50 fine (for his first offence!). Poor information on the train system caused this.&lt;br /&gt;
&lt;br /&gt;
There's probably more I could haul out of the memory banks if I wanted to, such as the cock up of the wiring at Altrincham where you had to pay someone to stand there until someone ordered some sleeving because it was too close to the footbridge. I&amp;nbsp;think&amp;nbsp;you get the idea though.&amp;nbsp;&lt;b&gt;Metrolink is mismanaged and not fit for purpose&lt;/b&gt;.&lt;br /&gt;
I feel it's Metrolink's duty to explain its self and to sort it out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-6227649079010905661?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MTMDjkVa-hT56iVxYJcX-Guk2IM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MTMDjkVa-hT56iVxYJcX-Guk2IM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MTMDjkVa-hT56iVxYJcX-Guk2IM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MTMDjkVa-hT56iVxYJcX-Guk2IM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/6227649079010905661/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=6227649079010905661" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/6227649079010905661?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/6227649079010905661?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2012/01/manchesters-metrolink-utter-disgrace.html" title="Manchester's Metrolink: An utter disgrace." /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0UESHc9cCp7ImA9WhRQFE8.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-5121952554932315529</id><published>2011-12-09T09:00:00.000Z</published><updated>2011-12-09T09:00:09.968Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-09T09:00:09.968Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xp-manchester" /><category scheme="http://www.blogger.com/atom/ns#" term="metaphor" /><title>Metaphors in software</title><content type="html">Many Extreme Programming practices are now considered industry standard or at the very least 'worthy'.&lt;br /&gt;
The poor cousin of these is perhaps the idea of System Metaphor. The intention behind XP's System Metaphor practice is to have a common &lt;i&gt;"story that everyone – customers, programmers, and managers - can tell about how the system works." &lt;/i&gt;This story often is told in the language of the problem domain, there is no metaphor. (In XP terms this is known as a &lt;i&gt;naïve&lt;/i&gt; metaphor)&lt;br /&gt;
&lt;br /&gt;
It was my guess that most systems are developed without a system metaphor (or a naïve one). So I thought I'd do an in depth study.&lt;script src="http://twtpoll.com/js/ibadge.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;iframe frameborder="0" height="400" id="twpw_if" name="twpw_if" onload="TwtpwFm.registerFrame(this);" scrolling="no" src="http://twtpoll.com/badge/if/?twt=nrpjs4&amp;amp;r=1" width="100%"&gt;&amp;amp;lt;p&amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;Your browser doesn't support iFrames :( Vote for this poll &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a href="http://twtpoll.com/nrpjs4"  title="here" target="_blank"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;here&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;.&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt;&lt;/iframe&gt;&lt;br /&gt;
Less than 20% of devs use the system metaphor. The evidence is damming!&lt;br /&gt;
&lt;br /&gt;
So do we even care about the system metaphor as a practice. If 80% of developers haven't used a system metaphor why would you even bother? Are developers missing a trick?&lt;br /&gt;
&lt;span style="font-size: large;"&gt;A world without metaphors. &lt;/span&gt;&lt;br /&gt;
Metaphors are everywhere and in software land they are impossible to exist without. Why? Because the mechanics of what is actually happening is so far removed from what the typical user can communicate we need to abstract to understand anything. As a software dev, I don't want to have the overhead thinking about how the electrons fly around the computers, copper wires, through the air and I probably don't need to know too much how data gets from my HD into memory for example. Developers think at one level of abstraction, their clients work at another. The divide is there.. too often do stakeholders turn around and complain about the 'jargon' the developers use.&lt;br /&gt;
&lt;br /&gt;
So to allow the computer scientists to communicate with the devs they cooked up data structures. Think about the humble stack. &lt;br /&gt;
&lt;span style="font-size: large;"&gt;The stack datatype.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
A tangible stack&amp;nbsp; is a set of objects placed on top of each other. To get to an item you need to remove the items above it. The last item you put on the stack is the first item you need to deal with. Now the CS boffins who were dreaming up datastructures came up with a collection of memory locations that were also to be last one in, first out. They could have called it anything (like particle physicists up, down, strange, charm, anyone?) and I bet in CS world there were some scientists that just didn't get the Stack straight away? So what's the best way of explaining a concept? Describe it in terms that explainee underderstands.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/liopic/1871326475/" style="margin-left: 1em; margin-right: 1em;" title="Towers of Hanoi in the cooker by Julio Martinez, on Flickr"&gt;&lt;img alt="Towers of Hanoi in the cooker" height="400" src="http://farm3.static.flickr.com/2016/1871326475_859e614eee.jpg" width="266" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
A Stack data type is not vertically aligned. It has no physical dimensions. There are &lt;b&gt;holes &lt;/b&gt;in the metaphor. As far as I know most "real" stacks don't pop either but the concept is good enough to convey the concept of how the data structure is supposed to function.&lt;br /&gt;
&lt;br /&gt;
The stack is just one example and, to be fair, a stack is a very simple concept. But look around the computer/software world and metaphors are just flippin' everywhere.&lt;br /&gt;
&lt;br /&gt;
In Design Patterns&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;repository&lt;/li&gt;
&lt;li&gt;bridge&lt;/li&gt;
&lt;li&gt;adapter&lt;/li&gt;
&lt;li&gt;factory&lt;/li&gt;
&lt;li&gt;decorator&lt;/li&gt;
&lt;li&gt;flyweight&lt;/li&gt;
&lt;li&gt;mediator&lt;/li&gt;
&lt;li&gt;command&lt;/li&gt;
&lt;/ul&gt;In Software Concepts&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;error&lt;/li&gt;
&lt;li&gt;bug&lt;/li&gt;
&lt;li&gt;loop&lt;/li&gt;
&lt;li&gt;concrete class&lt;/li&gt;
&lt;li&gt;file&lt;/li&gt;
&lt;li&gt;queue&lt;/li&gt;
&lt;li&gt;peek&lt;/li&gt;
&lt;li&gt;poke&lt;/li&gt;
&lt;li&gt;pointer&lt;/li&gt;
&lt;li&gt;engine&lt;/li&gt;
&lt;li&gt;layer&lt;/li&gt;
&lt;li&gt;core&lt;/li&gt;
&lt;li&gt;service&lt;/li&gt;
&lt;li&gt;bus&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
In the os paradigm&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;file system&lt;/li&gt;
&lt;li&gt;folders&lt;/li&gt;
&lt;li&gt;recycle bin&lt;/li&gt;
&lt;li&gt;window &lt;/li&gt;
&lt;li&gt;lock&lt;/li&gt;
&lt;li&gt;desktop&lt;/li&gt;
&lt;li&gt;mail box&lt;/li&gt;
&lt;li&gt;firewall&lt;/li&gt;
&lt;/ul&gt;and that's just the first few. Human's are naturally disposed to use metaphor and simile to explain concepts. The relatively dry topic of software engineering is an ideal breeding ground for metaphors. Most concepts are abstract and have no physical tangibility - what choice do we have?&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
These aren't the sort of systems I build though. I build systems for businesses that help them streamline the business process. My systems have complexity. How can metaphors help us to construct these systems?&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;A Common Understanding&lt;/span&gt;&lt;br /&gt;
Imagine you have two sets of people. The first set are a crack programming unit, the second are a group of domain experts. Both are knowledge specialists in their field. The project cannot fail. But when the two sets talk its like one group are from Mars and the other Venus.&lt;br /&gt;
&lt;br /&gt;
You have the option of getting the Martians to speak Venusian or the Venusian's could learn Martian ways. The problem you may come across here is that it takes a lot to learn Martian well. And boy those Venusians lead complicated lives. They are completely alien to those Martians.&lt;br /&gt;
&lt;br /&gt;
There's a third option: imagine if both Martians and Venusians have been observing Earthlings for a while then perhaps they could describe their problems using Earthling ideas and Earthling idioms.&lt;br /&gt;
&amp;nbsp;(Earthlings as we know are simple creatures with well defined funny-little habits).&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;But metaphors are alien to me?&lt;/span&gt;&lt;br /&gt;
I suppose its quite disconcerting to not plump for the naive metaphor. It seems easy... but is it?&lt;br /&gt;
Naive metaphors are a one way street. The dev team may potentially know nothing about the domain it is going to work with. The stakeholders hold all the cards.&lt;br /&gt;
&lt;br /&gt;
In the short term it is probably easier for the delivery team to learn about the problem domain.&lt;br /&gt;
What can happen though is that there may be an incomplete transferral of knowledge to the delivery team. I suppose that this unlikely to be too much of a problem in an iterative project. Agile accepts that not everything will be right first time but that doesn't mean we should aim to close the iteration loops.&lt;br /&gt;
&lt;br /&gt;
By introducing a metaphor the knowledge holders have to 'think' about how their domain is relates&lt;br /&gt;
to the metaphor. Processes that are 'second nature' need to be be deliberately revisited and described not only in terms of the business stakeholders but in a shared and a discovered paradigm.&lt;br /&gt;
&lt;br /&gt;
This joint learning I feel has some value. It seems strange that this practice is not more popular.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-5121952554932315529?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hXQ_f5-iTP5bb3fuqyNrGxg9H6o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hXQ_f5-iTP5bb3fuqyNrGxg9H6o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hXQ_f5-iTP5bb3fuqyNrGxg9H6o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hXQ_f5-iTP5bb3fuqyNrGxg9H6o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/5121952554932315529/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=5121952554932315529" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5121952554932315529?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5121952554932315529?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/12/metaphors-in-software.html" title="Metaphors in software" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm3.static.flickr.com/2016/1871326475_859e614eee_t.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEABRXY6fip7ImA9WhdVEUw.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-1011274544398153202</id><published>2011-09-15T19:59:00.000Z</published><updated>2011-09-15T19:59:14.816Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-15T19:59:14.816Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unit-test" /><category scheme="http://www.blogger.com/atom/ns#" term="refactoring" /><title>Thoughts on retro fitting tests.</title><content type="html">&lt;div&gt;Had an interesting talk with a colleague of mine some time back&amp;nbsp; on the topic of retrofitting tests to a system. I'm not a fan of retro fitting for the sake of it. The, now hopefully well documented, problem with TDD is that the 'test' bit is a side effect. Its practically a distraction to the design aspect of TDD. So when I get told to write 'unit' tests against an code base, I accept they are not going to be the same sort of unit tests as those that I would write when I'm doing test first.&lt;br /&gt;
&lt;br /&gt;
So why do I have an issue?&lt;br /&gt;
When we retro fit unit tests, &lt;b&gt;the best we can do is make observations of the current state of the system&lt;/b&gt;. This system may be&amp;nbsp;subtly&amp;nbsp;wrong, how can we know if we have no specification to verify against? At the unit level such detail may not be understood by the business. The scenario that the code was written under is most likely&amp;nbsp;forgotten&amp;nbsp;or more likely misunderstood. So when we write tests we merely &lt;b&gt;observe and report&lt;/b&gt;, we cannot say that we understand.&lt;br /&gt;
&lt;br /&gt;
I came across this issue, yesterday. My pair and I were refactoring some code and saw a redundant switch statement. looking at the system hollistically, it was obvious that the code didn't belong so we whipped it out, ran the tests and got red.&lt;br /&gt;
&lt;br /&gt;
The production code was&amp;nbsp;something&amp;nbsp;like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public string GetContent(int fooId)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var content = string.Empty;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;switch (fooId)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case 4:&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return _contentModule.GetContent();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return content;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
We knew that fooId would only ever be 4, (cough magic number) and so could simplify this method down but when we ran the test, we failed on:&lt;br /&gt;
&lt;br /&gt;
public void Should_return_stringEmpty_when_fooId_not_equal_to_4()&lt;br /&gt;
&lt;br /&gt;
When I looked at the log in source control it revealed that the tests had been committed 3 months after production code had. I'm guessing then that the test author had merely looked at the code and applied a test based on what the code actually does rather than the intent.&lt;br /&gt;
&lt;br /&gt;
This retro fitting of tests can therefore be dangerous. If we trust the tests (and we should) then retro fitting can be misleading and it is against the TDD ethos. Remember kids you should value specifying over verifying. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-1011274544398153202?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cdIzfsgsuySY1MkVtN-RbOrs6iA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cdIzfsgsuySY1MkVtN-RbOrs6iA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cdIzfsgsuySY1MkVtN-RbOrs6iA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cdIzfsgsuySY1MkVtN-RbOrs6iA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/1011274544398153202/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=1011274544398153202" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/1011274544398153202?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/1011274544398153202?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/09/thoughts-on-retro-fitting-tests.html" title="Thoughts on retro fitting tests." /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkEGSHkyeip7ImA9WhZbFEk.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-5860120756470526830</id><published>2011-06-18T23:42:00.001Z</published><updated>2011-06-18T23:43:49.792Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-18T23:43:49.792Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rewrite" /><title>Jack and Jill rewrite a system and then go on a dig</title><content type="html">A software system is like a bucket of water.&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-O9S039dcyH0/Tf014RIMn9I/AAAAAAAAAHY/aGFId-Z6AAs/s1600/leaky.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="214" src="http://4.bp.blogspot.com/-O9S039dcyH0/Tf014RIMn9I/AAAAAAAAAHY/aGFId-Z6AAs/s320/leaky.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Photo by&amp;nbsp;&lt;a href="http://www.flickr.com/photos/tobiasschlitt/"&gt;Tobias Schlitt&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
But other than just the code and the persistence of data there's knowledge too. Knowledge about the system that is sometimes stored in documents, sometimes stored in tests but always stored with people.&lt;br /&gt;
&lt;br /&gt;
I've just been watching Scott Bellware's "Beyond &lt;a href="http://www.ndc2011.no/agenda.aspx"&gt;Agile&lt;/a&gt;" talk and he talks about software development of simply being knowledge transfer. A product sponsor transfers the knowledge to an analyst, who transfers to the business analyst, who transfers to the develop to tester into a product.&lt;br /&gt;
&lt;br /&gt;
When we rewrite systems we will leak this knowledge. Exactly if you tried to pour a full bucket of water into another bucket or water. Chances are you'll spill a bit. Chances are the documentation is not comprehensive. Chances are the tests don't convey the meaning of the application well enough. Chances are the developers have forgotten what they were doing when they wrote that feature. Chances are the product sponsor has forgotten exactly why they wanted it 'that' way.&lt;br /&gt;
&lt;br /&gt;
When system stakeholders leave the project the bucket springs a leak. You have lost some of that knowledge. Even with comprehensive documentation, tests and a full handover. &amp;nbsp;And your bucket is probably not a bucket any more. What once was a bucket is now probably a kettle that does credit card payments... and its rusty but only on a Thursday.&lt;br /&gt;
&lt;br /&gt;
So how do I summarise this leaky abstraction? (go on groan)&lt;br /&gt;
&lt;br /&gt;
A software system is is more than just code. It is the users, the stakeholders, the delivery team and the state of the system. When rewriting the system it is going to be impossible to relive the journey of knowledge accumulation that the team went through to get to the system that you are rewriting. Even though there will be a set of artefacts you will have discovered to reconstruct the system this will not be the full picture. That's ok because you only need to do what your stakeholder's need now. Reconstructing 100% of the old system when no one knows what 100% is wasteful (and impossible)&lt;br /&gt;
&lt;br /&gt;
Rewriting software is like an archaeological dig.&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/--FG5jRFST_k/Tf02-kqr2pI/AAAAAAAAAHc/p_m_BE377Zc/s1600/dig.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/--FG5jRFST_k/Tf02-kqr2pI/AAAAAAAAAHc/p_m_BE377Zc/s320/dig.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Photo by&amp;nbsp;&lt;a href="http://www.flickr.com/photos/bengarney/"&gt;Ben Garney&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
Except rather than rebuilding the Roman fort exactly we extract what we want from it and make it better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-5860120756470526830?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6KPj9Vn96AdVjuwtI5WS6TOKYis/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6KPj9Vn96AdVjuwtI5WS6TOKYis/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6KPj9Vn96AdVjuwtI5WS6TOKYis/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6KPj9Vn96AdVjuwtI5WS6TOKYis/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/5860120756470526830/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=5860120756470526830" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5860120756470526830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5860120756470526830?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/06/jack-and-jill-rewrite-system-and-go-on.html" title="Jack and Jill rewrite a system and then go on a dig" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-O9S039dcyH0/Tf014RIMn9I/AAAAAAAAAHY/aGFId-Z6AAs/s72-c/leaky.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkMESX06eip7ImA9WhZUGUo.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-7223164775327012510</id><published>2011-06-13T13:53:00.001Z</published><updated>2011-06-13T14:13:28.312Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-13T14:13:28.312Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rewrite dddsw" /><title>DDDSW 3 - RE: the ReWrite session.</title><content type="html">I went to &lt;a href="http://www.dddsouthwest.com/"&gt;DDDSW&lt;/a&gt; on Saturday( a conference based around Microsoft technologies) specifically to see one session.&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;
"Rewriting software is the single worst mistake you can make - apparently" by &lt;a href="http://twitter.com/fatherfil"&gt;Phil Collins&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This subject is dear to my mind as I've been involved in many rewrite projects over the years with varying degrees of success. Its also a big part of my studies at the minute.&lt;br /&gt;
&lt;br /&gt;
Phil is a confident speaker and this session is an experience report rather than a "How to" session. Some of the choices that Phil has made I disagree with. I want to share the reasons why I disagree, not to have a pop at Phil but just to get clear in my mind why I do.&lt;span style="font-size: large;"&gt;&lt;br /&gt;
&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt; Language choice&lt;/span&gt;&lt;br /&gt;
Phil was moving from an old tightly coupled legacy system and he had a free choice of languages. He quite rightly had an R &amp;amp; D session on a few languages. However the basis of the choice he made given in the talk was problems with case insensitivity. There are many factors for choosing a language, tooling support &amp;amp; flexibility are two that spring to mind but the issues that you have in the first few weeks you will soon forget and so case insensitivity is a minor distraction in my opinion. Choose a language and platform that is right for the application not just the rewrite project.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Screen by screen rewrite.&lt;/span&gt;&lt;br /&gt;
Why? Sure you get all the features but this is an excellent time to find out exactly what you do use and more importantly what you don't. I know this from first had experience. I joined a rewrite project late that had done exactly this. There were dozens and I mean dozens of text boxes and fields in the application that were not used any more. Whole screens were devoted to the parts of the business that just didn't exist any more.&lt;br /&gt;
&lt;br /&gt;
Take the time to talk with your users about each screen. Try and come up with the story behind each feature. If your users don't need it. Don't rewrite it. This saves you time and gives you opportunity to remove cruft from your application.&lt;br /&gt;
&lt;br /&gt;
To be fair Phil did share a story where he added more features based on user interaction. I'm assuming that he may not have blindly rewritten all features.&lt;br /&gt;
&lt;br /&gt;
What Phil has got right:&lt;span style="font-size: large;"&gt;&lt;br /&gt;
&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Continuous integration.&lt;/span&gt; &lt;br /&gt;
Phil lauds this and has a very funky set of build radiators. (BVC of the build status) and I agree. CI is instant feedback and build radiators are key to that feedback.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Slowly, carefully.&lt;/span&gt;&lt;br /&gt;
Phil tells his devs to go slowly. Any project should not be done a break neck speed. Otherwise you are under pressure to cut corners. If you are just in a race to rewrite a function you will make mistakes. A rewrite is an opportunity to cut tech debt. Don't make the mistake of adding more.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;More Whiteboards&lt;/span&gt;&lt;br /&gt;
... I love just scribbling down stuff on white boards too. It is simply a great way to share ideas and concepts.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;What I would do - ascertain the vision&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Assuming&lt;/span&gt; &lt;span style="font-size: small;"&gt;that the rewrite has to be done. I would try and extract the vision for the project. Why is it that we have to do this rewrite? What are we trying to get out of the the rewrite? It may be to improve usability or performance. It may be for legal reasons. It may be the the cost of change is high in the legacy application or that the technology is just not supported.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;Observe system usage&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Given we now have a vision, a set of woolly statements that we are heading towards we can now look at the current application and its features. Look at each of the features and see if they still align with how the users are using them. A good idea here is to sit with the users and observe their daily activity. Its an eye opener to see how your application is actually being used and its often not as designed. Of course you will not all of the usage in just one session but you will certainly get the core.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;Speak with your users&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Next step is to interview your users find out what they think their processes are. At this point you should pick up things they do that you didn't pick up on the initial sweep. This is a great opportunity to find clunky procedure where you can improve upon. Many times I've done this and found hidden manual process too.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;Collaborate to write automated specifications&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Now that you have a vision, an idea of how the users are using the system and the processes they are trying to follow you can begin to look at the features the system needs to achieve the processes. These features can be broken down into user stories and then you can provide examples to specify the features. A tool like Cucumber (or SpecFlow) can work well in situations like this. Now that your specs are automated you can get that cosy feedback loop when you check with your CI system.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;Iterate&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Split your work up into chunks. Stop then reflect. Are we missing something? If so add it. Show your work to your users regularly. Rollout to them as soon as possible and as much as possible.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;Summary&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Phil's got some good ideas but his focus is different from mine&lt;/span&gt;. &lt;span style="font-size: small;"&gt;Check out his blog&lt;/span&gt;&lt;/span&gt; &lt;a href="http://soyouthinkyouneedtorewrite.com/"&gt;http://soyouthinkyouneedtorewrite.com/&lt;/a&gt; for some views on rewrites and if he does his talk near you go see it. But also don't rewrite feature for feature. Take the opportunity to prune dead features and improve existing ones.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-7223164775327012510?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WJ7TnVRuRT-0wPEPs_lXd6gO8k4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WJ7TnVRuRT-0wPEPs_lXd6gO8k4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WJ7TnVRuRT-0wPEPs_lXd6gO8k4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WJ7TnVRuRT-0wPEPs_lXd6gO8k4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/7223164775327012510/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=7223164775327012510" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/7223164775327012510?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/7223164775327012510?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/06/dddsw-3-re-rewrite-session.html" title="DDDSW 3 - RE: the ReWrite session." /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DU8NQns4fyp7ImA9WhZUEk4.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-5973266150588642370</id><published>2011-06-05T01:38:00.000Z</published><updated>2011-06-05T01:38:13.537Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-05T01:38:13.537Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lean" /><title>Actually all we care about.</title><content type="html">Mary Poppendeick is a legend. She's got a fantastic paper about team &lt;a href="http://www.poppendieck.com/pdfs/Compensation.pdf"&gt;rewarding&lt;/a&gt;, But I've just been reading her paper about lean thinking. "Wow John. Lean's so old now its in a nursing home." but hey I've just Mary's principles of lean thinking. Its nothing new if you aren't &amp;nbsp;on the agile slug trail but i kinda missed it. &lt;br /&gt;
&lt;br /&gt;
So for everyone else;&lt;br /&gt;
&lt;br /&gt;
here's what you are doing.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;YOU ARE WASTING YOUR TIME&lt;/span&gt;&lt;br /&gt;
Mary and some guy from japan have noticed that:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font: 12.0px 'Times New Roman'; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;b&gt;The Seven Wastes of Software Development&lt;/b&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Overproduction = Extra Features&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Inventory = Requirements&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Extra Processing Steps = Extra Steps&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Motion = Finding Information&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Defects = Defects Not Caught by Tests&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Waiting = Waiting, Including Customers&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Transportation = Handoffs&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Can you see this in your organisation?&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 10.0px Arial; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-5973266150588642370?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/l7vlk1x9DkaoGJ5p5_-lNTQzJHk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l7vlk1x9DkaoGJ5p5_-lNTQzJHk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/l7vlk1x9DkaoGJ5p5_-lNTQzJHk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l7vlk1x9DkaoGJ5p5_-lNTQzJHk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/5973266150588642370/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=5973266150588642370" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5973266150588642370?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5973266150588642370?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/06/actually-all-we-care-about.html" title="Actually all we care about." /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0MESXYzfSp7ImA9WhZUEk4.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-6555763067488767275</id><published>2011-06-05T00:56:00.000Z</published><updated>2011-06-05T00:56:48.885Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-05T00:56:48.885Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><title>Nobody cares about agile but you</title><content type="html">A poem :&lt;br /&gt;
I remember when I was concerned when agile was something that 'hippies did' (&amp;amp; me). I remember when people thought that agile meant no docs. I vaguely remember the acceptance. i don't remember the corporate adoption. I remember the scrum certification. I remember that now that the literati accept agile as a given. I remember moving jobs to an agile organisation. I remember how nothing had changed. I remember how this was not agile. I remember how we can do better. I remember the alt.net implosion. I remember the bright days of dev div. I remember the betrayal of people's hard work. &amp;nbsp;I remember getting my team to think about objects. I remember to get them to think about tests. I remember just writing code. I remember loving results. I remember loving the problem I remember &amp;nbsp;loving quality. I remember evolving design. I remember just wanting to make things better. I remember the stand ups, I remember the cynicism. I remember the hope. I remember the break through. I &amp;nbsp;try. We improve. we improve.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-6555763067488767275?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RqWD4MoGOX35J_fvShL8Fmy0EXw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RqWD4MoGOX35J_fvShL8Fmy0EXw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RqWD4MoGOX35J_fvShL8Fmy0EXw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RqWD4MoGOX35J_fvShL8Fmy0EXw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/6555763067488767275/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=6555763067488767275" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/6555763067488767275?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/6555763067488767275?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/06/nobody-cares-about-agile-but-you.html" title="Nobody cares about agile but you" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A04ESHY-fyp7ImA9WhZUEk8.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-4119543551970859833</id><published>2011-06-04T23:25:00.000Z</published><updated>2011-06-04T23:25:09.857Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-04T23:25:09.857Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rant" /><title>ORMs</title><content type="html">There has been a backlash against ORMs. I missed it. While you were all messing around with Nhibernate. I avoided it. Why? because I can always write database queries much easier in SQL.&lt;br /&gt;
&lt;br /&gt;
Always.&lt;br /&gt;
&lt;br /&gt;
My mappings were much better when I mapped in with NH. I've always worked in smaller teams and much of the code has been written procedurally.&lt;br /&gt;
&lt;br /&gt;
There I said it.&lt;br /&gt;
&lt;br /&gt;
But this is why I like ORMs... because over several years into .net people are still writing procedural code. For the first time people were forced to think about domain objects.&lt;br /&gt;
&lt;br /&gt;
and now we have EF. Ef is now getting people to think code first. (Wow welcome to the 1980s)&lt;br /&gt;
&lt;br /&gt;
and now we have stuff simple.data.&lt;br /&gt;
&lt;br /&gt;
ORMs were supposed to remove the impedance mistmatch between tables and code. This has only been solvee if your forward generate.&lt;br /&gt;
&lt;br /&gt;
For those of us with legacy systems &amp;nbsp;all this backwards mapping is too much of a ball ache.&lt;br /&gt;
minimilist web frameworks don;t help and this is why I'm writing crap like SQl.data.&lt;br /&gt;
We don't need to worry what to call our call because its the name of the entity. we don't need to worry about joins because its the best SQL we can write.&lt;br /&gt;
&lt;br /&gt;
Lets not worry about the mismatch because we can do what the devs did in the 80s. We write the best DSL to query data evar. S Q L.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-4119543551970859833?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8mSQ0Ymqocji3OMJq6TpE4R9O-A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8mSQ0Ymqocji3OMJq6TpE4R9O-A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8mSQ0Ymqocji3OMJq6TpE4R9O-A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8mSQ0Ymqocji3OMJq6TpE4R9O-A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/4119543551970859833/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=4119543551970859833" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/4119543551970859833?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/4119543551970859833?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/06/orms.html" title="ORMs" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEABSX0zeSp7ImA9WhZVEko.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-7281205518041445369</id><published>2011-05-24T21:32:00.000Z</published><updated>2011-05-24T21:32:38.381Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-24T21:32:38.381Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="msc" /><category scheme="http://www.blogger.com/atom/ns#" term="survey" /><title>Research in re-writing systems.</title><content type="html">I'm doing some research into re-writing systems with automated tests and I'm trying to get a feel for what the status quo is in this area.&lt;br /&gt;
&lt;br /&gt;
If you've got a spare couple of minutes to fill in this short survey. &amp;nbsp;I'd very much appreciate it.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://edu.surveygizmo.com/s3/549590/Re-writing-systems-with-TDD-and-BDD"&gt;My survey&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
If you don't want to do it.... well baby jesus will kill a kitten or something.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-7281205518041445369?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NRhZEAE4yKDqNvkBCslB18DYZ1c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NRhZEAE4yKDqNvkBCslB18DYZ1c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NRhZEAE4yKDqNvkBCslB18DYZ1c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NRhZEAE4yKDqNvkBCslB18DYZ1c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/7281205518041445369/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=7281205518041445369" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/7281205518041445369?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/7281205518041445369?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/05/research-in-re-writing-systems.html" title="Research in re-writing systems." /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkcEQnk6fyp7ImA9WhZQFk0.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-446628267148475513</id><published>2011-04-23T23:06:00.000Z</published><updated>2011-04-23T23:06:43.717Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-23T23:06:43.717Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="test coverage" /><category scheme="http://www.blogger.com/atom/ns#" term="specification" /><title>Test coverage or specification</title><content type="html">Whilst writing up some notes I keep on changing between tests that cover something (as in test coverage) and tests that specify behaviour. It strikes me that these two concepts&amp;nbsp;are orthogonal to one another. The former is an after thought, something that aids regression, the latter a pre-requisite to writing the code.&lt;br /&gt;
&lt;br /&gt;
The funny thing is that I hear about test coverage but we never talk about specification coverage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-446628267148475513?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/q9bhxLBI2MtyVzUGWcvMRP8KYOo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q9bhxLBI2MtyVzUGWcvMRP8KYOo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/q9bhxLBI2MtyVzUGWcvMRP8KYOo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q9bhxLBI2MtyVzUGWcvMRP8KYOo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/446628267148475513/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=446628267148475513" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/446628267148475513?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/446628267148475513?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/04/test-coverage-or-specification.html" title="Test coverage or specification" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkQDRXs9fCp7ImA9WhZQFUs.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-3156980790532999815</id><published>2011-04-23T13:07:00.001Z</published><updated>2011-04-23T13:12:54.564Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-23T13:12:54.564Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="abstract" /><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><title>TDD for abstract classes</title><content type="html">I don't seem to use abstract classes much anymore. The tendency is for me to prefer interfaces over abstract classes as I've been inculcated with mantra 'composition over inheritance'. Where common behaviour is observed though it just feels natural to shove that behaviour in , I dunno, something like a superclass.&lt;br /&gt;
I like the template pattern too. So I do use abstract classes occasionally.&lt;br /&gt;
&lt;br /&gt;
Concerning testing I have tended to duplicate testing this behaviour in the past. This is something that has not settled well. Duplication in testing may be slightly less repugnant than duplication in production code but there must be a valid reason.&lt;br /&gt;
&lt;br /&gt;
How should we tackle testing abstract methods then?&lt;br /&gt;
Here are a couple of strategies.&lt;br /&gt;
&lt;br /&gt;
Firstly here is my class&lt;br /&gt;
&lt;script src="https://gist.github.com/938572.js?file=MyAbstractClass.cs"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;An abstract test class&lt;/span&gt;&lt;br /&gt;
We can put the tests for the behaviour into an abstract test class using a protected but uninitialised instance member. In our concrete sub class test class we inherit from the abstract test class and instantiate the sub class variable When we run the tests the superclass tests run with the subclasses.&lt;br /&gt;
If the subclass has more methods that need to be tested then a clumsy casting of the concrete type over the instance variable has to performed each time we test. Alternatively a separate member of the subclass needs to be setup as well the abstract one.&lt;br /&gt;
&lt;script src="https://gist.github.com/938579.js?file=abstractTestClass.cs"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;An mock of the abstract class&lt;/span&gt;&lt;br /&gt;
Alternatively we can use a mocking framework to mock the abstract class and run tests on that.&lt;br /&gt;
&lt;script src="https://gist.github.com/938584.js?file=AbstractWithAmock.cs"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;A fake concrete class&lt;/span&gt;&lt;br /&gt;
If the feeling of mocking an abstract class doesn't sit well an slight variation would be to create a fake concrete instance and perform the tests on that.&lt;br /&gt;
&lt;script src="https://gist.github.com/938588.js?file=Fake.cs"&gt;
&lt;/script&gt;&lt;br /&gt;
If I was using Mspec today I could has used its behaviours functionality which may have been more simple but I wanted to see from a TDD point of view what options I had.&lt;br /&gt;
&lt;br /&gt;
Do you use any other strategies for testing abstract classes?&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://github.com/johnnonolan/Testing-an-Abstract-Class-Strategies"&gt;All the code if you want it&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-3156980790532999815?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Y4F_TS7mkQmSoNiQmyIlUuYb81E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y4F_TS7mkQmSoNiQmyIlUuYb81E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Y4F_TS7mkQmSoNiQmyIlUuYb81E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y4F_TS7mkQmSoNiQmyIlUuYb81E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/3156980790532999815/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=3156980790532999815" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/3156980790532999815?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/3156980790532999815?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/04/tdd-for-abstract-classes.html" title="TDD for abstract classes" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;CkcHRHw_eyp7ImA9WhZQFEg.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-4031765346099652366</id><published>2011-04-22T05:27:00.000Z</published><updated>2011-04-22T05:27:15.243Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T05:27:15.243Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mocks" /><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><title>TDD Strategies</title><content type="html">Just scribbling some notes thought this looked bloggable: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Driven-development can be approached using at least two strategies, a mock based approach or a state based approach (Martin Fowler calls this a classicist approach &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;http://martinfowler.com/articles/mocksArentStubs.html&lt;/a&gt;). When presented with the initial idea, TDD seems simple; write the test to verify the behaviour code you are about to write. A common example of this is a calculator.&lt;br /&gt;
&lt;br /&gt;
Say we have a calculator class that has the following method:&lt;br /&gt;
&lt;br /&gt;
public void int Add(int integer1, int integer2)&lt;br /&gt;
&lt;br /&gt;
We may write a test to verify this works first;&lt;br /&gt;
&lt;br /&gt;
public void Should_Sum_inputs_together()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var result = new Calculator().Add(1,4);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(5,result);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This is probably the defacto example of a state based testing approach. An action is performed on a class, and then its state is interrogated or a return value is verified. In many introductions to TDD you will find trivial examples such as this one. When test-driving code ‘in the wild’ you soon find that certain things become more complex very quickly.&lt;br /&gt;
Mock based TDD&lt;br /&gt;
Continuing on with the calculator example we can see where state based testing alone may not be enough.&lt;br /&gt;
&lt;br /&gt;
Say we move a little closer to the GUI and have a ButtonInterface class that implements the interface,&lt;br /&gt;
&lt;br /&gt;
IButtonInterface&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button Zero;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button One;&lt;br /&gt;
…&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button Nine;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button Add;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button Equals;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void PressButton(Button button);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Our test may be :&lt;br /&gt;
public void Should_Sum_inputs_together()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //mock a calculator -- I’m using pseudo code based on Moq&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var mock = new Mock&lt;icalculator&gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ICalculator calc = mock.Object;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IButtonInterface calcUI = new ButtonInterface(calc);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calcUI.PressButton(this.One);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calcUI.PressButton(this.Add);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calcUI.PressButton(this.Four);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calcUI.PressButton(this.Equals);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mock.Verify(c =&amp;gt; c.Add(1,4));&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
When testing the button interface we do not need to know how our class that does the addition manages the task. It is not the responsibility of the button interface to do so. However it is the responsibility to take the button inputs and send the appropriate messages to the calculator.&lt;br /&gt;
This is where mock based testing comes in. If the ICalculator interface hasn’t been written yet or perhaps there is a cost in setting up an ICalculator, for example it may be dependant on a filesystem or a database. In these cases tests may run slowly due to getting the dependancy into the correct state and then resetting it afterwards. In these examples and the more striking fact the the ButtonInterface doesn’t care all we need to verify is that the correct message has been sent to the correct interface.&lt;/icalculator&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-4031765346099652366?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_DzbvLUmJUOlRwhdvBj8Cmidslw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_DzbvLUmJUOlRwhdvBj8Cmidslw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_DzbvLUmJUOlRwhdvBj8Cmidslw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_DzbvLUmJUOlRwhdvBj8Cmidslw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/4031765346099652366/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=4031765346099652366" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/4031765346099652366?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/4031765346099652366?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/04/tdd-strategies.html" title="TDD Strategies" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DkEFSHk-fCp7ImA9WhZTFU4.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-282226013557489935</id><published>2011-03-19T10:25:00.001Z</published><updated>2011-03-19T11:36:59.754Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-19T11:36:59.754Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><title>Getting Better Steadily</title><content type="html">&lt;a href="http://agileotter.blogspot.com/"&gt;Tim Ottinger&lt;/a&gt;, asked me to write a few words for him about the &lt;a href="http://pragprog.com/titles/olag/agile-in-a-flash"&gt;Agile in a Flash&lt;/a&gt; cards he co-authored. I bought these recently to help us reboot the team into something more agile. The cards are great, concise pieces of information that we reflect on each morning. They started off on my desk but it was fantastic to see them missing from my desk and being talked about by the other developers. This hasn't happened with books or blog posts because the information in a book is usually buried 100s of pages in and 19" monitors are well, just not mobile enough. The cards invite being passed around and collaborated with. It's wonderful to see that happening.&lt;br /&gt;
&lt;br /&gt;
Anyway if you want to,&amp;nbsp;&lt;a href="http://agileinaflash.blogspot.com/2011/03/getting-better-guest-blog-post.html"&gt;read my story&lt;/a&gt; on the Agile in a Flash &lt;a href="http://agileinaflash.blogspot.com/"&gt;blog&lt;/a&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://imagery.pragprog.com/products/217/olag.jpg?1298589962" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://imagery.pragprog.com/products/217/olag.jpg?1298589962" width="228" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-282226013557489935?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cnIlc9GThk4FlXTOrEr5US50rG4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cnIlc9GThk4FlXTOrEr5US50rG4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cnIlc9GThk4FlXTOrEr5US50rG4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cnIlc9GThk4FlXTOrEr5US50rG4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/282226013557489935/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=282226013557489935" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/282226013557489935?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/282226013557489935?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/03/getting-better-steadily.html" title="Getting Better Steadily" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DE8GQHkzcSp7ImA9Wx9bGU4.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-1015873508877589617</id><published>2011-02-28T23:45:00.001Z</published><updated>2011-02-28T23:47:01.789Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-28T23:47:01.789Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xp-manchester" /><category scheme="http://www.blogger.com/atom/ns#" term="Bdd" /><title>Design contradictions between test levels</title><content type="html">I thought I'd spend tonight finishing off the &lt;a href="https://github.com/johnnonolan/ChessBoard-Kata"&gt;BDD Chessboard Kata&lt;/a&gt; exercise I started with Jim McDonald at an XP Manchester coding dojo. Jim is a fan of emergent design, whereas I advocate a little design up front.&lt;br /&gt;
For those who don't know the kata. There are a number of predefined specifications written in the Gherkin DSL based around the movement of 2 chess pieces on a chessboard.&lt;br /&gt;
This is the feature we were implementing.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Feature: Boundaries of the board.&lt;br /&gt;
In order to obey the rules of Chess&lt;br /&gt;
As a player &lt;br /&gt;
I want to be prevented from entering moves outside the boundary of the board.&lt;br /&gt;
&lt;br /&gt;
Scenario: Pawn at top.&lt;br /&gt;
Given I have a White Pawn at A8 &lt;br /&gt;
And I have a Black Knight at A1&lt;br /&gt;
When I move the Pawn to A9&lt;br /&gt;
Then I should be warned of an illegal move message&lt;br /&gt;
&lt;br /&gt;
Scenario: Knight heads off board&lt;br /&gt;
Given I have a Black Knight at G8&lt;br /&gt;
And I have a White Pawn at A1&lt;br /&gt;
And I move the Pawn to A2&lt;br /&gt;
When I move the Knight to I7&lt;br /&gt;
Then I should be warned of an illegal move message&lt;/blockquote&gt;We've completed most of the steps on each of the scenarios using a location class implementing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: #1e39f6; font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;span style="color: black;"&gt; &lt;/span&gt;interface&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: #2ca3bb;"&gt;ILocation&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #1e39f6;"&gt;void&lt;/span&gt; MoveTo(&lt;span style="color: #1e39f6;"&gt;string&lt;/span&gt; location);&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Each time we touched a class we've covered it with mspec tests.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div style="color: #2ca3bb; font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;[&lt;/span&gt;Subject&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: #1e39f6;"&gt;typeof&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;Location&lt;span style="color: black;"&gt;))]&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #2ca3bb; font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: #1e39f6;"&gt;public&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: #1e39f6;"&gt;class&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;When_creating_a_location_with_an_invalid_position&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 11.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #2ca3bb;"&gt;Because&lt;/span&gt; of = () =&amp;gt;; exception = &lt;span style="color: #2ca3bb;"&gt;Catch&lt;/span&gt;.Exception(() =&amp;gt;; &lt;span style="color: #1e39f6;"&gt;new&lt;/span&gt; &lt;span style="color: #2ca3bb;"&gt;Location&lt;/span&gt;(&lt;span style="color: #b61f1f;"&gt;"Z22"&lt;/span&gt;));&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 11.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #2ca3bb;"&gt;Behaves_like&lt;/span&gt;&amp;lt;&lt;span style="color: #2ca3bb;"&gt;AnInvalidLocation&amp;gt;&lt;/span&gt;; its_in_the_wrong_location;&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 11.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #1e39f6;"&gt;protected&lt;/span&gt; &lt;span style="color: #1e39f6;"&gt;static&lt;/span&gt; &lt;span style="color: #2ca3bb;"&gt;Exception&lt;/span&gt; exception;&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 11.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 11.0px;"&gt;&lt;/div&gt;&lt;div style="color: #2ca3bb; font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;[&lt;/span&gt;Subject&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: #1e39f6;"&gt;typeof&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;Location&lt;span style="color: black;"&gt;))]&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #2ca3bb; font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: #1e39f6;"&gt;public&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: #1e39f6;"&gt;class&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;When_moving_a_piece_to_invalid_location&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #2ca3bb;"&gt;Establish&lt;/span&gt; that = () =&amp;gt;; location = &lt;span style="color: #1e39f6;"&gt;new&lt;/span&gt; &lt;span style="color: #2ca3bb;"&gt;Location&lt;/span&gt;(&lt;span style="color: #b61f1f;"&gt;"A1"&lt;/span&gt;);&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #2ca3bb;"&gt;Because&lt;/span&gt; of = () =&amp;gt;; exception = &lt;span style="color: #2ca3bb;"&gt;Catch&lt;/span&gt;.Exception( ()=&amp;gt;; location.MoveTo(&lt;span style="color: #b61f1f;"&gt;"X2"&lt;/span&gt;));&lt;/div&gt;&lt;div style="color: #2ca3bb; font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;Behaves_like&lt;span class="Apple-style-span" style="color: black;"&gt;&amp;lt;&lt;/span&gt;AnInvalidLocation&amp;gt;&lt;span style="color: black;"&gt;&amp;nbsp;an_invalid_move;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 11.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #1e39f6;"&gt;protected&lt;/span&gt; &lt;span style="color: #1e39f6;"&gt;static&lt;/span&gt; &lt;span style="color: #2ca3bb;"&gt;Exception&lt;/span&gt; exception;&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #1e39f6;"&gt;static&lt;/span&gt;&amp;nbsp;I&lt;span style="color: #2ca3bb;"&gt;Location&lt;/span&gt; location;&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div style="font: 9.5px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 11.0px;"&gt;&lt;/div&gt;I've DRYed out (a little) the invalid move behaviour in my Location.&lt;br /&gt;
&lt;br /&gt;
Now that I've come to implement my final step, "Then I should be warned of an illegal move message".&lt;br /&gt;
I suddenly need to implement the invalid move behaviour. (Even though the WHEN is where the invalid move occurs I don't &lt;i&gt;need&lt;/i&gt;&amp;nbsp;to write the behaviour yet).&lt;br /&gt;
&lt;br /&gt;
So this is where the emergent design has lead me to. If I am to follow the &lt;a href="http://c2.com/xp/YouArentGonnaNeedIt.html"&gt;YAGNI&lt;/a&gt; or &lt;a href="http://www.codinghorror.com/blog/2006/10/the-last-responsible-moment.html"&gt;LRM&lt;/a&gt; principles I don't want do anything thing more than display a message. But If I change the behaviour of my location classes' MoveTo method to return a message, then the good design principles that my class level specifications has lead me too are at odds with the demands of the specification passing.&lt;br /&gt;
&lt;br /&gt;
I am trying not to introduce another class to handle game messaging but by not doing so I undo my hard work at the class level. Is this the last responsible moment?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-1015873508877589617?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kaaQBZTZW1tAQyxwTuJE0189i2k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kaaQBZTZW1tAQyxwTuJE0189i2k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kaaQBZTZW1tAQyxwTuJE0189i2k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kaaQBZTZW1tAQyxwTuJE0189i2k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/1015873508877589617/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=1015873508877589617" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/1015873508877589617?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/1015873508877589617?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/02/design-contradictions-between-test.html" title="Design contradictions between test levels" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CEcAQH08fip7ImA9Wx9bEUs.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-8710118814901880302</id><published>2011-02-20T00:34:00.000Z</published><updated>2011-02-20T00:34:01.376Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-20T00:34:01.376Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Bdd xp-manchester" /><title>Thoughts on Xp Manchester BDD session</title><content type="html">Last week I ran a session on BDD at XP Manchester. I'm writing up some notes on it so I thought I'd share them with the wider world.&lt;br /&gt;
&lt;br /&gt;
A lot of the reading I've done on BDD has mainly focused on the tooling. This to a certain extent is unsurprising as inception of BDD &lt;a href="http://dannorth.net/2006/06/04/theres-more-to-bdd-than-evolving-tdd/"&gt;was about getting people out of the 'test' mindset&lt;/a&gt;. &amp;nbsp;But as Dan North say's "Don't lose sight of the bigger picture or you'll miss all the good stuff". What is the bigger picture? Well that's a good question. Even though there is a wikipedia &lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development"&gt;entry&lt;/a&gt;&amp;nbsp;(more on this later), and a seemingly abandoned&amp;nbsp;&lt;a href="http://behaviour-driven.org/"&gt;wiki driven website&lt;/a&gt;&amp;nbsp;&amp;nbsp;it isn't completely clear what exactly BDD is. I thought that without a clear definition that it would be a useful exercise to find out what other practitioners thought.&lt;br /&gt;
&lt;br /&gt;
Cue the XP Manchester session. I opened up with a very brief summary of what I thought people knew about BDD, the emphasis was on the tooling. (For the latecomers those were those magical 2 minutes).&lt;br /&gt;
Following the brief synopsis I wanted&amp;nbsp;people's definitions of BDD. I got the group to write in brief their thoughts.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://farm6.static.flickr.com/5252/5451423912_c95149a912.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://farm6.static.flickr.com/5252/5451423912_c95149a912.jpg" width="191" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Attributes of BDD&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;In case you can't read my scrawl, the board read:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;It helps requirements&lt;/li&gt;
&lt;li&gt;It is automating acceptance criteria&lt;/li&gt;
&lt;li&gt;It is about communication&lt;/li&gt;
&lt;li&gt;It is a DSL&lt;/li&gt;
&lt;li&gt;It is a process&lt;/li&gt;
&lt;li&gt;It is a specification&lt;/li&gt;
&lt;li&gt;It is a pull based system approach&lt;/li&gt;
&lt;li&gt;It links features and functionality&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;The group seemed to focus on the automated acceptance testing side of it. Even though BDD as a process was mentioned the majority of the group seemed to lean towards BDD as an acceptance framework.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;What I wanted to do was for the group to &lt;u&gt;define&lt;/u&gt; BDD, the methodology.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;In doing the research for the session, I asked a question on the BDD google group. Its a good &lt;a href="http://groups.google.com/group/behaviordrivendevelopment/browse_thread/thread/3909dbdc03e95099"&gt;thread&lt;/a&gt;, well worth a read. Liz Keogh pointed me in the direction of a BDD definition (which can be found on wikipedia).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;BDD is a second-generation, outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;/blockquote&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://farm6.static.flickr.com/5256/5451424822_e1b3ecd5c8.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://farm6.static.flickr.com/5256/5451424822_e1b3ecd5c8.jpg" width="191" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Discussion on definition&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;There's a lot in that. We spent the most of the rest of the session discussing the different parts of those 2 sentences. The trouble with interactive sessions is that the discussion can drift in other directions or falter. &amp;nbsp;And this part of the session wasn't quite how I'd imagined it would go. Because I had shown the group the definition the discussion lead down that path rather than creating something new.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;So one the main discussion points were around Outside-in. The the group consensus is that we work from what the user wants, implement that from the UI afterwards. I touched on the analysis aspects of outside-in. That is when we do analysis on the domain, we start from what we know and then we delve down into the problem space until we have an adequate understanding.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The other point which I feel which got some interest was that BDD encompasses all stakeholders. Not just the project sponsors, or the users but developers, infrastructure, everyone. We posticulated that this would throw up a lot more scenarios. Following on from this we discussed how that classes are microsystems, and that unit tests (or context specfications in our case) are just acceptance tests at a micro level.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Following the discussion. I wanted people to code so I devised a simple BDD exercise, supplying gherkin scenarios. I'm doing an MSc at the moment so I intend to analyse the results in my thesis.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;If anybody fancies doing the exercise I'll post a follow-up blog on where it is and how you can help me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Slides are below:&lt;br /&gt;
&lt;div id="__ss_6987839" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/johnnonolan/exploring-bdd" title="Exploring bdd"&gt;Exploring bdd&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse6987839" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=exploringbdd-110219182619-phpapp02&amp;stripped_title=exploring-bdd&amp;userName=johnnonolan" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse6987839" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=exploringbdd-110219182619-phpapp02&amp;stripped_title=exploring-bdd&amp;userName=johnnonolan" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnnonolan"&gt;johnnonolan&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-8710118814901880302?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9lMvEJFUpYo3egqopx4XMewEvjM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9lMvEJFUpYo3egqopx4XMewEvjM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9lMvEJFUpYo3egqopx4XMewEvjM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9lMvEJFUpYo3egqopx4XMewEvjM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/8710118814901880302/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=8710118814901880302" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/8710118814901880302?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/8710118814901880302?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/02/thoughts-on-xp-manchester-bdd-session.html" title="Thoughts on Xp Manchester BDD session" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm6.static.flickr.com/5252/5451423912_c95149a912_t.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUEDR3wyfyp7ImA9Wx9WFUs.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-2971699993288470486</id><published>2011-01-16T22:20:00.002Z</published><updated>2011-01-20T22:47:56.297Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-20T22:47:56.297Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git vim" /><title>Help I'm a Windows developer get me out of here! (Or The Escape from Vim)</title><content type="html">Git is a great product. When we thought the problem of source control had been solved, Linus Torvalds came up and looked at the problem and made a superior product to the tools I had began to take for granted. However Linus didn't design Git with windows developers in mind. We are used to rich user interfaces where as Git's command line interface is where its strength lies. In fact Gitk (the GUI client for Git) is an&amp;nbsp;abomination and I suspect a major reason for Git's adoption rate to not be much higher.&amp;nbsp;I use msysgit through the Bash shell and everything is rosey, normally. Sometimes I get myself into a pickle. &lt;br /&gt;
&lt;br /&gt;
Git is fussy, you have to commit with a message. I usually use the message flag (git commit -m "commit message") so I don't have to drop into the frankly alien Vim. On occasion I forget so I thought I'd document how to get out of it.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="#Summary"&gt;tl:dr - just get me out of here!&lt;/a&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/__Ws638p-N98/TTNqj53DsyI/AAAAAAAAAG4/PUhhlfjiUwE/s1600/GitOne.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="380" src="http://1.bp.blogspot.com/__Ws638p-N98/TTNqj53DsyI/AAAAAAAAAG4/PUhhlfjiUwE/s640/GitOne.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;You start of in a screen with lots of garish colours and it seems that none of your keystrokes do anything. Even typing sensible stuff like 'quit' or 'exit' just doesn't work! No doubt you are completely&amp;nbsp;exasperated. What's happened is that Git has started the Vim editor and you are in COMMAND mode. Yes Vim doesn't let you edit straight away. You have to tell it too. What you want is to put Vim into INSERT mode. This will allow you to start editing.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/__Ws638p-N98/TTNqBDa6NiI/AAAAAAAAAG0/kIdqzYwseL4/s1600/GitTwo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="380" src="http://1.bp.blogspot.com/__Ws638p-N98/TTNqBDa6NiI/AAAAAAAAAG0/kIdqzYwseL4/s640/GitTwo.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Press i to enter INSERT mode, You can tell you are in INSERT mode by two thing. Firstly you will see -- INSERT -- in the bottom left of the console window and secondly when you depress an alphanumeric key the value will actually appear in the editor!&amp;nbsp;You can now use the keyboard to type the commit message.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/__Ws638p-N98/TTNrRofI5lI/AAAAAAAAAG8/A2-sI3EfT4Y/s1600/GitThree.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="380" src="http://1.bp.blogspot.com/__Ws638p-N98/TTNrRofI5lI/AAAAAAAAAG8/A2-sI3EfT4Y/s640/GitThree.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
When you have finished the message you then will want to either save the message or abandon you changes. To do this you need to re-enter COMMAND mode. Press ESC to do this.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To save changes Unix people have made it simple for us Windows types. On a QUERTY keyboard you simply press the key above S, for save. Its obvious! But before you do that just press the colon key. So that's :w to save. In reality you will just want to save and exit at the same time. Again to exit you use simply use the key that's two to the left, the q key. So you can either chain the Save and Exit :wq or just Exit :q.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/__Ws638p-N98/TTNrur1MiXI/AAAAAAAAAHA/kup6ftQcdjo/s1600/GitFour.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/__Ws638p-N98/TTNrur1MiXI/AAAAAAAAAHA/kup6ftQcdjo/s1600/GitFour.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h2&gt;&lt;a href="http://www.blogger.com/post-create.g?blogID=10896391" name="Summary"&gt;Summary&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
So there you have it. To escape Vim and commit your changes do the following.&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;press i to enter insert mode&amp;nbsp;&lt;/li&gt;
&lt;li&gt;write commit message&lt;/li&gt;
&lt;li&gt;press ESC to return to command mode&lt;/li&gt;
&lt;li&gt;type :wq to save and quit (think write and quit) OR just quit :!q&lt;/li&gt;
&lt;/ol&gt;Hope this helps someone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-2971699993288470486?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tYDp8nwrGjaodGaa9uAsHe4WFp4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tYDp8nwrGjaodGaa9uAsHe4WFp4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tYDp8nwrGjaodGaa9uAsHe4WFp4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tYDp8nwrGjaodGaa9uAsHe4WFp4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/2971699993288470486/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=2971699993288470486" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/2971699993288470486?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/2971699993288470486?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/01/help-im-windows-developer-get-me-out-of.html" title="Help I'm a Windows developer get me out of here! (Or The Escape from Vim)" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/__Ws638p-N98/TTNqj53DsyI/AAAAAAAAAG4/PUhhlfjiUwE/s72-c/GitOne.png" height="72" width="72" /><thr:total>4</thr:total></entry><entry gd:etag="W/&quot;CEIASHw9fCp7ImA9Wx9WEU4.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-5414071729023460372</id><published>2011-01-15T23:02:00.000Z</published><updated>2011-01-15T23:02:29.264Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-15T23:02:29.264Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xp-manchester" /><title>Xp Man XL</title><content type="html">I think it was probably 5 years ago that I read &lt;a href="http://www.amazon.co.uk/Extreme-Programming-Explained-Embrace-Change/dp/0201616416"&gt;Kent Beck's XP explained&lt;/a&gt;. The book had a profound effect on me, not because there was anything radical but more the fact that the ideas contained just seemed to resonate with me. 5 years have passed and Extreme Programming kind of went off the radar. When people thought of Agile then generally meant Scrum and many of the practices I associated with XP were deemed superfluous or perhaps &lt;i&gt;too&lt;/i&gt; extreme.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/__Ws638p-N98/TTImw619jlI/AAAAAAAAAGo/OIFf_u460zQ/s1600/XPManchester.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/__Ws638p-N98/TTImw619jlI/AAAAAAAAAGo/OIFf_u460zQ/s1600/XPManchester.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
However over the last 7 months or so Manchester has started its own XP group and I believe that interest is growing again. As well as monthly meetings at the ever accommodating &lt;a href="http://madlab.org.uk/"&gt;MadLab&lt;/a&gt;, the group organises short guerilla coding dojos and today we had a code retreat, an extra large XP Manchester if you will.&lt;br /&gt;
&lt;br /&gt;
The day was split in to 2 halves. In the morning we had 3 sessions of Conway's Game of Life and in the afternoon we tackled 3 sessions for the CheckOut kata. Time passed surprisingly quickly and both sessions were interesting. The group dynamic was mainly .Net developers, then Python, a Ruby dev and a Java dev.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/__Ws638p-N98/TTInHtS0iKI/AAAAAAAAAGs/nhcIKdneCfE/s1600/Gospers_glider_gun.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/__Ws638p-N98/TTInHtS0iKI/AAAAAAAAAGs/nhcIKdneCfE/s1600/Gospers_glider_gun.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life"&gt;Conway's Game of Life&lt;/a&gt; is a simple simulation of cellular generation. Cell lifetimes are governed by simple rules and so the problem lends itself easily to any language. The group was split into pairs and tasked with finishing the problem. We then swapped pairs and started the problem again, encouraged to approach the problem in a different way. I worked with C# &amp;amp; MsTest,&amp;nbsp;then C#/MSpec,&amp;nbsp;then Python and its unit test framework.&lt;br /&gt;
&lt;br /&gt;
What I took from the retrospectives was the diversity of the approaches to the relatively simple problem.&amp;nbsp;Whereas other groups kept on thinking in terms of grids and cells, my pairs concentrated on the behaviour. Some groups gave cells a tolerance, there were different state models. It just goes to show how we interpret language differently.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/__Ws638p-N98/TTImgyK1EoI/AAAAAAAAAGk/IpA5ZX3ejEM/s1600/images.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/__Ws638p-N98/TTImgyK1EoI/AAAAAAAAAGk/IpA5ZX3ejEM/s1600/images.jpeg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
The afternoon &lt;a href="http://codekata.pragprog.com/2007/01/kata_nine_back_.html"&gt;CheckOut kata&lt;/a&gt; sessions were done in a different way. We had one session to finish the kata, one to refuctor and we were supposedly going to have a third to refactor it back. Fortunately we didn't have chance to do the third session and there were some great examples of terrible code that I certainly didn't want to touch with a barge pole.&lt;br /&gt;
&lt;blockquote&gt; &lt;a href="http://www.waterfall2006.com/gorman.html"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Refuctoring&lt;/span&gt;&lt;/a&gt; is the process of taking a well-designed piece of code and, through a series of small, reversible changes, making it completely unmaintainable by anybody except yourself. Comprehensive regression testing guarantees that nobody will be any the wiser. &amp;nbsp;&amp;nbsp;&lt;/blockquote&gt;Surprisingly it was difficult to deliberately write bad code intentionally. (yes I said intentionally) However once you got going it was a lot of fun. I worked with Mark Kirschstein and we had fun with xml, huge switch statements, dead code and much more. The stand out worst involved an ascii Dr. Spock and some brilliant Linq abuse.&lt;br /&gt;
&lt;br /&gt;
The day was lots of fun and great to see some python written by a python developer. The group is full of people who love their trade and its a pleasure to write code with them. These events just give so much. Unless you are lucky its rare that get to work with developers that are willing to improve and share their skills. If you are interested in attending or contributing a session in the future please join the &lt;a href="https://groups.google.com/group/xp-manchester"&gt;google group&lt;/a&gt; or follow the &lt;a href="http://xpmanchester.wordpress.com/"&gt;blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thanks to everyone involved today!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-5414071729023460372?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hWJKbba6R2U4_j1LWSOpPm_noE0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hWJKbba6R2U4_j1LWSOpPm_noE0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hWJKbba6R2U4_j1LWSOpPm_noE0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hWJKbba6R2U4_j1LWSOpPm_noE0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/5414071729023460372/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=5414071729023460372" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5414071729023460372?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5414071729023460372?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2011/01/xp-man-xl.html" title="Xp Man XL" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/__Ws638p-N98/TTImw619jlI/AAAAAAAAAGo/OIFf_u460zQ/s72-c/XPManchester.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0MMSXc_fyp7ImA9Wx5UEE0.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-6554537751050343722</id><published>2010-10-13T21:27:00.001Z</published><updated>2010-10-13T21:31:28.947Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-13T21:31:28.947Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="crap code" /><category scheme="http://www.blogger.com/atom/ns#" term="xp values" /><title>A Codefession</title><content type="html">&lt;i&gt;"Forgive me Father for I have sinned, It has been 3 iterations since my last confession."&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/__Ws638p-N98/TLYMMwynupI/AAAAAAAAAGY/EiRonORbhAU/s1600/woman+in+confession.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/__Ws638p-N98/TLYMMwynupI/AAAAAAAAAGY/EiRonORbhAU/s320/woman+in+confession.jpg" width="222" /&gt;&lt;/a&gt;&lt;/div&gt;I was brought up a Catholic and one part of being a Catholic is Confession. It's great! You do a load of bad stuff (sin), tell a priest, &amp;nbsp;he gives you a penance and then he absolves you.&lt;br /&gt;
Now that the slate is clean, you can do loads of bad stuff again until your next confession. (I think that's how it works).&lt;br /&gt;
&lt;br /&gt;
When coding, I'm a good boy. I've read the &lt;a href="http://cc2e.com/"&gt;various&lt;/a&gt; &lt;a href="http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;gospels&lt;/a&gt;. I even try and &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;write my code&lt;/a&gt; so I don't give in to temptation. And, oh boy, there is temptation. The devil manifests himself in many ways.&lt;br /&gt;
&lt;br /&gt;
There's the temptation to hack it together because you're going to fix it later. The devil knows this will never happen. The devil can be in the form of a looming deadline. You're under pressure and so your good intentions go straight out the window. The devil can be that you are working in an area or language that you are unfamiliar with.&lt;br /&gt;
&lt;br /&gt;
Well I let the devil into my life the other day, I'm ashamed to tell you Father, I sinned. I wrote a real bit of untested, hacky code the other day. Just thinking about it makes me feel guilty. I fixed a defect but at the same time made that bit of code a little bit less maintainable. I broke the &lt;a href="http://programmer.97things.oreilly.com/wiki/index.php/The_Boy_Scout_Rule"&gt;boy scout rule&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Ok...lets drop the metaphor. Programmer writes crap code under duress. Is this acceptable? Well, it depends. In an ideal world all my code would be written like an angry Agile Alliance was stood behind me with baseball bat but we all deviate from time to time, even&amp;nbsp;&lt;a href="http://twitter.com/coreyhaines"&gt;Saint Corey&lt;/a&gt;!&amp;nbsp;I think the most important lesson is to understand the reasons why you have strayed.&lt;br /&gt;
&lt;br /&gt;
Be honest with yourself, why did this happen? What can you do to prevent this happening again? I've done my own retrospective, I guess this blog post is part of it. I know what went wrong and I hope I'll recognise the signs that it will happen again. And when I see those signs I hope I can do what I can to mitigate the circumstances that force me to right it.&lt;br /&gt;
&lt;br /&gt;
I've pulled this into the sprint reviews too. When I've not achieved what I set out too, I want find the root cause. We've not being doing this and I've no idea why. After all,&amp;nbsp;&lt;a href="http://www.thehackerchickblog.com/2009/03/scrum-framework-for-finding-failure.html"&gt;Scrum is not going to solve your problems, it’s just going to make them in-your-face obvious, every day&lt;/a&gt;. I've been thinking about &lt;a href="http://www.extremeprogramming.org/values.html"&gt;XP values&lt;/a&gt;&amp;nbsp;recently too. Without &lt;b&gt;courage &lt;/b&gt;and &lt;b&gt;communication &lt;/b&gt;and to a certain extent &lt;b&gt;feedback&lt;/b&gt; we are setting ourselves up for a failure.&lt;br /&gt;
&lt;br /&gt;
In the talk by &lt;a href="http://www.infoq.com/presentations/Software-Craftsmanship-Beyond-The-Hype"&gt;Software Craftsmanship, Beyond The Hype&lt;/a&gt;,&amp;nbsp;Corey Haines talks about when you have to get stuff done quickly you drop back to the skills you find instinctive. It takes time to learn techniques (such as TDD). Its a natural process. That's why practice and honing your &lt;a href="http://johnnosnose.blogspot.com/2009/10/tdd-kata-do-not-attempt-this-alone.html9gEG3udlKh7A&amp;amp;sig2=_m0o2Zht7Va3bvDgfe3WYA"&gt;technique&lt;/a&gt; are important and that's why just coding in work time doesn't give you the time and space to perfect your skills.&lt;br /&gt;
&lt;br /&gt;
Ok metaphor back on.&lt;br /&gt;
&lt;br /&gt;
Father: My child before I absolve you this is your penance. Say 20 Hail Ruby's and do 10 Our Katas.&lt;br /&gt;
Me: Thank you Father, see you next week!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-6554537751050343722?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MZx3NSQV68H_0FeK1SryZv3mY7A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MZx3NSQV68H_0FeK1SryZv3mY7A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MZx3NSQV68H_0FeK1SryZv3mY7A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MZx3NSQV68H_0FeK1SryZv3mY7A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/6554537751050343722/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=6554537751050343722" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/6554537751050343722?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/6554537751050343722?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2010/10/codefession.html" title="A Codefession" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/__Ws638p-N98/TLYMMwynupI/AAAAAAAAAGY/EiRonORbhAU/s72-c/woman+in+confession.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0EBQXo6fyp7ImA9WxFaE0w.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-1309508370584758880</id><published>2010-07-16T22:34:00.000Z</published><updated>2010-07-16T22:34:10.417Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-16T22:34:10.417Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="assert" /><category scheme="http://www.blogger.com/atom/ns#" term="unit-test" /><title>Be more assertive when unit testing (and not when challenging me)</title><content type="html">I tweeted &lt;a href="http://twitter.com/JohnnoNolan/status/18676430353"&gt;this&lt;/a&gt; today.&lt;br /&gt;
&lt;blockquote&gt;A test without an assert is not a test. It leaves the intended behaviour as completely ambiguous.&lt;/blockquote&gt;Apparently I'm wrong. Some people disagreed. They were mistaken.&lt;br /&gt;
Let's examine their arguments.&lt;br /&gt;
&lt;br /&gt;
Argument #1: Name the test method clearly enough and you don't need an assert?&lt;br /&gt;
&lt;br /&gt;
public void Should_not_throw_when_doing_that_thing()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var obj = new MyObj();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var result= obj.doThatThing();&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
To me this this has a huge gap missing in it. I'm a fan of the &lt;a href="http://c2.com/cgi/wiki?ArrangeActAssert"&gt;AAA&lt;/a&gt; pattern when constructing tests. Above we are only doing the Arrange and Act part. &amp;nbsp;This is why I'm not a fan of the [ExpectedException] attribute. There is no assert within the body of the message. It just doesn't read as I expect to be.&lt;br /&gt;
&lt;br /&gt;
Argument #2: A test can contain no assertions, if you are mocking interactions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 [Test]&lt;br /&gt;
public void WhenDoingSomeThingWithAnotherThingThatWillOccur()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;var someThing = MockRepository.GenerateStub&lt;isomething&gt;();&lt;/isomething&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;var anotherThing = MockRepository.GenerateStub&lt;ianotherthing&gt;();&lt;/ianotherthing&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;someThing.Stub(x =&amp;gt; x.Do(1)).Return(2);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;new myObj(someThing, anotherThing).Do(1);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;notificationSender.AssertWasCalled(//blah);&lt;br /&gt;
}&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;Ok this is a good point but when you are interaction testing you are still asserting that a behaviour is true. Its even there in the code.&lt;br /&gt;
&lt;br /&gt;
As you can tell I'm not convinced. Can anyone provide a compelling reason to leave asserts out of tests?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-1309508370584758880?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_FYpAlENV0-Csv4HCDGvY9tvQXg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_FYpAlENV0-Csv4HCDGvY9tvQXg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_FYpAlENV0-Csv4HCDGvY9tvQXg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_FYpAlENV0-Csv4HCDGvY9tvQXg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/1309508370584758880/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=1309508370584758880" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/1309508370584758880?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/1309508370584758880?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2010/07/be-more-assertive-when-unit-testing-and.html" title="Be more assertive when unit testing (and not when challenging me)" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CEMGR3w5cSp7ImA9WxFbE0o.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-5916738659075951915</id><published>2010-07-05T23:27:00.000Z</published><updated>2010-07-05T23:27:06.229Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-05T23:27:06.229Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="recruitment" /><title>Its more than your job's worth!</title><content type="html">Recently I've been tasked with recruiting my replacement for my current employer. My worry is that the team will end up with someone who is just there to pick up a pay-cheque or a bumbling incompetent (yes another one, v funny). &amp;nbsp;As the position is to lead and support an ASP.Net WebForms app I wanted to test the candidate's ability in ASP.Net WebForms. I presumed that the candidate would jump at the chance of proving their worth prior to an interview.&lt;br /&gt;
&lt;br /&gt;
Here's the test&lt;br /&gt;
&lt;blockquote&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;A dating agency, CandyDate, is running a promotion for its members.&amp;nbsp;&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;It will provide some romantic food for one date that is set up for its members.&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;A date comprises of two people, the organiser and the guest, and a location.&amp;nbsp;&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;The Romantic food that the member can choose from is&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Belgian Choccies&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Grapes&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Oysters&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Strawberries&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Asparagus&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;A member can only set up one date but can be an guest on any number of dates and the food must be chosen.&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;When an organiser submits his date there is a 1 in 4 chance he will also win one of 2 bottles of champagne.&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;After the 2 bottles have been won there should be no more chance to win the champagne (as there's none left)&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;The website is very simple (and trusting) so no authentication is needed. Each of the members have unique firstnames (for simplicity) allegiance&amp;nbsp;&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Please construct a simple website to model this scenario in ASP.Net WebForms (vb or c#). If you do not have VS2008 handy you can use VS2010 express but please target .net 2.0 or 3.5 &amp;nbsp; (http://www.microsoft.com/express) . If you need to use a db please use SQL2005 express or SQLlite. All other dependencies should be shipped with the website.&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;The "Date Form" will be a link off the main website so please start off with a dummy landing page.&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;All that is required is that you give the members the ability to enter the details of a date and a message (or page) to say the date has been submitted confirming the arrangements. A special message will be shown if the member has won the champagne.&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Please do not leave the pages unstyled but don't spend hours on your colour schemes/fonts either. Simple is fine.&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font: 13.0px Courier; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;You shouldn't spend more than 2 hours on this test.&amp;nbsp;&lt;/div&gt;&lt;/blockquote&gt;I thought that the test was&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;very simple&lt;/li&gt;
&lt;li&gt;open-ended to allow some creativity&lt;/li&gt;
&lt;li&gt;show a rudimentary knowledge of asp.net , data access and simple logic.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Of the 12 candidates sent the test I had &amp;lt; 50% completion. I couldn't understand why I was getting so few back. These were keen, pre-screened (yes i used recruiters) prospects apparently. So tonight I made the test public and asked for the feedback on Twitter. Some of the comments were along the lines of:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Too vague&lt;/li&gt;
&lt;li&gt;Too long description&lt;/li&gt;
&lt;li&gt;Two hours is too long.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;This surprised me. I kept things deliberately vague so people could create and yet I gave what I thought was enough information to keep them on the right track. I timed the test and did mine well within the allotted timeframe and in any case is 2 hours a lot of time to invest in your career? For over 50% people it was. I think the time issue is the one that gets me.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;So I'm interested, after you've done your cv and after you've seen a job you wanted where do you draw the line at making the effort for your new role? I've never had a problem at launching myself at a tech test. I don't mind spending time on a panel interview. Even in failure I've learnt more about myself by going through the motions of applying for a role.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;What is more than a job's worth?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-5916738659075951915?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/x2OxjkzP7vkTKZ6mbrL0XwRhr4Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x2OxjkzP7vkTKZ6mbrL0XwRhr4Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/x2OxjkzP7vkTKZ6mbrL0XwRhr4Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x2OxjkzP7vkTKZ6mbrL0XwRhr4Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/5916738659075951915/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=5916738659075951915" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5916738659075951915?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/5916738659075951915?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2010/07/its-more-than-your-jobs-worth.html" title="Its more than your job's worth!" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;A0EERXc8eip7ImA9WxFWEUg.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-3617461005773129756</id><published>2010-05-29T18:58:00.002Z</published><updated>2010-05-29T19:00:04.972Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-29T19:00:04.972Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="macbookpro" /><category scheme="http://www.blogger.com/atom/ns#" term="parallels" /><category scheme="http://www.blogger.com/atom/ns#" term="frustration" /><category scheme="http://www.blogger.com/atom/ns#" term="tilde" /><title>The case of the missing Tilde ~</title><content type="html">&lt;h1&gt;The case of the missing Tilde ~&lt;/h1&gt;&lt;div&gt;I've been looking at Ruby on Rails recently following the book&amp;nbsp;&lt;a href="http://pragprog.com/titles/cerailn/rails-for-net-developers" id="rrbp" title="Rails for .Net developers"&gt;Rails for .Net developers&lt;/a&gt;. This has meant I've been working in a Windows 7 VM in my Mac Book Pro. (I use the excellent &lt;a href="http://www.parallels.com/products/desktop/" id="fnc." title="Parallels"&gt;Parallels&lt;/a&gt;). At some point in the book I had to use the tilde (~) symbol but the life of me couldn't find it as the tilde (~) key produces a pipe |. My Web Search skills failed me and there seemed to be nothing on the Parallels site but eventually I discovered it. So for the benefit of the next person to search I'm going to document it here.&amp;nbsp;&lt;/div&gt;&lt;div id="okyc" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfkskksn_57dg8sstcg_b" style="height: 179.2px; width: 320px;" /&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;&lt;b&gt;To type a tilde (~) in a windows 7 vm on parallels with a macbook pro you press&lt;/b&gt;:&lt;/div&gt;&lt;h3&gt;SHIFT and § &amp;nbsp;&lt;/h3&gt;&lt;div style="text-align: left;"&gt;That's shift and the &lt;a href="http://en.wikipedia.org/wiki/Section_sign" id="evef" title="section sign symbol (§)"&gt;section sign symbol (§)&lt;/a&gt;&amp;nbsp;which is the ±.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-3617461005773129756?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GjGEQ-49y72d5RNZ3QcYQpQqv_4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GjGEQ-49y72d5RNZ3QcYQpQqv_4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GjGEQ-49y72d5RNZ3QcYQpQqv_4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GjGEQ-49y72d5RNZ3QcYQpQqv_4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/3617461005773129756/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=3617461005773129756" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/3617461005773129756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/3617461005773129756?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2010/05/case-of-missing-tilde.html" title="The case of the missing Tilde ~" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;D08DQ348cSp7ImA9WxFSGE0.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-8783218213470408881</id><published>2010-04-20T23:24:00.000Z</published><updated>2010-04-20T23:24:32.079Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-20T23:24:32.079Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="seo-unfriendly" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><title>Thoughts on Testing</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;I drew a picture with Balsamiq. Which is great. These are my current thoughts on testing.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/__Ws638p-N98/S8422gfUgbI/AAAAAAAAAFY/bhpZg6W-1b4/s1600/ThoughtsOnTesting.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="420" src="http://3.bp.blogspot.com/__Ws638p-N98/S8422gfUgbI/AAAAAAAAAFY/bhpZg6W-1b4/s640/ThoughtsOnTesting.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Consider this blog part II of my SEO unfriendly series.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-8783218213470408881?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/UIE0xyIfsg0MueEQJ_iq49b1EwQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UIE0xyIfsg0MueEQJ_iq49b1EwQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/UIE0xyIfsg0MueEQJ_iq49b1EwQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UIE0xyIfsg0MueEQJ_iq49b1EwQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/8783218213470408881/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=8783218213470408881" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/8783218213470408881?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/8783218213470408881?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2010/04/thoughts-on-testing.html" title="Thoughts on Testing" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/__Ws638p-N98/S8422gfUgbI/AAAAAAAAAFY/bhpZg6W-1b4/s72-c/ThoughtsOnTesting.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Ck4NSHw9eip7ImA9WxFTEUk.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-8079710679835918948</id><published>2010-04-01T16:56:00.000Z</published><updated>2010-04-01T16:56:39.262Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-01T16:56:39.262Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="community" /><title>Community Rocks</title><content type="html">Apparently Microsoft gave out there MVP awards today. MVPs (most valuable professionals are described as such:&lt;br /&gt;
&lt;blockquote&gt;These exceptional community leaders come from a wide range of backgrounds. They are teachers, artists, doctors, engineers, as well as technologists, who actively share their high-quality, real-world technical expertise with the community and with Microsoft.&lt;/blockquote&gt;Inevitably there are people who don't get these award who deserve them. Those people that give their time and effort unselfishly for the benefit of others. Or those who want to have their efforts recognised but they've not quite made it. &lt;br /&gt;
&lt;br /&gt;
I seem to be meeting more and more people that "actively share their high-quality, real-world technical expertise with the community" either through Twitter or sites like StackOverflow, the blogosphere or the user groups I attend. And that's ignoring the tons of excellent free open-source software. So I just wanted to thank you all. I don't care about your motivations whether they be completely altruistic or for the fact you're trying to jump up a notch in some imaginary ladder. Your engagement with me validates this sometimes difficult job. Thank you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-8079710679835918948?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YKkTEfmX5eAfzmfcQkwBbwKGWY4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YKkTEfmX5eAfzmfcQkwBbwKGWY4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YKkTEfmX5eAfzmfcQkwBbwKGWY4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YKkTEfmX5eAfzmfcQkwBbwKGWY4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/8079710679835918948/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=8079710679835918948" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/8079710679835918948?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/8079710679835918948?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2010/04/community-rocks.html" title="Community Rocks" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;Ck4NQXo_fCp7ImA9WxBUGE4.&quot;"><id>tag:blogger.com,1999:blog-10896391.post-752276216364511362</id><published>2010-03-05T23:16:00.000Z</published><updated>2010-03-05T23:16:30.444Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-05T23:16:30.444Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="readability" /><category scheme="http://www.blogger.com/atom/ns#" term="mstest" /><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><title>The case of the missing assert</title><content type="html">I was looking at a friend of mines code late last night and he was writing his tests in MSTest. The test he wrote was an expected exception test. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;        [TestMethod]
        [ExpectedException(typeof(SomeException))]
        public void CanDoSomething_WithSomeThingThatThrows_ReturnsTrue()
        {
            var something = SomeFactory.GetSomething();
            something.DoSomething&lt;isomethingelse&gt;(x =&amp;gt; { throw new NotImplementedException(); });

            var result = something.DoSomethingElse&amp;lt;ISomeThingElse&amp;gt;();

            Assert.IsTrue(true);
        }
&lt;/pre&gt;I was tired, it was late, I'm used to a using different test framework but I got in contact straight away.&lt;br /&gt;
&lt;blockquote&gt;....spotted something in your codez. You're Assert is true everytime.&lt;/blockquote&gt;Of course dear reader you will have spotted the ExpectedException attribute as you, unlike me are not an idiot but my eyes see:&lt;br /&gt;
&lt;pre&gt;        [TEST BLAH]
        [yes i didn't spot the attrib here]
        public void STUFF_I_WILL_READ_IF_TEST_IS_NOT_OBVIOUS()
        {
            //SOME ARRANGING STUFF
            ..blah
            //THIS IS IMPORTANT
            var result = something.DoSomethingElse&amp;lt;ISomeThingElse&amp;gt;();
            //AND SO IS THIS
            Assert.IsTrue(true);
        }
&lt;/pre&gt;In my semi-comatosed state my eyes fix on Assert.IsTrue(true) and I can look away from it. I'm used to NUnit's (and xUnit and mbUnit) Assert.Throws&lt;br /&gt;
&lt;pre&gt;        [TEST BLAH]
        public void STUFF_I_WILL_READ_IF_TEST_IS_NOT_OBVIOUS()
        {
            //SOME ARRANGING STUFF
            ..blah
            //THIS IS IMPORTANT
            Assert.Throws&lt;SomeException&gt;(()=&gt; something.DoSomethingElse&amp;lt;ISomeThingElse&amp;gt;());

        }
&lt;/pre&gt;However &lt;em&gt;some&lt;/em&gt; frameworks don't support this. So you've got 2 options.&lt;br /&gt;
Option 1 Attribute and fail.&lt;br /&gt;
&lt;pre&gt;        [TestMethod]
        [ExpectedException(typeof(SomeException))]
        public void CanDoSomething_WithSomeThingThatThrows_ReturnsTrue()
        {
            var something = SomeFactory.GetSomething();
            something.DoSomething&lt;isomethingelse&gt;(x =&amp;gt; { throw new NotImplementedException(); });

            var result = something.DoSomethingElse&amp;lt;ISomeThingElse&amp;gt;();

            Assert.Fail();
        }
&lt;/pre&gt;As my eyes always look the assert and so if I see a fail. I'll look to see why.&lt;br /&gt;
Option 2 No Attribute try catch &lt;br /&gt;
&lt;pre&gt;        [TestMethod]
        public void CanDoSomething_WithSomeThingThatThrows_ReturnsTrue()
        {
            var something = SomeFactory.GetSomething();
            something.DoSomething&lt;isomethingelse&gt;(x =&amp;gt; { throw new NotImplementedException(); });
            try
            {
                var result = something.DoSomethingElse&amp;lt;ISomeThingElse&amp;gt;();
                Assert.Fail();
            }
            catch (SomeException)
            {
                Assert.IsTrue(true);
            } 
            catch (Exception)
            {
               Assert.Fail();
            }
        }
&lt;/pre&gt;And what happens when we want to invoke an action that doesn't expect anything. That you just want to run to see if doesn't fail. Well you've got Assert.DoesNotThrow in &lt;em&gt;most&lt;/em&gt; .Net unit testing frameworks.&lt;br /&gt;
You can call the Assert.IsTrue(True);&lt;br /&gt;
&lt;pre&gt;        [TestMethod]
        public void CanDoSomething_WithSomeThingThatDoesnotThrow()
        {
            var something = SomeFactory.GetSomething();
            something.DoSomething&lt;isomethingelse&gt;(x =&amp;gt; { throw new NotImplementedException(); });
           Assert.IsTrue(True);
        }
&lt;/pre&gt;Or just drop the assert.&lt;br /&gt;
&lt;pre&gt;        [TestMethod]
        public void CanDoSomething_WithSomeThingThatDoesnotThrow()
        {
            var something = SomeFactory.GetSomething();
            something.DoSomething&lt;isomethingelse&gt;(x =&amp;gt; { throw new NotImplementedException(); });
          
        }
&lt;/pre&gt;So with MStest you can't use Assert.Throws but you do have options. Mine is to use another framework ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10896391-752276216364511362?l=johnnosnose.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/u1Zk8Ou7q5njlapKXk3oWX0Wn5o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u1Zk8Ou7q5njlapKXk3oWX0Wn5o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/u1Zk8Ou7q5njlapKXk3oWX0Wn5o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u1Zk8Ou7q5njlapKXk3oWX0Wn5o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://johnnosnose.blogspot.com/feeds/752276216364511362/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=10896391&amp;postID=752276216364511362" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/752276216364511362?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/10896391/posts/default/752276216364511362?v=2" /><link rel="alternate" type="text/html" href="http://johnnosnose.blogspot.com/2010/03/case-of-missing-assert.html" title="The case of the missing assert" /><author><name>Johnno Nolan</name><uri>http://www.blogger.com/profile/15620075254402056526</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry></feed>

