<?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>Basil Vandegriend: Professional Software Development &#187; Test Driven Development</title>
	<atom:link href="http://www.basilv.com/psd/blog/tag/test-driven-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.basilv.com/psd</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 13:23:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Test Driven Development &#8211; Benefits, Limitations, and Techniques</title>
		<link>http://www.basilv.com/psd/blog/2009/test-driven-development-benefits-limitations-and-techniques</link>
		<comments>http://www.basilv.com/psd/blog/2009/test-driven-development-benefits-limitations-and-techniques#comments</comments>
		<pubDate>Tue, 01 Dec 2009 20:22:15 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/?p=463</guid>
		<description><![CDATA[I wrote previously about the process I went through in adopting test driven development (TDD). In this article I discuss my experience with TDD: the benefits, the limitations, and the techniques I use when doing TDD. Benefits This section covers the benefits, as I see them, of doing TDD. This does not include the benefits [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote previously about the <em>process</em> I went through in <a href="http://www.basilv.com/psd/blog/2009/adopting-test-driven-development">adopting test driven development</a> (TDD). In this article I discuss my experience with TDD: the benefits, the limitations, and the techniques I use when doing TDD.</p>
<h3>Benefits</h3>
<p>This section covers the benefits, as I see them, of doing TDD. This does <em>not</em> include the benefits of doing automated unit testing, which I am a big fan of and have been doing for years using a non-TDD approach (i.e. writing tests after writing production code). </p>
<ol>
<li>Using TDD provides great code coverage, especially conditional code coverage. Strictly following <a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd">Robert C. Martin’s three rules of TDD</a> should result in 100% coverage for both statements and conditionals. I allow myself to deviate from these rules at times, but still obtain 90+% coverage.
<p>Previously when writing tests after coding, as part of my process to ensure I was <a href="http://www.basilv.com/psd/blog/2009/my-definition-of-done">done a feature</a> I would check the code coverage results to identify gaps and add missing tests. I have found that this code coverage check is mostly a formality when doing TDD.
</li>
<li>TDD helps avoids the tedium that I have experienced at times writing the tests after coding. Often while doing TDD I am able to establish what I call the red-green rhythm: write a failing test (unit test result bar goes red), then get it to pass (bar changes to green). This rhythm makes it more enjoyable to write the tests, although the tedium is not completely eliminated. As a result, I find it takes less discipline to write the tests first than afterwards – I do not have to force myself to write a bunch of tests after getting some functionality in place.</li>
<li>When I started using TDD I was initially uncomfortable with writing the simplest possible code to get a failing test to pass (TDD rule #3) when I knew that the final production code would be different. As my experience using TDD increased, I began to see a number of benefits of following this rule:
<ul>
<li>Writing more code than the minimum necessary to pass the test runs the risk of having logic in the production code (statements or conditions) not covered by the tests.</li>
<li>At times, when the design for the method / class was a little fuzzy to me, writing the simplest possible code actually proved helpful, as I could then write another failing test which then clarified for me what the design would need to be.</li>
</ul>
</li>
<li>Using TDD, especially when strictly following the three rules, seems to eliminate the question / debate about how much to test. When introducing unit testing to developers (not TDD, just the use of automated unit tests), I get asked this question time and time again. I have a standard answer I use, but it no longer seems relevant when doing strict TDD. In fact, the question itself no longer applies when doing TDD.</li>
</ol>
<h3>Limitations</h3>
<p>When adopting a new practice it is important to know the contexts in which the practice is less applicable. I have come across a number of situations in which TDD seemed less helpful. These were the situations when I was most likely to deviate from the three rules of TDD or abandon TDD entirely.</p>
<ol>
<li>I prefer to have the design of the method / class I am working on fairly clear in my head before I start writing tests. Sometimes I do this on paper, but sometimes I do this by working with the actual code which would be a deviation from TDD. Since adopting TDD I have tried to do this design in the test code instead of in production code, with mixed results. Sometimes this worked fine, and sometimes it felt unnatural and less productive. I have the feeling that as I gain experience with TDD I will grow more comfortable with doing design within test code.
</li>
<li>When I need to code a non-trivial algorithm I often extract logic into separate methods on the same class or need to invoke new methods on collaborating classes. Often I need to write these additional methods as the minimum needed to get my failing unit test to pass, which means that I am strictly following TDD. The issue is that my normal unit testing practice is to test methods individually as much as possible, especially methods on other classes, and the rules of TDD do not require me to do so. In essence, my original failing unit test ends up being an integration-style test for the overall algorithm, while I want to have individual unit tests for methods making up the algorithm. So the limitation of TDD is not that it cannot be applied – I am using it – but that it is not enough to ensure what I consider to be a sufficient level of testing. See the Techniques section below for how I address this limitation.</li>
<li>In situations where automated unit tests are not applicable, TDD obviously does not apply. Some people would insist that everything be unit tested, and I agree that it is a goal to aspire to, but in some circumstances I feel that unit testing is not pragmatic. Situations where I am unlikely to use automated unit tests and hence TDD include:
<ul>
<li>Prototyping or other exploratory-style work such as an architectural spike. However, when trying to understand the behavior of third-party libraries, I often do find it helpful to do this via unit tests.</li>
<li>User interfaces such as web pages or emails. Automated tests can be used to verify that the web page or email content is produced without failure, but the actual content and formatting is best checked by a human.</li>
</ul>
</ol>
<h3>Techniques</h3>
<p>I have adopted several techniques for using TDD to fit my style of coding that go beyond the three rules. I prefer to think of them, however, as tips or tricks of the trade rather than firm rules. </p>
<ol>
<li>I developed a technique to address the limitation of TDD discussed above regarding the creation of new methods on collaborating classes under a single failing unit test. When I go to create a new method on a different class, I recursively apply TDD. So before creating the new method, I create a new test for it on a different test class corresponding to this other class. This means that I now have two failing tests, not one, so I modify the TDD rules and just run the tests of this second class while working on this new method. Once I am done with the method, I can run the suite, confirm I have just the one original failing test, and resume working on the original method.
</li>
<li>There are often times when, upon getting the current tests to pass, there are multiple scenarios to select from to write the next test. Which one to pick? My own preference is to choose a scenario that will fail given the current production code – do not choose a scenario that will automatically pass. The reason for this preference is that this helps maintain that rhythm of alternating between failing and passing tests. After all of these failure-inducing scenarios are tested, I do go back to add the scenarios I expect to pass. At this point, while I’m still technically following TDD, it feels like my old approach of writing the tests afterwards: the production code is finished, and I am testing the remaining scenarios to confirm it is correct.
</li>
</ol>
<h3>Conclusion</h3>
<p>Overall I found test driven development to be a very effective process for producing high-quality code, and I plan to continue to use it. I highly recommend every developer to experiment with adopting TDD and evaluate the benefits and limitations for themselves.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2009/test-driven-development-benefits-limitations-and-techniques/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adopting Test Driven Development</title>
		<link>http://www.basilv.com/psd/blog/2009/adopting-test-driven-development</link>
		<comments>http://www.basilv.com/psd/blog/2009/adopting-test-driven-development#comments</comments>
		<pubDate>Tue, 17 Nov 2009 23:22:28 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[personal development]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/?p=453</guid>
		<description><![CDATA[I have always been keen on using automated unit tests since I first heard about them almost a decade ago. I have known about test driven development (TDD) for almost as long but the practice of writing tests first before writing production code never really clicked for me when I first tried it years ago. [...]]]></description>
			<content:encoded><![CDATA[<p>I have always been keen on using automated unit tests since I first heard about them almost a decade ago. I have known about test driven development (TDD) for almost as long but the practice of writing tests first before writing production code never really clicked for me when I first tried it years ago. Since then I have evolved my approach of writing tests, but still almost always after I write the production code. </p>
<p>Recently I was prompted by multiple sources to give TDD a try, the most prominent and vocal of which was <a href="http://butunclebob.com/">Robert C Martin</a>, who stated that <a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd">he believed TDD to be one of the most significant new software development practices he had adopted in his 30 years of experience</a>.  I found particularly compelling <a href="http://blog.objectmentor.com/articles/2009/10/06/echoes-from-the-stone-age">his comparison of TDD for software development to the medical practice of sterile operating rooms</a>. </p>
<p>Based on these strong recommendations, I decided that I needed to give test driven development another try.</p>
<h3>Preparation</h3>
<p>I resolved to not just haphazardly try TDD like I did before, but to adopt it as a development practice for a period of time as a <a href="http://www.basilv.com/psd/blog/2008/continuous-improvement-experiments">continuous improvement experiment</a>. I deliberately went with a more disciplined approach. Based on my knowledge of personal development and continuous improvement, I knew that the change would be difficult, especially at first. So I prepared for the change via the following steps:</p>
<ul>
<li>I reflected on the difficulties I would face in adopting TDD. I expected to struggle with two issues. The first was the drop in productivity due to getting familiar with doing TDD – I would be spending a greater percentage of my time thinking about my process of coding as it related to TDD, rather than the code I was writing. The second was the natural tendency to revert back to my established pattern of behavior. This reflection ensured I would have more realistic expectations when I started using TDD.
</li>
<li>I refreshed my knowledge of the details of doing TDD that go beyond the core idea of writing tests before code. My favorite reference was <a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd">Robert C. Martin’s three rules of test driven development</a> which are:
<ol>
<li>You are not allowed to write any production code unless it is to make a failing unit test pass.</li>
<li>You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.</li>
<li>You are not allowed to write any more production code than is sufficient to pass the one failing unit test.</li>
</ol>
</li>
<li>I wrote a note to do TDD and stuck it to the front of my keyboard were it would always be visible to me. It served as both an affirmation and a reminder.
</li>
</ul>
<p>Having finished my preparation, it was time to actually start doing test-driven development.</p>
<h3>Adoption</h3>
<p>My initial start with TDD was easy: I started my next coding task by writing a test rather than production code. If only it stayed so simple :) </p>
<p>At first the shift in process was difficult as I had to consciously remember to write the test first, and then write only a portion of the production code necessary to get it to pass. My productivity felt a lot lower (I have no idea whether it was significantly worse or only a little). But I had expected this and used discipline to force myself to continue with TDD.</p>
<p>One of the hurdles I faced was how strictly to follow the three rules of TDD - particularly rule number three. I had always been uncomfortable with the idea of writing temporary or intermediate production code that would get the current test to pass, but that I knew was not the final form and that I would need to change. An example is implementing an algorithm to return a fixed value (say zero or null) rather than implement the actual logic. I decided to take a <a href="http://www.basilv.com/psd/blog/2006/are-you-a-rule-maker-or-a-rule-breaker">pragmatic approach</a> and allow myself to deviate from the three rules on occasion, when following the rules seemed too onerous or difficult. I did not want blind adherence to the rules to cause me to completely give up on TDD. I expected that over time as my familiarity with TDD grew, I would be able to become stricter in adhering to the rules.</p>
<p>As expected I suffered setbacks along the way. I started a development task by writing most of a method of production code before realizing that I had no failing test. In another case I had a failing test but then churned out the entire production method, including all the special cases, well after that test would pass. I took these setbacks in stride – I considered them a normal outcome of adopting a new behavior, rather than personal failures, and simply returned to doing TDD once I became aware of my departure.</p>
<p>After about a week, doing TDD became less of a struggle. After about three weeks (the typical minimum duration to establish a new habit) TDD began to feel more natural. By this point I had clarified for myself the benefits and limitations of TDD and had integrated it into my development process. I have a lot more to say about this which I will save for a follow-up post. As a quick summary, I find TDD to be a valuable practice that I intend to continue to use.</p>
<h3>Conclusion</h3>
<p>If you have not tried TDD, I strongly recommend you experiment with adopting it as a development practice. Looking beyond just TDD, one of the points of this article is to encourage you to always be thinking about your capabilities as a software developer and continuously seek to improve. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2009/adopting-test-driven-development/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

