<?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>James Gregory &#187; TDD</title>
	<atom:link href="http://jagregory.com/writings/category/tdd/feed/" rel="self" type="application/rss+xml" />
	<link>http://jagregory.com</link>
	<description>Monkeying with the code</description>
	<lastBuildDate>Tue, 22 Jun 2010 11:07:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>All about dependencies</title>
		<link>http://jagregory.com/writings/all-about-dependencies/</link>
		<comments>http://jagregory.com/writings/all-about-dependencies/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 16:24:05 +0000</pubDate>
		<dc:creator>James Gregory</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Alt.Net]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.jagregory.com/2008/04/05/all-about-dependencies/</guid>
		<description><![CDATA[This article serves as an introduction to the concept of Dependency Injection, and why you&#8217;d want to use it. It is not a getting started guide for using containers. If you&#8217;re interested in those, my personal preference is Castle Windsor and you can find their getting started guide here.
What are dependencies? Also referred to as [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>This article serves as an introduction to the concept of <a href="http://martinfowler.com/articles/injection.html">Dependency Injection</a>, and why you&#8217;d want to use it. It is not a getting started guide for using containers. If you&#8217;re interested in those, my personal preference is <a href="http://www.castleproject.org/container/">Castle Windsor</a> and you can find their <a href="http://www.castleproject.org/container/gettingstarted/index.html">getting started guide here</a>.</p></blockquote>
<p>What are dependencies? Also referred to as couplings, dependencies are other modules that one module requires to fulfill it&#8217;s purpose.</p>
<p>Are dependencies bad? No, of course they&#8217;re not, otherwise we wouldn&#8217;t be able to create anything. However, highly coupled code can cause a lot of problems for your application.</p>
<p>If your code requires knowledge of how a dependency works, then your code is highly coupled. If your code is tied explicitly to an implementation, then your code is also highly coupled.</p>
<p>Take the following example:</p>
<pre name="code" class="c-sharp">
public class ProductUpdater
{
	public void StoreChanges(Product product)
	{
	  SqlDataStore dataStore = new SqlDataStore();

	  dataStore.CreateConnection();
	  dataStore.OpenConnection();

	  dataStore.Update(product);

	  dataStore.CloseConnection();
	}
}
</pre>
<p>The above example is highly coupled to the <code>SqlDataStore</code>. Firstly, it directly creates an instance, which means there&#8217;s no way for us to replace that instance if we need to (I&#8217;ll come to why you&#8217;d want to do that in a bit). Secondly, it relies on a great deal of knowledge of <code>SqlDataStore</code>&#8217;s implementation. In this code we can see that you need to create a connection and open it before you can update the record; that&#8217;s quite a bit of implementation knowledge. If the <code>SqlDataStore</code> was to change so that the <code>OpenConnection</code> method created a connection if one didn&#8217;t already exist, then we&#8217;d need to change every caller of  that code to remove the <code>CreateConnection</code> call; in large system situations like that can quickly lead to a fear of change and refactoring.</p>
<p>I mentioned directly creating an instance stops us from replacing it if need be.  Well when would you actually want to do this? For those unfamiliar with unit testing, you probably haven&#8217;t encountered <a href="http://www.martinfowler.com/bliki/TestDouble.html">test doubles</a>; there are different types of test doubles, but for the purposes of this example they&#8217;re interchangeable.</p>
<p>A test double serves as a swap-in replacement for one of your dependencies. These allow you to execute a piece of code under test, without having to worry about whether things are being put in your database, or e-mails sent for example. If your code is creating instances within methods, those instances cannot be replaced by a test double. Without that ability, testing becomes considerably more difficult.</p>
<p>Tightly tying your code to an instance of a class reduces the flexibility and reuse of your code. Take the above example, that same code could be used to update the product in a cache instead of the database; similarly, you could use an in-memory storage instead of a database for when you&#8217;re running in a test or demo environment. If only your method wasn&#8217;t so tightly tied to the implementation.</p>
<p>This is solved by using <a href="http://martinfowler.com/articles/injection.html">Dependency Injection</a>, which is a part of the <a href="http://en.wikipedia.org/wiki/Dependency_inversion_principle"Dependency Inversion Principal</a> and <a href="http://en.wikipedia.org/wiki/Inversion_of_Control">Inversion of Control</a>.</p>
<blockquote><p>[DIP] seeks to &#8220;invert&#8221; the conventional notion that high level modules in software should depend upon the lower level modules. The principle states that high level or low level modules should not depend upon each other, instead they should depend upon abstractions. &#8212; Wikipedia</p></blockquote>
<p>Essentially, dependency injection allows you to stop instantiating your dependencies. Instead they&#8217;re &#8220;injected&#8221; into your object when it is instantiated itself. This allows the dependencies to be swapped out like we mentioned above.</p>
<p>So taking the original example, here&#8217;s a version of it that&#8217;s been updated to use dependency injection.</p>
<pre name="code" class="c-sharp">
public class ProductUpdater
{
	private SqlDataStore dataStore;

	public ProductUpdater(SqlDataStore dataStore)
	{
		this.dataStore = dataStore;
	}

	public void StoreChanges(Product product)
	{
	  dataStore.CreateConnection();
	  dataStore.OpenConnection();

	  dataStore.Update(product);

	  dataStore.CloseConnection();
	}
}
</pre>
<p>The above implementation now allows us to create a test double, and replace the <code>SqlDataStore</code> in our tests. As I mentioned before, we could now easily push in an in-memory implementation without any changes to the code required.</p>
<p>We can take this further though, because we&#8217;re still tied to a concrete class. Lets make <code>SqlDataStore</code> implement an interface, so we can create other implementations.</p>
<pre name="code" class="c-sharp">
public interface IDataStore
{
	void CreateConnection();
	void OpenConnection();
	void Update(Product product);
	void CloseConnection();
}

public class ProductUpdater
{
	private IDataStore dataStore;

	public ProductUpdater(IDataStore dataStore)
	{
		this.dataStore = dataStore;
	}

	public void StoreChanges(Product product)
	{
	  dataStore.CreateConnection();
	  dataStore.OpenConnection();

	  dataStore.Update(product);

	  dataStore.CloseConnection();
	}
}
</pre>
<p>Now our example is no longer specifically tied to a <code>SqlDataStore</code>, so we could quite easily pass it a <code>FileSystemDataStore</code>, or an <code>InMemoryDataStore</code>, or anything else that implements <code>IDataStore</code>. All that without having to touch a single line within the <code>ProductUpdater</code>.</p>
<p>That&#8217;s the power of dependency injection, and why you should stop hard-coding your dependencies.</p>
]]></content:encoded>
			<wfw:commentRss>http://jagregory.com/writings/all-about-dependencies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On testing implementation</title>
		<link>http://jagregory.com/writings/on-testing-implementation/</link>
		<comments>http://jagregory.com/writings/on-testing-implementation/#comments</comments>
		<pubDate>Mon, 10 Dec 2007 21:02:22 +0000</pubDate>
		<dc:creator>James Gregory</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.jagregory.com/2007/12/10/on-testing-implementation/</guid>
		<description><![CDATA[I&#8217;ve found my-self in the situation of retro-fitting a library of code with unit tests, not a good situation to be in. However, what&#8217;s more concerning is I&#8217;ve just caught my-self writing tests that are heavily testing the implementation of a method; rather than simply testing if the method does what it&#8217;s supposed to.
There are [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve found my-self in the situation of retro-fitting a library of code with unit tests, not a good situation to be in. However, what&#8217;s more concerning is I&#8217;ve just caught my-self writing tests that are heavily testing the implementation of a method; rather than simply testing if the method does what it&#8217;s supposed to.</p>
<p>There are a few problems with falling into this trap. Firstly, it&#8217;s very brittle. Secondly, you shouldn&#8217;t be concerned with the internals. Thirdly, it&#8217;s very time consuming.</p>
<p>To elaborate&#8230;</p>
<p>It&#8217;s brittle because you&#8217;re essentially writing a script of how the method is going to execute, which of course will change whenever you do any refactoring. So your tests break every time you make a change to your code, which is not only annoying, but will quickly lead to <a href="http://martinfowler.com/bliki/TestCancer.html">test cancer</a>, where tests aren&#8217;t run or are commented out.</p>
<p>You shouldn&#8217;t be concerned with the internals, because as long as your method is doing as requested, you shouldn&#8217;t really care how it&#8217;s achieving it&#8217;s goal. Not bolting down the internals allows methods to be refactored without too much resistance from the tests. This will increase the signal-to-noise ratio, allowing failing tests to be representative of a problem greater than your basic refactorings.</p>
<p>Finally, it&#8217;s time consuming simply because you&#8217;re duplicating most of your work. All the time you spent writing the method (or the test, if done first) is then duplicated writing the tests (or code&#8230;). This is a pain, because as mentioned above, you&#8217;ll keep doing this work every time you change the method.</p>
<p>The hardest part is learning how to not do this kind thing blindly. There are plenty of times when you&#8217;ll need this kind of testing, but don&#8217;t make it your default! Test expectations, not implementations.</p>
]]></content:encoded>
			<wfw:commentRss>http://jagregory.com/writings/on-testing-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DeleGrid &#8211; a paged GridView control</title>
		<link>http://jagregory.com/writings/delegrid/</link>
		<comments>http://jagregory.com/writings/delegrid/#comments</comments>
		<pubDate>Sun, 09 Dec 2007 16:47:21 +0000</pubDate>
		<dc:creator>James Gregory</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Hobby Projects]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.jagregory.com/2007/12/09/delegrid/</guid>
		<description><![CDATA[Introducing the DeleGrid
The DeleGrid is a control derived from the ASP.Net GridView, that delegates its data retrieval back out of the control. This allows the developer full control over the records that are retrieved, thus allowing proper paging to be implemented using whatever collection type you prefer.
Why the DeleGrid?
It came about because I wanted a [...]]]></description>
			<content:encoded><![CDATA[<h3>Introducing the DeleGrid</h3>
<p>The DeleGrid is a control derived from the ASP.Net GridView, that delegates its data retrieval back out of the control. This allows the developer full control over the records that are retrieved, thus allowing proper paging to be implemented using whatever collection type you prefer.</p>
<h4>Why the DeleGrid?</h4>
<p>It came about because I wanted a nice way of implementing paging using NHibernate without having the grid know about it. I really didn&#8217;t want NHibernate to leave my data layer, so I needed a nice way of the grid calling my DAL with the paging parameters.</p>
<p>I didn&#8217;t want to utilise the ObjectDataSource because honestly, it made me feel dirty. I&#8217;m all for delegation and composition, but not when it means creating a control in my HTML that acts as a DAL. Additionally, I didn&#8217;t feel the ObjectDataSource was very type-safe, or refactor-friendly, with the method names and types exposed in the HTML. Granted, the IDE would probably pick it up, but I don&#8217;t want to risk a runtime failure on it.</p>
<h3>Using the DeleGrid (aka The Example)</h3>
<p>After getting the source or assembly and doing the usual song-and-dance, add a reference to the control to your page:</p>
<pre name="code" class="html">
&lt;%@ Register Assembly=&quot;JAGregory.Controls.DeleGrid&quot;
  Namespace=&quot;JAGregory.Controls&quot; TagPrefix=&quot;jag&quot; %&gt;
</pre>
<p>Then create an instance of the control, turning the paging on and setting the correct page size:</p>
<pre name="code" class="html">
&lt;jag:DeleGrid ID=&quot;grid&quot; runat=&quot;server&quot; AllowPaging=&quot;true&quot;
  PageSize=&quot;4&quot; /&gt;
</pre>
<p>Now you have a control set up, however it sill won&#8217;t bind correctly. So, you need to attach the event handlers in the code-behind.</p>
<pre name="code" class="c-sharp">
protected override void OnInit(EventArgs eventArgs)
{
  base.OnInit(eventArgs);

  grid.TotalRecordCountRequest += delegate {
    // code to get total
  };
}
</pre>
<p>Starting with the TotalRecordCountRequest, this event is raised when the grid needs to know how many records in total your grid is going to be displaying. This number is the cumulative count of all the pages. I&#8217;m going to use a simple repository pattern to factor away my DAL logic.</p>
<p>The OnInit method is now:</p>
<pre name="code" class="c-sharp">
protected override void OnInit(EventArgs eventArgs)
{
  base.OnInit(eventArgs);

  ProductRepository repos = new ProductRepository();

  grid.TotalRecordCountRequest += delegate {
    return repos.GetTotal();
  };
}
</pre>
<p>Now your grid knows how many records it has overall, however we still haven&#8217;t told it how to actually get the data. So now to put the code in the PageDataRequest handler. This event is raised when the grid is needing a new page of data, this will get called once on initial data-bind, then again every time you change the page (or sorting etc&#8230;).</p>
<p>The OnInit method is now:</p>
<pre name="code" class="c-sharp">
protected override void OnInit(EventArgs eventArgs)
{
  base.OnInit(eventArgs);

  ProductRepository repos = new ProductRepository();

  grid.TotalRecordCountRequest += delegate {
    return repos.GetTotal();
  };
  grid.PageDataRequest += delegate(object sender, DataRequestEventArgs e) {
    return repos.GetRange(e.Start, e.Size);
  };
}
</pre>
<p>The event-handler receives an instance of DataRequestEventArgs, which contains the start index of the current page of data, and the number of records in a page. It also contains a SortField and SortDirection, for when sorting is enabled on the grid; however, we aren&#8217;t utilising them in this example.</p>
<p>Finally we just need to bind the grid on page load. We don&#8217;t re-bind the grid on post-back, due to that being handled internally in the DeleGrid.</p>
<pre name="code" class="c-sharp">
protected override void OnLoad(EventArgs eventArgs)
{
  base.OnLoad(eventArgs);

  if (!IsPostBack)
    grid.DataBind();
}
</pre>
<p>That&#8217;s all there is to it!</p>
<p>You don&#8217;t need to use delegates, the normal event-handler syntax is fine (and probably preferred for larger examples). I just did it this way for brevity&#8217;s sake.</p>
<h3>Further reading&#8230;</h3>
<h4>Testing</h4>
<p>I&#8217;ve written a small number of tests that cover the implementation of the grid as best I can. There was only so-far I was willing to go to test the control, as it&#8217;s heavily tied to the ASP.Net implementation; which can get pretty messy for testing without using something like NUnitASP, which was a bit much for one control.. I&#8217;ve got coverage of about 85% of the code, which I&#8217;d say is pretty reasonable anyway.</p>
<h4>Sorting</h4>
<p>As mentioned above, you can implement sorting in your handlers by accessing the SortField and SortDirection properties of the event arguments.</p>
<h4>DeleGrid.AlwaysRequestTotal</h4>
<p>By default the DeleGrid only requests the total number of records on the initial data-bind, however if you see this as being a problem (such as with rapidly changing data-sets), you may want to set this property to true so it refreshes the total on every data-bind.</p>
<h3>Downloads</h3>
<p>The DeleGrid is open-source under the <a href="http://en.wikipedia.org/wiki/BSD_licenses">new BSD License</a>; read the license for what you&#8217;re allowed to do.</p>
<p>You can download the source here: <a href="http://jagregory.googlecode.com/files/DeleGrid-1.0-source.zip">Download Source</a>.<br />
You can download the latest binary here: <a href="http://jagregory.googlecode.com/files/DeleGrid-1.0.zip">Download Binary</a>.</p>
<p>The source is also accessible from Subversion at: <a href="http://jagregory.googlecode.com/svn/trunk/DeleGrid/">http://jagregory.googlecode.com/svn/trunk/DeleGrid/</a> (using user jagregory-read-only)</p>
<p><strong>All patches are welcomed with open arms!</strong></p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblog.jagregory.com%2f2007%2f12%2f09%2fdelegrid%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblog.jagregory.com%2f2007%2f12%2f09%2fdelegrid%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jagregory.com/writings/delegrid/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Test-drive properly, test fully</title>
		<link>http://jagregory.com/writings/test-drive-properly-test-fully/</link>
		<comments>http://jagregory.com/writings/test-drive-properly-test-fully/#comments</comments>
		<pubDate>Sat, 21 Jul 2007 09:48:00 +0000</pubDate>
		<dc:creator>James Gregory</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.jagregory.com/2007/07/21/test-drive-properly-test-fully/</guid>
		<description><![CDATA[I started writing this as a comment, but I felt it’s own post was deserved.
Ricky Clarkson left me a link in a comment to one of his posts that ties in quite nicely to my recent Getting with it: Test Driven Development post.
Ricky makes the point that TDD can be dangerous, and can lull you [...]]]></description>
			<content:encoded><![CDATA[<p>I started writing this as a comment, but I felt it’s own post was deserved.</p>
<p><a href="http://rickyclarkson.blogspot.com/">Ricky Clarkson</a> left me a link in a comment to one of <a href="http://rickyclarkson.blogspot.com/2007/05/you-dont-need-tdd-you-need-repl.html">his posts</a> that ties in quite nicely to my recent <a href="http://blog.jagregory.com/2007/07/17/getting-with-it-test-driven-development/">Getting with it: Test Driven Development</a> post.</p>
<p>Ricky makes the point that <span class="caps">TDD</span> can be dangerous, and can lull you into a false sense of security. <em>I agree.</em></p>
<p>As with any technology, when used incorrectly it can cause more damage than not using it at all.</p>
<p>Ricky’s example should serve as a double-barreled warning. You can’t be test-driven only when it’s convenient, and you need to have good test coverage.</p>
<h3>Being Test-Driven isn’t being Convenience-Driven</h3>
<p>Just by being in a car with seat-belts doesn’t mean they’ll save you when you crash, you need to actually wear them.</p>
<p>You can’t pick and choose which parts of <span class="caps">TDD</span> you want to use, then be surprised when it lets you down.</p>
<p>If your boss comes storming in demanding a copy of the system, tell him to wait. Remember, it’s your hide on the line, if you give him a broken system you’ll be the one to pay. If he doesn’t understand testing, lie, tell him it’s building or something similar, it doesn’t exist until it’s finished.</p>
<h3>Test coverage</h3>
<p>There’s very little more important than good test coverage, without it you’re leaving yourself wide open for problems.</p>
<p>In Ricky’s example, he’s fallen into a common problem with test design. <em>He’s only testing the expected outcome of his method.</em> We’ve all fallen into this trap at some point, but it’s a dangerous place to be. Without full coverage, just as Ricky said, you end up with a false sense of security.</p>
<p>For full test coverage of a method, you really need to test it’s expected outcome, how it handles edge-cases, and how it handles bad data.</p>
<pre name="code">
(assert (equal (point+ (point 999 987) (point 789 998)) (point 1788 1985)))
</pre>
<p>Had Ricky’s test suite included the above edge-case test, it would have caught the flaw in his method’s design, and been able to correct it. A few more like the above, to cover minus numbers and very low values, and his situation would have been greatly different.</p>
<p>If there’s a way you can improve testing, it’s to write more unit tests. Only leave those bits you really can’t test to integration. Everything else should be adequately covered.</p>
<h3>In parting</h3>
<p>Remember, using <span class="caps">TDD</span> isn’t an excuse to leave your common sense at the door. If you’re writing a method which you know is going to be used in several places, test those several places, give it very good coverage. If you’re writing a sum function like Ricky, you know how it’s going to be used, don’t just write if statements to cover all your input data, that’s using coding to make a test pass an excuse to write bad code.</p>
]]></content:encoded>
			<wfw:commentRss>http://jagregory.com/writings/test-drive-properly-test-fully/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Getting with it: Test-Driven Development</title>
		<link>http://jagregory.com/writings/getting-with-it-test-driven-development/</link>
		<comments>http://jagregory.com/writings/getting-with-it-test-driven-development/#comments</comments>
		<pubDate>Tue, 17 Jul 2007 23:38:09 +0000</pubDate>
		<dc:creator>James Gregory</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.jagregory.com/2007/07/17/getting-with-it-test-driven-development/</guid>
		<description><![CDATA[Test-driven development is a practice that has started to make some serious headway into the average developer world of .Net. The tools have reached a stage of maturity where they offer solutions to most (if not all) aspects of test-driven development. Alongside the improved tools there has been a dramatic increase in the quantity and [...]]]></description>
			<content:encoded><![CDATA[<p>Test-driven development is a practice that has started to make some serious headway into the average developer world of .Net. The tools have reached a stage of maturity where they offer solutions to most (if not all) aspects of test-driven development. Alongside the improved tools there has been a dramatic increase in the quantity and quality of articles addressing the needs of new and established test-driven developers. The combined effect of this is of a reduced learning curve for the average developer.</p>
<p>On a personal note, test-driven development is something I should have started doing a long time ago, it&#8217;s certainly something that I&#8217;ve known about long-enough to be unable to claim ignorance. I take no pride in saying that my sole reason for not learning sooner is laziness. I bet I&#8217;m not the only one though. There&#8217;s a lot to learn, and not all of it is simply new tools, some of it is mental too; rewiring your brain isn&#8217;t an easy task.</p>
<p>Having broke through the pain barrier, I can now vouch for the other side and say it really is nicer.</p>
<p>So how would I convince my-self from six months ago, that test-driven development is a worthwhile pursuit? Well after a bit of ear twisting about being lazy, I&#8217;d have to raise the point of security. I don&#8217;t mean the &#8220;IM <span class="caps">IN UR HARD DRIVE</span>, STEALIN <span class="caps">UR FILEZ</span>&#8221; security, but the knowledge that you&#8217;re the one who&#8217;ll find bugs in your code, not the tester (or worse, the customer). A record of bugless (or bug-minimal) releases will bode well at your performance reviews. That, and nobody likes people finding problems in their code, so it&#8217;s best you find them first.</p>
<p>That all sounds rather selfish and egotistical. What about the team, the flexibility, and the clean structured code-base? I&#8217;m a big advocate of a clean code-base, and a well oiled team can&#8217;t be beat, but from experience, not everybody else feels the same way. Developers tend to respond more readily to two things: money, and fun. I&#8217;m generalising of course, but your average-joe developer isn&#8217;t an altruist, he isn&#8217;t going to go out of his way to help others. Give him the prospect of some extra cash, or even just the chance to break out of the mundane, and it&#8217;s a whole different game.</p>
<p>This was the turning point for me, where test-driven development past the point of being a nice-to-have practice and entered the territory of being something that could benefit me in my daily life. I also discovered it&#8217;s pretty fun too.</p>
<blockquote>
<p>Test-Driven Development = Security in code = Security in your job</p>
</blockquote>
<p><em>N.B. I shall not be held responsible for anyone who still proceeds to lose their job, even while practicing test-driven development.</em></p>
<p>One last thing that I haven&#8217;t mentioned. There&#8217;s a feeling. A feeling of joy, a reassuring warmth. You get this feeling often when you&#8217;re test-driven. Found a bug? Write a test. Test fails. Fix the bug. Test passes. You&#8217;ve fixed the bug; knowledge, safety, and security.</p>
<h3>Learning to drive</h3>
<p>When learning how to test drive your development, it&#8217;s important to know that you aren&#8217;t specifically learning a new tool as many people have put it. Not in the same respect as learning a new <span class="caps">IDE</span> or source control system. Test-driven development isn&#8217;t something physical. As I mentioned earlier, it requires you to rewire your programming brain. Although to successfully master test-driven development you are required to learn some physical tools (<a href="http://www.nunit.org/">NUnit</a> for example), the primary change will be a<br />
mental one.</p>
<p>The most basic changes to your mental-model will be that your tests literally drive your code. You&#8217;ve probably heard it before, but you test first<sup><a href="#fn1">1</a></sup>.</p>
<p>What follows is a simple run-through of how you&#8217;d test-drive some simple development, and how changes to a system would be handled.</p>
<p>I&#8217;m going to try to keep the code as terse as possible, as to not complicate the theory with execution. There will be some boilerplate code that I will not include, such as setting up the fixtures. <a href="http://xprogramming.com">Ron Jeffries</a> provides a <a href="http://www.xprogramming.com/xpmag/acsUsingNUnit.htm">good introduction to NUnit</a> for .Net developers.</p>
<h4>The First Iteration</h4>
<p>To set the scene: you&#8217;re a developer building a system for a very small shop. They&#8217;ve been working primarily from spreadsheets, but feel they&#8217;re ready to move on to a real system.</p>
<p>While other developers are creating the rest of the system, we&#8217;re tasked with creating the method for retrieving the price for the products. As this is a very small outfit, we&#8217;re only going to start with one product. Very small outfit.</p>
<p>We&#8217;re told that the product we&#8217;re going to be passed is an Apple, so following our mantra we&#8217;re going to write our test first.</p>
<pre name="code" class="c-sharp">
[Test]
public void ReturnsCorrectPriceForApples()
{
  Inventory inventory = new Inventory();

  Assert.AreEqual(0.5, inventory.GetPrice("Apple"),
    "One apple should cost 50p.");
}
</pre>
<p>You can see that we&#8217;ve now written our first test, unfortunately this test will not pass yet as we can&#8217;t even compile.</p>
<p>Never fear, lets create the class.</p>
<pre name="code" class="c-sharp">
class Inventory
{
    public double GetPrice(string product)
    {
        return 0;
    }
}
</pre>
<p>We&#8217;ve now created the class, so the code compiles and we&#8217;re able to execute our first test.</p>
<p>It failed. This one of the key steps in test-driven development. Make a test, and make it fail, then write the functionality required to make the test pass. Baring that in mind, we&#8217;ll now modify our code to allow the test to pass.</p>
<pre name="code" class="c-sharp">
public double GetPrice(string product)
{
    return 0.5;
}
</pre>
<p>It passed, that&#8217;s one test under our belt.</p>
<p>You&#8217;ll notice that this isn&#8217;t a very good design, but we&#8217;ve written enough code for the method to work for it&#8217;s current usage. We&#8217;re letting the tests drive our code, which means we&#8217;re ending up with only the code we require. <span class="caps">YAGNI</span>: You Aren&#8217;t Gonna Need It<sup><a href="#fn2">2</a></sup>.</p>
<h4>The Second Product</h4>
<p>Our implementation of <code>GetPrice</code> is painfully simple, so simple that we don&#8217;t even support multiple products. This worked fine for us while the customer only had one product, but they&#8217;ve now expanded and have requested their second product be added. Lets write another test to cover this new request.</p>
<pre name="code" class="c-sharp">
[Test]
public void ReturnsCorrectPriceForSausages()
{
    Inventory inventory = new Inventory();

    Assert.AreEqual(2.99, inventory.GetPrice("Sausages"),
        "One pack of sausages should cost £2.99");
}
</pre>
<p>Once again, if we compile and run this test it will fail, because we&#8217;ve hard-coded the method to always return <code>£0.50</code>. So lets update the method to work for sausages too.</p>
<pre name="code" class="c-sharp">
public double GetPrice(string product)
{
    if (product == "Apple")
        return 0.5;
    else
        return 2.99;
}
</pre>
<p>The test now passes.</p>
<p>Once again, this code isn&#8217;t pretty, but it does the job. We could implement this in a much better way, but we don&#8217;t have the time, there&#8217;s always more urgent things that need doing. What&#8217;s important in what we&#8217;ve just been doing is creating the tests, which serve as our safety net for when we eventually do decide to make this code nicer. We know that by re-running our tests, our code still works as it did originally.</p>
<h4>Refactoring</h4>
<p>Fast forward a couple of months in our systems life. The customer now wants some more products adding, after all there&#8217;s only so much you can do with apples and sausages. They&#8217;ve supplied us with a list of products, with their prices:</p>
<table>
<tr>
<td><strong>Product</strong></td>
<td><strong>Price</strong></td>
</tr>
<tr>
<td>Potatoes</td>
<td>3.99</td>
</tr>
<tr>
<td>Cola</td>
<td>1.27</td>
</tr>
<tr>
<td>Bread</td>
<td>0.99</td>
</tr>
<tr>
<td>Milk</td>
<td>0.47</td>
</tr>
</table>
<p>Looking at our code, we can easily see that this is going to get messy, fast. This is where we turn to refactoring our code.</p>
<blockquote>
<p>&#8220;Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.&#8221;<br />&#8212;Martin Fowler</p>
</blockquote>
<p>Test-driven development makes it easier for a developer to refactor, as the tests you create define a contract that the code must adhere to, any breaking of the contract is immediately noticeable.</p>
<p>Lets spend a small amount of time refactoring our current implementation to make it easier for future product additions.</p>
<pre name="code" class="c-sharp">
class Inventory
{
    private Dictionary&lt;string, double&gt; products;

    public Inventory()
    {
        products = new Dictionary&lt;string, double&gt;();

        products["Apple"] = 0.5;
        products["Sausages"] = 2.99;
    }

    public double GetPrice(string product)
    {
        return products[product];
    }
}
</pre>
<p>We&#8217;ve now made the code a bit cleaner, and the design a little bit more flexible. If we now re-run our tests, we will see that everything still passes. We are safe in the knowledge that everything the customer requested previously still works. We&#8217;re now safe to proceed with their new request, adding the new products. Thanks to our refactoring, this change is nice and easy. First things first, we need to create our tests to cover this requirement.</p>
<pre name="code" class="c-sharp">
[Test]
public void ReturnsCorrectPricesForOtherProducts()
{
    Inventory inventory = new Inventory();

    Assert.AreEqual(3.99, inventory.GetPrice("Potatoes"),
        "Potatoes should be £3.99.");
    Assert.AreEqual(1.27, inventory.GetPrice("Cola"),
        "Cola should be £1.27.");
    Assert.AreEqual(0.99, inventory.GetPrice("Bread"),
        "Bread should be 99p.");
    Assert.AreEqual(0.47, inventory.GetPrice("Milk"),
        "Milk should be 47p.");
}
</pre>
<p>As should be realising by now, this test is going to fail. After running to confirm, we need to update our constructor to include the new products.</p>
<p>You may wonder why we bothered to run the test when we know that it was going to fail. Well it&#8217;s a good practice to get into, because if you don&#8217;t actually witness your test failing, you don&#8217;t know for certain whether your test is actually correct. You might be testing the wrong thing. If your test passes when you expect it not to, you know there&#8217;s something wrong; but if you don&#8217;t catch it, your pass after your change won&#8217;t mean anything.</p>
<pre name="code" class="c-sharp">
public Inventory()
{
    products = new Dictionary&lt;string, double&gt;();

    products["Apple"] = 0.5;
    products["Sausuages"] = 2.99;
    products["Potatoes"] = 3.99;
    products["Cola"] = 1.27;
    products["Bread"] = 0.99;
    products["Milk"] = 0.47;
}
</pre>
<p>After making this change, our test will now pass. We&#8217;ve now successfully completed our customer&#8217;s requirement, and our code has become a little bit more manageable in the process.</p>
<h4>Boundary Conditions</h4>
<p>The customer is happy with our implementation of their requirements, even if we can see some places for improvement, and the release date is looming. The customer starts integrating their existing data into our system. After importing the list of products from a spreadsheet, the system is given a thorough run through.</p>
<p>The customer noticed that after importing the list of products, whenever anyone bought an apple, the system crashed. After some investigation, it ends up the spreadsheet with the products had apples in all lower-case, while our inventory has it stored with an upper-case letter a.</p>
<p>This exposes a flaw in our testing logic. We&#8217;ve currently just been testing how we expect the method to behave under normal usage, but not actually testing how it will act if we pass it things other than what it&#8217;s expecting. Our tests should also be testing for invalid data and boundary conditions.</p>
<blockquote>
<p><strong>Boundary Condition:</strong> A problem or situation that occurs only at a extreme (maximum or minimum) operating parameter.</p>
<p>An example of a boundary condition would be supplying <code>1</code> and <code>12</code> to a <code>GetDaysInMonth</code> method.</p>
</blockquote>
<blockquote>
<p><strong>Invalid Input:</strong> Anything outside standard operating expectations.</p>
<p>Using the same example as boundary conditions, invalid input would cover supplying <code>-6</code>, <code>0</code> and <code>76</code> to the <code>GetDaysInMonth</code> method.</p>
</blockquote>
<p>We&#8217;ll write a test to cover the invalid input the customer encountered, we&#8217;ll pass in a valid product name, but one that&#8217;s capitalised incorrectly.</p>
<pre name="code" class="c-sharp">
[Test]
public void ReturnsCorrectProductPriceWhenPassedIncorrectCasedName()
{
    Inventory inventory = new Inventory();

    Assert.AreEqual(0.5, inventory.GetPrice("AppLE"),
        "Should return price of Apples, 50p.");
}
</pre>
<p>Running this test will fail, as usual. So lets fix the code to allow case-insensitive product names.</p>
<pre name="code" class="c-sharp">
public Inventory()
{
    products = new Dictionary&lt;string, double&gt;();

    products["apple"] = 0.5;
    products["sausuages"] = 2.99;
    products["potatoes"] = 3.99;
    products["cola"] = 1.27;
    products["bread"] = 0.99;
    products["milk"] = 0.47;
}

public GetPrice(string product)
{
    return products[product.ToLower()];
}
</pre>
<p>We&#8217;ve modified our constructor to set the product names as lower-case, then modified our method to convert the inputted product name to lower-case as well. This way our searches are case-insensitive.</p>
<p>Running all our tests should assure us that our existing code still functions, and we&#8217;re now safe from any case variations from the customer&#8217;s product list.</p>
<p>While doing this change, it&#8217;s noticeable that we&#8217;re also not handling the case for if a price is requested for a product that isn&#8217;t in the inventory. If this occurs we really should pass a message up to the <span class="caps">GUI</span>, so it can present the user with something.</p>
<p>Due to this being an exceptional situation, it&#8217;s ideally suited to an exception! Let&#8217;s write a test to handle this case.</p>
<pre name="code" class="c-sharp">
[Test, ExpectedException(typeof(InvalidProductException))]
public void ThrowsAnExceptionForAnInvalidProduct()
{
    Inventory inventory = new Inventory();

    inventory.GetPrice("My Invalid Product");
}
</pre>
<p>We&#8217;ve introduced a new attribute to our test in this case, <code>ExpectedException</code>, this simply allows you to specify what exception you want a method to throw in the situation you&#8217;re testing.</p>
<blockquote>
<p><strong>Note:</strong> This test requires the use of a custom exception, I&#8217;m not going to show the implementation here as it&#8217;s simple stuff. I&#8217;ve chosen to use a custom exception so our &#8220;GUI guys&#8221; know what to capture for this case.</p>
<p>It&#8217;s generally regarded as good practice to wrap your internal errors in something that&#8217;s meaningful to the rest of the application, hiding the implementation details. An <code>InvalidProductException</code> is much easier to understand and implement than <code>NullReferenceException</code>, <code>IndexOutOfRangeException</code> etc. This is another topic in itself though.</p>
</blockquote>
<p>To make this test pass, we need to update our <code>GetPrice</code> method to handle invalid products.</p>
<pre name="code" class="c-sharp">
public double GetPrice(string product)
{
    if (!products.ContainsKey(product))
        throw new InvalidProductException("Product supplied, " + product +", is not in the inventory.");

    return products[product];
}
</pre>
<p>We&#8217;re now doing a simple check to see if the internal product Dictionary contains an entry for the requested product, if it doesn&#8217;t we&#8217;ll throw one of our <code>InvalidProductException</code>&#8217;s.</p>
<p>Running our test again will now assure us that our method throws an exception in these circumstances.</p>
<p>We can now return to integration and the customer can be assured that it all works.</p>
<h4>Learning Conclusions</h4>
<p>What have we witnessed in running through this little exercise?</p>
<ol>
<li><strong>How easy it is to test first</strong> &#8211; It&#8217;s really not that complicated. Once you&#8217;ve learnt to apply the restraint needed to stop yourself from just diving in, it&#8217;s easy.</li>
<li><strong>The security you get from tests</strong> &#8211; If you&#8217;ve come from an environment that doesn&#8217;t have any code tests, you&#8217;re probably enjoying the reassurance that tests bring. You&#8217;re at least safe in the knowledge that you haven&#8217;t broken anything existing with your new features. The more tests you introduce, the more solid your base for making changes becomes.</li>
<li><strong>Ease of refactoring</strong> &#8211; As with the above, it&#8217;s easy to refactor your existing code when you&#8217;ve got a suite of tests in-place.</li>
<li><strong>Light-weight nature of your code</strong> &#8211; When you&#8217;re only coding to make your tests pass, you&#8217;re less likely to code features that aren&#8217;t required. This makes your code as light as possible.</li>
</ol>
<h3>Dealing with Legacies</h3>
<p>Lets be honest here, nobody likes legacy code. You know the kind of code I mean. The code written by the mysterious and elusive previous developers. Usually it&#8217;s dire, sometimes it&#8217;s shocking, most of the time it&#8217;s untested.</p>
<p>Testing legacy code can be a nightmare in itself, but it is possible. What you need to remember in this situation is that you can&#8217;t be a hero. There&#8217;s no way you can create a test suite that covers the whole system, it&#8217;s just not feasible.</p>
<p>Your best approach to testing legacy code is an incremental one. If you find a bug in the system, write a test that fails because of it, then fix the code and run your test. That way you have a test that covers that bug, and you&#8217;re now safe from that bug showing up again. Eventually, if you continue this way, you&#8217;ll end-up with a nice suite of tests covering your common bugs.</p>
<p>Often the system you&#8217;re trying to test will be an unstructured mess, it&#8217;ll be very hard to separate out logical concerns. It may be possible for you to utilise mock and stub objects<sup><a href="#fn3">3</a></sup> in these situations, which will help you break down the barriers. Sometimes even this isn&#8217;t possible, and these may be the cases where you&#8217;re either going to have to live with a few hundred lines of setup code for your tests, or live without automated testing, at least until you can rework the code to facilitate testing more readily.</p>
<p>Another form of legacy that you&#8217;re no doubt going to encounter is that of the legacy mind. How you write code may have been turned on its head by the introduction of test-driven development, and you&#8217;re going to slip back into your old ways every now and again. This happens to everyone at some point, but if you can force yourself to maintain your standards then you&#8217;ll eventually break the barrier and you wont look back. If I code without unit tests now, I feel an overwhelming sense of insecurity and dirtiness. It&#8217;s a good thing!</p>
<h3>Recommended Reading</h3>
<ul>
<li><a href="http://c2.com/cgi/wiki?ExtremeProgrammingRoadmap">Extreme Programming Roadmap</a> Great resource, lots of discussion, including some from the greats.</li>
<li><a href="http://www.martinfowler.com/">Martin Fowler</a> Lots of good articles.</li>
<li><a href="http://codebetter.com/blogs/jeremy.miller">Jeremy Miller</a> Plenty of reading material, lots of insightful stuff. Rules of <span class="caps">TDD</span>: <a href="http://codebetter.com/blogs/jeremy.miller/archive/2005/10/20/133437.aspx">1</a>, <a href="http://codebetter.com/blogs/jeremy.miller/archive/2006/03/09/140465.aspx">2</a>, <a href="http://codebetter.com/blogs/jeremy.miller/archive/2006/05/30/145752.aspx">3</a>, <a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/04/27/Jeremy_2700_s-Fourth-Law-of-Test-Driven-Development_3A00_-Keep-Your-Tail-Short.aspx">4</a></li>
<li><a href="http://www.xprogramming.com/xpmag/acsUsingNUnit.htm">Adventures in C#: Using NUnit</a> Good introduction to using NUnit.</li>
<li><cite><a href="http://www.amazon.co.uk/gp/product/0735619492?ie=UTF8&#038;tag=jamegreg-21&#038;linkCode=as2&#038;camp=1634&#038;creative=6738&#038;creativeASIN=0735619492">Extreme Programming Adventures in C#</a></cite>, Ron Jeffries &#8211; Honest and friendly introduction to <span class="caps">TDD</span> and XP.</li>
<li><cite><a href="http://www.amazon.co.uk/gp/product/0201485672?ie=UTF8&#038;tag=jamegreg-21&#038;linkCode=as2&#038;camp=1634&#038;creative=6738&#038;creativeASIN=0201485672">Refactoring: Improving the Design of Existing Code</a></cite>, Martin Fowler &#8211; Refactoring bible.</li>
</ul>
<h3>References</h3>
<p id="fn1"><sup>1</sup> <a href="http://www.extremeprogramming.org/rules/testfirst.html">Extreme Rules: Test First</a>, ExtremeProgramming.org</p>
<p id="fn2"><sup>2</sup> <a href="http://c2.com/xp/YouArentGonnaNeedIt.html">You Aren&#8217;t Gonna Need It</a>, Extreme Programming Roadmap</p>
<p id="fn3"><sup>3</sup> <a href="http://martinfowler.com/articles/mocksArentStubs.html">Mocks Aren&#8217;t Stubs</a>, Martin Fowler</p>
]]></content:encoded>
			<wfw:commentRss>http://jagregory.com/writings/getting-with-it-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
