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

<channel>
	<title>Richard Lawrence &#187; patterns</title>
	<atom:link href="http://www.richardlawrence.info/tag/patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.richardlawrence.info</link>
	<description>On making software teams happier and more productive</description>
	<lastBuildDate>Tue, 20 Jul 2010 21:38:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>WatiN Patterns #3: Don&#8217;t Over-specify</title>
		<link>http://www.richardlawrence.info/2009/10/30/watin-patterns-3-dont-over-specify/</link>
		<comments>http://www.richardlawrence.info/2009/10/30/watin-patterns-3-dont-over-specify/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 15:20:31 +0000</pubDate>
		<dc:creator>Richard Lawrence</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[WatiN]]></category>
		<category><![CDATA[WatiN Patterns]]></category>

		<guid isPermaLink="false">http://www.richardlawrence.info/?p=202</guid>
		<description><![CDATA[After a long hiatus, I&#8217;m resuming the WatiN Patterns series. Pattern #1 covered why and how your tests should clean up after themselves. Pattern #2 covered how you should name your tests and why they should only assert one thing. Pattern #3 is about keeping your tests maintainable by specifying just enough in your element [...]


Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/' rel='bookmark' title='Permanent Link: WatiN Patterns #2: One Assertion and a Name to Match'>WatiN Patterns #2: One Assertion and a Name to Match</a></li>
<li><a href='http://www.richardlawrence.info/2009/02/04/watin-patterns-1-no-browser-left-behind/' rel='bookmark' title='Permanent Link: WatiN Patterns #1: No Browser Left Behind'>WatiN Patterns #1: No Browser Left Behind</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/24/another-look-at-watin/' rel='bookmark' title='Permanent Link: Another Look at WatiN'>Another Look at WatiN</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p>After a long hiatus, I&#8217;m resuming the WatiN Patterns series. <a href="/2009/02/04/watin-patterns-1-no-browser-left-behind/">Pattern #1</a> covered why and how your tests should clean up after themselves. <a href="/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/">Pattern #2</a> covered how you should name your tests and why they should only assert one thing.</p>
<p>Pattern #3 is about keeping your tests maintainable by specifying just enough in your element selectors.</p>
<p><span id="more-202"></span></p>
<p>If you&#8217;re using WatiN, you&#8217;re probably also using ASP.NET Web Forms, which means your controls get IDs like this: ctl1001_Content_Content_txtUsername. Though you gave your username text box the ID &#8220;txtUsername&#8221;, ASP.NET prepends the IDs of each of the container controls to your text box&#8217;s ID in the HTML that goes to the browser. This is good for preventing name collisions between controls in different user controls on the same page. But it can lead you to write fragile tests. Consider this example:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #008000;">&#91;</span>Test<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> ShouldAuthenticateUsersSuccessfully<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008000;">&#40;</span>IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://mytestapp/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ctl1001_Content_Content_txtUsername&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;richard&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ctl1001_Content_Content_txtPassword&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;password&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ctl1001_Content_Content_btnLogin&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Welcome, Richard!&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Suppose someone moves the login widgets outside one of those nested &#8220;Content&#8221; controls. Now our test fails. Did login stop working? Probably not. But, thanks to ASP.NET&#8217;s &#8220;helpful&#8221; ID scheme, we can no longer find the login widgets&mdash;their IDs have changed. We could update the test to the new IDs:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #008000;">&#91;</span>Test<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> ShouldAuthenticateUsersSuccessfully<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008000;">&#40;</span>IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://mytestapp/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ctl1001_Content_txtUsername&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;richard&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ctl1001_Content_txtPassword&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;password&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ctl1001_Content_btnLogin&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Welcome, Richard!&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Or we could solve the root problem of fragile tests:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #008000;">&#91;</span>Test<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> ShouldAuthenticateUsersSuccessfully<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008000;">&#40;</span>IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://mytestapp/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Regex<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;txtUsername$&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;richard&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Regex<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;txtPassword$&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;password&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Regex<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;btnLogin$&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Welcome, Richard!&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>WatiN accommodates regular expressions instead of strings for IDs. Now we&#8217;ve specified, &#8220;a text field with an ID ending in txtUsername&#8221; (note the ending dollar sign), instead of, &#8220;a text field with exactly the ID ctl1001_Content_Content_txtUsername.&#8221; Much more flexible.</p>
<p>To keep your tests from being fragile, <strong>when selecting elements on the page, use the least specific method and value necessary to find the element you want.</strong></p>


<p>Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/' rel='bookmark' title='Permanent Link: WatiN Patterns #2: One Assertion and a Name to Match'>WatiN Patterns #2: One Assertion and a Name to Match</a></li>
<li><a href='http://www.richardlawrence.info/2009/02/04/watin-patterns-1-no-browser-left-behind/' rel='bookmark' title='Permanent Link: WatiN Patterns #1: No Browser Left Behind'>WatiN Patterns #1: No Browser Left Behind</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/24/another-look-at-watin/' rel='bookmark' title='Permanent Link: Another Look at WatiN'>Another Look at WatiN</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlawrence.info/2009/10/30/watin-patterns-3-dont-over-specify/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Patterns for Splitting User Stories</title>
		<link>http://www.richardlawrence.info/2009/10/28/patterns-for-splitting-user-stories/</link>
		<comments>http://www.richardlawrence.info/2009/10/28/patterns-for-splitting-user-stories/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 14:04:29 +0000</pubDate>
		<dc:creator>Richard Lawrence</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[product management]]></category>
		<category><![CDATA[Product Owner]]></category>
		<category><![CDATA[user stories]]></category>

		<guid isPermaLink="false">http://www.richardlawrence.info/?p=190</guid>
		<description><![CDATA[Good user stories follow Bill Wake&#8217;s INVEST model. They&#8217;re Independent, Negotiable, Valuable, Estimable, Small, and Testable. The small requirement drives us to split large stories. But the stories after splitting still have to follow the model. Many new agile teams attempt to split stories by architectural layer: one story for the UI, another for the [...]


Related posts:<ol><li><a href='http://www.richardlawrence.info/2008/12/10/when-stories-are-larger-than-planned/' rel='bookmark' title='Permanent Link: Short Answers #1: When Stories Are Larger Than Planned'>Short Answers #1: When Stories Are Larger Than Planned</a></li>
<li><a href='http://www.richardlawrence.info/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/' rel='bookmark' title='Permanent Link: WatiN Patterns #2: One Assertion and a Name to Match'>WatiN Patterns #2: One Assertion and a Name to Match</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/21/agile-product-management-boot-camp/' rel='bookmark' title='Permanent Link: Agile Product Management Boot Camp'>Agile Product Management Boot Camp</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p><img src="http://www.richardlawrence.info/wp-content/uploads/2009/10/matryoshka.jpg" alt="Matryoshka" title="Matryoshka" width="200" height="166" class="alignright size-full wp-image-210" />Good user stories follow Bill Wake&#8217;s <a href="http://xp123.com/xplor/xp0308/index.shtml">INVEST model</a>. They&#8217;re <strong>I</strong>ndependent, <strong>N</strong>egotiable, <strong>V</strong>aluable, <strong>E</strong>stimable, <strong>S</strong>mall, and <strong>T</strong>estable. The <em>small</em> requirement drives us to split large stories. But the stories after splitting still have to follow the model.</p>
<p>Many new agile teams attempt to split stories by architectural layer: one story for the UI, another for the database, etc. This may satisfy <em>small</em>, but it fails at <em>independent</em> and <em>valuable</em>.</p>
<p>Over my years with agile, I&#8217;ve discovered nine patterns for splitting user stories into good, smaller stories. <span id="more-190"></span></p>
<p><em>(Note: As with any pattern language, I didn&#8217;t invent these patterns, I&#8217;ve just observed and compiled them. For example, <a href="http://radio.javaranch.com/lasse/2008/06/13/1213375107328.html">this great post</a> by Lasse Koskela put names on some patterns I&#8217;d observed but not named, especially &#8220;Major Effort.&#8221;)</em></p>
<h3>How Small?</h3>
<p>How small should stories be? I recommend 6-10 stories per iteration, so how small is small enough depends on your team&#8217;s velocity. Before your next planning meeting calculate what estimate should trigger splitting a story. For most teams, it seems to be 8 or 13 points. But on a recent project I&#8217;m doing by myself, I&#8217;ve needed to split 5-point stories.</p>
<p>When you&#8217;re in a planning meeting and you hit your trigger estimate, pull out the cheat sheet at the end of this article and try a few of the patterns until you find a good split.</p>
<h3>Which Pattern to Use</h3>
<p>You&#8217;ll often find that you can split a story using several of the patterns. Which split should you choose? I use two rules of thumb:</p>
<ol>
<li><strong>Choose the split that lets you deprioritize or throw away a story.</strong> The 80/20 principle says that most of the value of a user story comes from a small share of the functionality. When one split reveals low-value functionality and another doesn&#8217;t, it suggests that the latter split hides waste inside each of the small stories. Go with the split that lets you throw away the low-value stuff.</li>
<li><strong>Choose the split that gets you more equally sized small stories.</strong> The split that turns an 8 point story into four 2 point stories is more useful than the one that produces a 5 and a 3. It gives the Product Owner more freedom to prioritize parts of the functionality separately.</li>
</ol>
<h3>Pattern #1: Workflow Steps</h3>
<p>Here&#8217;s a story from a content management system one of my clients was creating:</p>
<blockquote><p>
As a content manager, I can publish a news story to the corporate website.
</p></blockquote>
<p>Didn’t sound too big&mdash;until we dug into the workflow to get a story published. It turned out that just to get a few sentence news story on the corporate website required both editorial and legal approval and final review on a staging site. There&#8217;s no way 6-10 stories like this would fit in an iteration.</p>
<p>In a workflow like this, the biggest value often comes from the beginning and end. The middle steps add incremental value, but don&#8217;t stand alone. So it can work well to build the simple end-to-end case first and then add the middle steps and special cases.</p>
<p>The new stories included:</p>
<blockquote><p>
&#8230;I can publish a news story directly to the corporate website.<br />
&#8230;I can publish a news story with editor review.<br />
&#8230;I can publish a news story with legal review.<br />
&#8230;I can view a news story on a staging site.<br />
&#8230;I can publish a news story from the staging site to production.
</p></blockquote>
<h3>Pattern #2: Business Rule Variations</h3>
<p>This story has a few equally complex stories hidden within it that accomplish the same thing using different business rules:</p>
<blockquote><p>
As a user, I can search for flights with flexible dates.
</p></blockquote>
<p>Digging into &#8220;flexible dates&#8221; reveals several different business rules, each of which can be a good story on its own:</p>
<blockquote><p>
&#8230;as &#8220;n days between x and y.&#8221;<br />
&#8230;as &#8220;a weekend in December.&#8221;<br />
&#8230;as &#8220;&plusmn; n days of x and y.&#8221;
</p></blockquote>
<h3>Pattern #3: Major Effort</h3>
<p>Sometimes a story can be split into several parts where most of the effort will go towards implementing the first one. For example, this credit card processing story,</p>
<blockquote><p>
As a user, I can pay for my flight with VISA, MasterCard, Diners Club, or American Express.
</p></blockquote>
<p>could be split into four stories, one for each card type. But the credit card processing infrastructure will be built to the support the first story; adding more card types will be relatively trivial. We could estimate the first story larger than the other three, but then we have to remember to change our estimates if the Product Owner later changes priorities. Instead, we should defer the decision about which card type gets implemented first like this:</p>
<blockquote><p>
&#8230;I can pay with one credit card type (of VISA, MC, DC, AMEX).<br />
&#8230;I can pay with all four credit card types (VISA, MC, DC, AMEX) (given one card type already implemented).
</p></blockquote>
<p>The two new stories still aren&#8217;t independent, but the dependency is much clearer than it would be with a story for each card type.</p>
<h3>Pattern #4: Simple/Complex</h3>
<p>When you&#8217;re in a planning meeting discussing a story, and the story seems to be getting larger and larger (&#8220;what about x?&#8221;; &#8220;have you considered y?&#8221;), stop and ask, &#8220;What&#8217;s the simplest version of this?&#8221; Capture that simple version as its own story. You&#8217;ll probably have to define some acceptance criteria on the spot to keep it simple. Then, break out all the variations and complexities into their own stories. So, for example, this story,</p>
<blockquote><p>
As a user, I can search for flights between two destinations.
</p></blockquote>
<p>stays simple by splitting off variations like,</p>
<blockquote><p>
&#8230;specifying a max number of stops.<br />
&#8230;including nearby airports.<br />
&#8230;using flexible dates.<br />
&#8230;etc.
</p></blockquote>
<h3>Pattern #5: Variations in Data</h3>
<p>Complexity in a story can come from handling variations in data. For example, a system I&#8217;m currently working on needs to model geographic areas served by transportation providers. We could have burned our whole project budget just handing geography; it&#8217;s potentially that complex. When I talked through the story,</p>
<blockquote><p>
As a user, I can search for transportation providers by trip origin and destination.
</p></blockquote>
<p>with our Product Owner, I discovered that, while we didn&#8217;t need full-fledged GIS, modeling geography would still be quite complex. We stopped and asked, &#8220;What&#8217;s the &#8216;good enough&#8217; way to model geography so we can build other high-value features now?&#8221; We settled on,</p>
<blockquote><p>
As a user, I can search for transportation providers by trip origin and destination as counties.
</p></blockquote>
<p>This worked for a while, until we collected more data and found that some providers only served certain cities or even neighborhoods. So a new story came up:</p>
<blockquote><p>
As a user, I can search for transportation providers by trip origin and destination as counties, cities, towns, or neighborhoods.
</p></blockquote>
<p>Looking over the new provider data, we also discovered that some providers will support trips originating in a single city but ending in any number of surrounding cities. This led to the story:</p>
<blockquote><p>
Providers can serve different geographic areas for trip origin and destination.
</p></blockquote>
<p>All three of these stories are split from the original geography story. The difference here is that we added stories just-in-time after building the simplest version. But sometimes you know the data variations up-front. The classic example is localization:</p>
<blockquote><p>
As a content manager, I can create news stories.<br />
&#8230;in English.<br />
&#8230;in Japanese.<br />
&#8230;in Arabic.<br />
&#8230;etc.
</p></blockquote>
<h3>Pattern #6: Data Entry Methods</h3>
<p>Complexity sometimes is in the user interface rather than in the functionality itself. In that case, split the story to build it with the simplest possible UI and then build the more usable or fancier UI. These, of course, aren&#8217;t independent&mdash;the second story effectively is the original story if you do it first&mdash;but it still can be a useful split.</p>
<blockquote><p>
As a user, I can search for flights between two destinations.<br />
&#8230;using simple date input.<br />
&#8230;with a fancy calendar UI.
</p></blockquote>
<h3>Pattern #7: Defer Performance</h3>
<p>Sometimes, a large part of the effort is in making a feature fast&mdash;the initial implementation isn’t all that hard. But you can learn a lot from the slow implementation and it has some value to a user who wouldn&#8217;t otherwise be able to do the action in the story. In this case, break the story into &#8220;make it work&#8221; and &#8220;make it fast&#8221;:</p>
<blockquote><p>
As a user, I can search for flights between two destinations.<br />
&#8230;(slow&mdash;just get it done, show a &#8220;searching&#8221; animation).<br />
&#8230;(in under 5 seconds).
</p></blockquote>
<h3>Pattern #8: Operations (e.g. CRUD)</h3>
<p>The word &#8220;manage&#8221; in a user story is a giveaway that the story covers multiple operations. This offers a natural way to split the story. For example:</p>
<blockquote><p>
As a user, I can manage my account.<br />
&#8230;I can sign up for an account.<br />
&#8230;I can edit my account settings.<br />
&#8230;I can cancel my account.
</p></blockquote>
<h3>Pattern #9: Break Out a Spike</h3>
<p>A story may be large not because it&#8217;s necessarily complex, but because the implementation is poorly understood. In this case, no amount of talking about the business part of the story will allow you to break it up. Do a time-boxed spike first to resolve uncertainty around the implementation. Then, you can do the implementation or have a better idea of how to break it up. Don&#8217;t know how to implement the following story?</p>
<blockquote><p>
As a user, I can pay by credit card.
</p></blockquote>
<p>Then, break it into:</p>
<blockquote><p>
Investigate credit card processing.<br />
Implement credit card processing.
</p></blockquote>
<p>In the &#8220;investigate&#8221; story, the acceptance criteria should be questions you need answered. Do just enough investigation to answer the questions and stop; it&#8217;s easy to get carried away doing research.</p>
<p>The spike split is last because it should be your last resort. You probably know enough to build something. Do that, and you&#8217;ll know more. So, make every effort to use one of the previous eight patterns before resorting to the spike pattern.</p>
<h3>Conclusion</h3>
<p>Resist the temptation to split an overly large user story by architectural layers. Instead, try these patterns to split your story into smaller stories that still satisfy the INVEST model. Let me know how it works for you or if you&#8217;ve run into unsplittable stories (I love a challenge!).</p>
<p><a href='http://www.richardlawrence.info/wp-content/uploads/2009/10/Story-Splitting-Cheat-Sheet.pdf'>Download the Story Splitting Cheat Sheet</a></p>


<p>Related posts:<ol><li><a href='http://www.richardlawrence.info/2008/12/10/when-stories-are-larger-than-planned/' rel='bookmark' title='Permanent Link: Short Answers #1: When Stories Are Larger Than Planned'>Short Answers #1: When Stories Are Larger Than Planned</a></li>
<li><a href='http://www.richardlawrence.info/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/' rel='bookmark' title='Permanent Link: WatiN Patterns #2: One Assertion and a Name to Match'>WatiN Patterns #2: One Assertion and a Name to Match</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/21/agile-product-management-boot-camp/' rel='bookmark' title='Permanent Link: Agile Product Management Boot Camp'>Agile Product Management Boot Camp</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlawrence.info/2009/10/28/patterns-for-splitting-user-stories/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WatiN Patterns #2: One Assertion and a Name to Match</title>
		<link>http://www.richardlawrence.info/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/</link>
		<comments>http://www.richardlawrence.info/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 23:46:19 +0000</pubDate>
		<dc:creator>Richard Lawrence</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[WatiN]]></category>
		<category><![CDATA[WatiN Patterns]]></category>

		<guid isPermaLink="false">http://www.richardlawrence.info/?p=146</guid>
		<description><![CDATA[One way to keep your WatiN tests maintainable is to keep them small and focused. WatiN Pattern #2, then, is a way to do just that. Your tests should assert one thing. Just one. And the name of the test should describe whatever it is you&#8217;re asserting. Looking at our example from last time, we [...]


Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/02/04/watin-patterns-1-no-browser-left-behind/' rel='bookmark' title='Permanent Link: WatiN Patterns #1: No Browser Left Behind'>WatiN Patterns #1: No Browser Left Behind</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/24/another-look-at-watin/' rel='bookmark' title='Permanent Link: Another Look at WatiN'>Another Look at WatiN</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/19/web-testing-for-net-teams-watin-or-watir/' rel='bookmark' title='Permanent Link: Web Testing for .NET Teams: WatiN or Watir?'>Web Testing for .NET Teams: WatiN or Watir?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p>One way to keep your WatiN tests maintainable is to keep them small and focused. WatiN Pattern #2, then, is a way to do just that.</p>
<p><span id="more-146"></span></p>
<p>Your <strong>tests should assert one thing</strong>. Just one. And <strong>the name of the test should describe whatever it is you&#8217;re asserting</strong>. Looking at our example from <a href="/2009/02/04/watin-patterns-1-no-browser-left-behind/">last time</a>, we see that we&#8217;ve got the one assertion part right, but the name doesn&#8217;t match.</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SearchPageTest<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008000;">&#40;</span>IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://www.google.com/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;q&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Richard Lawrence&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;btnG&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;www.richardlawrence.info&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>In a nod to the <a href="http://dannorth.net/introducing-bdd">BDD approach</a> (more BDD to show up in future patterns), I like to <strong>name the test class for the thing we&#8217;re testing and use test names starting with &#8220;Should&#8221; that specify what the thing we&#8217;re testing ought to do</strong>. So, we could change our example to something like this:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080; font-style: italic;">// using statements, namespace declaration, etc.</span><br />
<span style="color: #008080; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#91;</span>TestClass<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> GoogleSearchPage<br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// ...</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> ShouldReturnSearchResultsSuccessfully<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008000;">&#40;</span>IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://www.google.com/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;q&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Richard Lawrence&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;btnG&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;www.richardlawrence.info&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Now we have one assertion, and our test name indicates that it&#8217;s asserting that the Google search page should return search results successfully. <strong>If that test fails, we know what&#8217;s gone wrong.</strong></p>
<p>It&#8217;s not yet transparent that the assertion on line 17 does what the test name indicates, but we&#8217;ll deal with that in future patterns.</p>


<p>Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/02/04/watin-patterns-1-no-browser-left-behind/' rel='bookmark' title='Permanent Link: WatiN Patterns #1: No Browser Left Behind'>WatiN Patterns #1: No Browser Left Behind</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/24/another-look-at-watin/' rel='bookmark' title='Permanent Link: Another Look at WatiN'>Another Look at WatiN</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/19/web-testing-for-net-teams-watin-or-watir/' rel='bookmark' title='Permanent Link: Web Testing for .NET Teams: WatiN or Watir?'>Web Testing for .NET Teams: WatiN or Watir?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlawrence.info/2009/02/11/watin-patterns-2-one-assertion-and-a-name-to-match/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WatiN Patterns #1: No Browser Left Behind</title>
		<link>http://www.richardlawrence.info/2009/02/04/watin-patterns-1-no-browser-left-behind/</link>
		<comments>http://www.richardlawrence.info/2009/02/04/watin-patterns-1-no-browser-left-behind/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 23:35:44 +0000</pubDate>
		<dc:creator>Richard Lawrence</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[WatiN]]></category>
		<category><![CDATA[WatiN Patterns]]></category>

		<guid isPermaLink="false">http://www.richardlawrence.info/?p=119</guid>
		<description><![CDATA[In my previous posts on WatiN, I lamented the shortage of online documentation and resolved to do something about it by documenting the patterns I&#8217;ve found for good WatiN tests. This is the first in a series in which I&#8217;ll take an example of the typical beginner WatiN test I see and refactor it to [...]


Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/01/24/another-look-at-watin/' rel='bookmark' title='Permanent Link: Another Look at WatiN'>Another Look at WatiN</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/19/web-testing-for-net-teams-watin-or-watir/' rel='bookmark' title='Permanent Link: Web Testing for .NET Teams: WatiN or Watir?'>Web Testing for .NET Teams: WatiN or Watir?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p>In my <a href="/2009/01/19/web-testing-for-net-teams-watin-or-watir/" title="Web Testing for .NET Teams: WatiN or Watir?">previous</a> <a href="/2009/01/24/another-look-at-watin/" title="Another Look at WatiN">posts</a> on WatiN, I lamented the shortage of online documentation and resolved to do something about it by documenting the patterns I&#8217;ve found for good WatiN tests. This is the first in a <a href="/tag/watin-patterns/" title="All WatiN Patterns posts">series</a> in which I&#8217;ll take an example of the typical beginner WatiN test I see and refactor it to use the patterns I recommend.</p>
<p>Consider this test:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SearchPageTest<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://www.google.com/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;q&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Richard Lawrence&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;btnG&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;www.richardlawrence.info&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Close</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>It has a few problems, but I want to highlight one in this post: <strong>This test doesn&#8217;t properly clean up after itself.</strong> If the code on lines 66-70 throws an exception or if the assertion fails, line 71 will never be executed. When you&#8217;re testing on your own machine, this can be annoying&mdash;you have to close the IE window manually. But if the test runs unattended (e.g. as part of continuous integration) it can be much more than annoying.</p>
<p><span id="more-119"></span></p>
<p>I&#8217;ve sometimes seen this attempt to work around the problem:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SearchPageTest<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://www.google.com/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;q&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Richard Lawrence&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;btnG&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">bool</span> resultsFound <span style="color: #008000;">=</span> ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;www.richardlawrence.info&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Close</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>resultsFound<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Introducing a local boolean to indicate success and closing the browser before the assertion ensures that the browser gets closed whether the assertion fails or succeeds. However, it won&#8217;t necessarily close the browser in case of an exception.</p>
<p>Fortunately, WatiN.Core.IE implements IDisposable, so you can do this:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SearchPageTest<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008000;">&#40;</span>IE ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">GoTo</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;http://www.google.com/&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;q&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TypeText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Richard Lawrence&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Button</span><span style="color: #008000;">&#40;</span>Find<span style="color: #008000;">.</span><span style="color: #0000FF;">ByName</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;btnG&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Click</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsTrue</span><span style="color: #008000;">&#40;</span>ie<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;www.richardlawrence.info&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>In case you&#8217;re not familar with the &#8220;using&#8221; statement, it&#8217;s a shortcut for this:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; IE ie<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">try</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ie <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> IE<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// whatever you're going to do with ie</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">finally</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>ie <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie<span style="color: #008000;">.</span><span style="color: #0000FF;">Dispose</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>At the end of the using block (or when an exception is thrown) ie.Dispose() is called, which closes the browser window.</p>
<p><strong>Use this pattern in your WatiN tests to ensure that your tests clean up after themselves and leave no browser window behind.</strong></p>


<p>Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/01/24/another-look-at-watin/' rel='bookmark' title='Permanent Link: Another Look at WatiN'>Another Look at WatiN</a></li>
<li><a href='http://www.richardlawrence.info/2009/01/19/web-testing-for-net-teams-watin-or-watir/' rel='bookmark' title='Permanent Link: Web Testing for .NET Teams: WatiN or Watir?'>Web Testing for .NET Teams: WatiN or Watir?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlawrence.info/2009/02/04/watin-patterns-1-no-browser-left-behind/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Another Look at WatiN</title>
		<link>http://www.richardlawrence.info/2009/01/24/another-look-at-watin/</link>
		<comments>http://www.richardlawrence.info/2009/01/24/another-look-at-watin/#comments</comments>
		<pubDate>Sat, 24 Jan 2009 16:29:50 +0000</pubDate>
		<dc:creator>Richard Lawrence</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[Agile 2009]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[WatiN]]></category>
		<category><![CDATA[Watir]]></category>

		<guid isPermaLink="false">http://www.richardlawrence.info/?p=115</guid>
		<description><![CDATA[At my current client, we&#8217;ve decided to use WatiN, largely for the C# vs. Ruby reason I discussed earlier this week. After spending a week working with WatiN (following a year of rarely using it), I&#8217;m impressed. Ruby and the active Watir community still have their advantages. But WatiN has really come into its own [...]


Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/01/19/web-testing-for-net-teams-watin-or-watir/' rel='bookmark' title='Permanent Link: Web Testing for .NET Teams: WatiN or Watir?'>Web Testing for .NET Teams: WatiN or Watir?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p>At my current client, we&#8217;ve decided to use <a href="http://watin.sourceforge.net/">WatiN</a>, largely for the C# vs. Ruby reason I <a href="/2009/01/19/web-testing-for-net-teams-watin-or-watir/">discussed earlier this week</a>. After spending a week working with WatiN (following a year of rarely using it), I&#8217;m impressed. Ruby and the active Watir community still have their advantages. But WatiN has really come into its own with C# 3.0 features like lambdas. I&#8217;m pleased with the test code we&#8217;re producing in terms of readability, speed, flexibility, and maintainability. I&#8217;ve proposed an <a href="http://agile2009.agilealliance.org/">Agile 2009</a> tutorial <a title="Please log in and add comments on my session proposal." href="http://agile2009.agilealliance.org/node/505">session</a> on the patterns I&#8217;m using to get those results, and I&#8217;ll post more on that topic here soon. (Which will hopefully help with one of WatiN&#8217;s shortcomings—documentation.)</p>


<p>Related posts:<ol><li><a href='http://www.richardlawrence.info/2009/01/19/web-testing-for-net-teams-watin-or-watir/' rel='bookmark' title='Permanent Link: Web Testing for .NET Teams: WatiN or Watir?'>Web Testing for .NET Teams: WatiN or Watir?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlawrence.info/2009/01/24/another-look-at-watin/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
