<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7888275152424656007</id><updated>2012-02-16T02:37:41.408-08:00</updated><category term='visual studio'/><category term='technical debt'/><category term='dependency injection'/><category term='TDD'/><category term='introduction'/><category term='mocking'/><category term='refactoring'/><category term='dog&apos;s bollocks'/><category term='breaking dependencies'/><category term='wrapping'/><category term='OMG'/><category term='WTF'/><category term='separation of concerns'/><category term='quality'/><category term='examples'/><title type='text'>OMG WTF TDD</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://omgwtftdd.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://omgwtftdd.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Erik Rydeman</name><uri>http://www.blogger.com/profile/04353346939599565563</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_-rXD_s1vAYE/SYIiIISIQuI/AAAAAAAAAQI/lnLGpafWiuM/S220/bluesky.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7888275152424656007.post-7527248135614776614</id><published>2009-02-02T01:56:00.000-08:00</published><updated>2009-03-18T08:35:49.183-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dependency injection'/><category scheme='http://www.blogger.com/atom/ns#' term='examples'/><category scheme='http://www.blogger.com/atom/ns#' term='wrapping'/><category scheme='http://www.blogger.com/atom/ns#' term='breaking dependencies'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Testing DateTime.Now - Introducing Wrap and Override</title><content type='html'>&lt;div class="abstract"&gt;&lt;strong&gt;Abstract:&lt;/strong&gt;&lt;div&gt;The student said to his zen master: "What time is it?"&lt;/div&gt;&lt;div&gt;"It is &lt;a href="#solution"&gt;TimeWarper.Now&lt;/a&gt;", the master replied.&lt;/div&gt;&lt;div&gt;"What time is that?", asked the student.&lt;/div&gt;&lt;div&gt;"It is whatever time I need it to be.", said the master. &lt;/div&gt;&lt;div&gt;And the student was enlightened.&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Quite often you'll want your application to save a timestamp of when something occured. Due to the nature of time this presents a special set of challenges when it comes to testing.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's look at an example for logging exceptions.&lt;/div&gt;&lt;div&gt;Here's an initial attempt at a test:&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;[Test]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestLogException_LogsCorrectValues()&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; AbandonedMutexException(&lt;span class="str"&gt;"The poor mutex was abandoned!"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;{&lt;br /&gt;&lt;span class="rem"&gt;// Log the exception&lt;/span&gt;&lt;br /&gt;ExceptionLog log = _exceptionLogger.LogException(ex);&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// Assert that the logged values are correct&lt;/span&gt;&lt;br /&gt;Assert.AreEqual(&lt;span class="str"&gt;"System.Threading.AbandonedMutexException"&lt;/span&gt;, log.ExceptionType);&lt;br /&gt;Assert.AreEqual(&lt;span class="str"&gt;"The poor mutex was abandoned!"&lt;/span&gt;, log.Message);&lt;br /&gt;Assert.That(!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(log.StackTrace));&lt;br /&gt;Assert.AreEqual(1, log.NumOccurences);&lt;br /&gt;Assert.AreEqual(DateTime.Now, log.FirstOccurrence); &lt;span class="rem"&gt;// &lt;-- Mind the dates!&lt;/span&gt;&lt;br /&gt;Assert.AreEqual(DateTime.Now, log.LastOccurrence);  &lt;span class="rem"&gt;// &lt;-- Mind the dates!&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;That looks straightforward enough doesn't it?&lt;/div&gt;&lt;div&gt;Let's make the test work:&lt;/div&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExceptionLogger&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ExceptionLog LogException(Exception ex)&lt;br /&gt;{&lt;br /&gt;ExceptionLog log = &lt;span class="kwrd"&gt;new&lt;/span&gt; ExceptionLog();&lt;br /&gt;log.ExceptionType = ex.GetType().ToString();&lt;br /&gt;log.Message = ex.Message;&lt;br /&gt;log.NumOccurences = 1;&lt;br /&gt;log.StackTrace = ex.StackTrace;&lt;br /&gt;log.FirstOccurrence = DateTime.Now;&lt;br /&gt;log.LastOccurrence = DateTime.Now;&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; log;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExceptionLog&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ExceptionType { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Message { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; StackTrace { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime FirstOccurrence { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime LastOccurrence { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; NumOccurences { get; set; }&lt;br /&gt;}&lt;/pre&gt;&lt;div&gt;Running the test, we see that it fails!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_-rXD_s1vAYE/SYbgvb1LvEI/AAAAAAAAARw/lwqjQGWbx3M/s1600-h/datetimefail.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 287px;" src="http://1.bp.blogspot.com/_-rXD_s1vAYE/SYbgvb1LvEI/AAAAAAAAARw/lwqjQGWbx3M/s400/datetimefail.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5298169117177265218" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The line failing is:&lt;pre class="csharpcode"&gt;Assert.AreEqual(DateTime.Now, log.FirstOccurrence);&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;With this message:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;NUnit.Framework.AssertionException:   &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Expected: 2009-02-02 11:39:42.820&lt;br /&gt;But was:  2009-02-02 11:39:42.787&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see 33 milliseconds have past between saving &lt;span class="Apple-style-span" style="font-style: italic;"&gt;DateTime.Now&lt;/span&gt; to &lt;span class="Apple-style-span" style="font-style: italic;"&gt;log.FirstOccurence&lt;/span&gt; and comparing the results to &lt;span class="Apple-style-span" style="font-style: italic;"&gt;DateTime.Now&lt;/span&gt; in the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Assert.AreEqual&lt;/span&gt; method.&lt;/div&gt;&lt;div&gt;This makes perfect sense. Time tends to pass even for very fast computers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But what do we do about it? There are a few possible solutions that spring to mind:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;Remove the Assert -&lt;/span&gt; We could just decide it's too much trouble to test and move on. That's not very nice. If we go down that road we could just stop testing right now and finish the code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Make the Assert less precise&lt;/span&gt; - We could just strip the milliseconds. Who cares about them anyway? We could do that, but there's a 3,3% chance that the test is run in the milliseconds that overlaps one second changing to another. This would cause the test to inexplicably fail every now and again. Unacceptable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Overload &lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic; "&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;ExceptionLogger.LogException&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;We could get control of what DateTime to set by overloading &lt;span class="Apple-style-span" style="font-weight: bold; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;LogException&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;like this&lt;/span&gt;:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;[Test]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestLogException_LogsCorrectValues()&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; AbandonedMutexException(&lt;span class="str"&gt;"The poor mutex was abandoned!"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;{&lt;br /&gt;DateTime now = DateTime.Now; &lt;span class="rem"&gt;//&amp;lt;-- New variable!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// Log the exception&lt;/span&gt;&lt;br /&gt;ExceptionLog log = _exceptionLogger.LogException(ex, now);&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// Assert that the logged values are correct&lt;/span&gt;&lt;br /&gt;Assert.AreEqual(&lt;span class="str"&gt;"System.Threading.AbandonedMutexException"&lt;/span&gt;, log.ExceptionType);&lt;br /&gt;Assert.AreEqual(&lt;span class="str"&gt;"The poor mutex was abandoned!"&lt;/span&gt;, log.Message);&lt;br /&gt;Assert.That(!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(log.StackTrace));&lt;br /&gt;Assert.AreEqual(1, log.NumOccurences);&lt;br /&gt;Assert.AreEqual(now, log.FirstOccurrence); &lt;span class="rem"&gt;// &lt;-- Compare now instead&lt;/span&gt;&lt;br /&gt;Assert.AreEqual(now, log.LastOccurrence);  &lt;span class="rem"&gt;// &lt;-- Compare now instead&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExceptionLogger&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ExceptionLog LogException(Exception ex)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; LogException(ex, DateTime.Now);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ExceptionLog LogException(Exception ex, DateTime timeOfException)&lt;br /&gt;{&lt;br /&gt;ExceptionLog log = &lt;span class="kwrd"&gt;new&lt;/span&gt; ExceptionLog();&lt;br /&gt;log.ExceptionType = ex.GetType().ToString();&lt;br /&gt;log.Message = ex.Message;&lt;br /&gt;log.NumOccurences = 1;&lt;br /&gt;log.StackTrace = ex.StackTrace;&lt;br /&gt;log.FirstOccurrence = timeOfException; &lt;span class="rem"&gt;//Use the passed in value&lt;/span&gt;&lt;br /&gt;log.LastOccurrence = timeOfException;  &lt;span class="rem"&gt;//Use the passed in value&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; log;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;This solution is actually not too shabby. The test passes:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://2.bp.blogspot.com/_-rXD_s1vAYE/SYb2ljSHTeI/AAAAAAAAAR4/26s_Ns74OP0/s400/overloadsuccess.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5298193136634777058" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But it comes with two drawbacks:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;It's making the method signature more complex. People using ExceptionLogger might not be sure if they're required to pass in a datetime and what it should be.&lt;/li&gt;&lt;li&gt;We're not actually testing that DateTime.Now is used as the timestamp in the default case.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's look at an alternative!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=""&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;a name="solution"&gt;&lt;/a&gt;The Solution: Bending time and space&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Let's face it, DateTime.Now is one of those things that gets called a lot and that you don't want to think about. The previous solution works well for a test this small but in more complex scenarios we probably have enough stuff to throw around that we don't want to complicate things further by passing confusing DateTime arguments that are not really needed.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To get complete control of time itself for unit testing here is a class I always create within two hours of joining a software project:&lt;/div&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TimeWarper&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DateTime? _now;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// TimeWarper.Now is a utility for getting the current time.&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// In production code it simply wraps DateTime.Now, but allows the current&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// DateTime to be overridden for unit testing purposes.&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DateTime Now&lt;br /&gt;{&lt;br /&gt; get&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;return&lt;/span&gt; _now ?? DateTime.Now;&lt;br /&gt; }&lt;br /&gt; set&lt;br /&gt; {&lt;br /&gt;     _now = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;div&gt;This is a comon trick known as Wrap and Override. &lt;/div&gt;&lt;div&gt;You wrap the thing you want to fake in your unit test and override it with something under your control. In this case we just want to make time stand still so we can accurately measure it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's how it looks if we use it in the example above:&lt;/div&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;[TestFixture]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExceptionLoggerTests&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;private&lt;/span&gt; ExceptionLogger _exceptionLogger;&lt;br /&gt;&lt;br /&gt; [SetUp]&lt;br /&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetUp()&lt;br /&gt; {&lt;br /&gt;     TimeWarper.Now = DateTime.Now; &lt;span class="rem"&gt;//Freeze!&lt;/span&gt;&lt;br /&gt;     _exceptionLogger = &lt;span class="kwrd"&gt;new&lt;/span&gt; ExceptionLogger();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; [Test]&lt;br /&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestLogException_LogsCorrectValues()&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;     {&lt;br /&gt;         &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; AbandonedMutexException(&lt;span class="str"&gt;"The poor mutex was abandoned!"&lt;/span&gt;);&lt;br /&gt;     }&lt;br /&gt;     &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;     {&lt;br /&gt;         &lt;span class="rem"&gt;// Log the exception&lt;/span&gt;&lt;br /&gt;         ExceptionLog log = _exceptionLogger.LogException(ex);&lt;br /&gt;&lt;br /&gt;         &lt;span class="rem"&gt;// Assert that the logged values are correct&lt;/span&gt;&lt;br /&gt;         Assert.AreEqual(&lt;span class="str"&gt;"System.Threading.AbandonedMutexException"&lt;/span&gt;, log.ExceptionType);&lt;br /&gt;         Assert.AreEqual(&lt;span class="str"&gt;"The poor mutex was abandoned!"&lt;/span&gt;, log.Message);&lt;br /&gt;         Assert.That(!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(log.StackTrace));&lt;br /&gt;         Assert.AreEqual(1, log.NumOccurences);&lt;br /&gt;         Assert.AreEqual(TimeWarper.Now, log.FirstOccurrence); &lt;span class="rem"&gt;// &amp;lt;-- TimeWarper!&lt;/span&gt;&lt;br /&gt;         Assert.AreEqual(TimeWarper.Now, log.LastOccurrence);  &lt;span class="rem"&gt;// &amp;lt;-- TimeWarper!&lt;/span&gt;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExceptionLogger&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; ExceptionLog LogException(Exception ex)&lt;br /&gt; {&lt;br /&gt;     ExceptionLog log = &lt;span class="kwrd"&gt;new&lt;/span&gt; ExceptionLog();&lt;br /&gt;     log.ExceptionType = ex.GetType().ToString();&lt;br /&gt;     log.Message = ex.Message;&lt;br /&gt;     log.NumOccurences = 1;&lt;br /&gt;     log.StackTrace = ex.StackTrace;&lt;br /&gt;     log.FirstOccurrence = TimeWarper.Now; &lt;span class="rem"&gt;//Tada.wav!&lt;/span&gt;&lt;br /&gt;     log.LastOccurrence = TimeWarper.Now;  &lt;span class="rem"&gt;//Tada.wav!&lt;/span&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;return&lt;/span&gt; log;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;There you have it.&lt;/div&gt;&lt;div&gt;Freezing time for unit tests is a great way to make them simpler. You can deal with DateTimes as a value type rather than having to declare multiple variables. Simply refer to any unique point in time you want to set or compare against as &lt;span class="Apple-style-span" style="font-style: italic;"&gt;TimeWarper.Now.AddMinutes(x) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7888275152424656007-7527248135614776614?l=omgwtftdd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://omgwtftdd.blogspot.com/feeds/7527248135614776614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omgwtftdd.blogspot.com/2009/02/testing-datetimenow-introducing-wrap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/7527248135614776614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/7527248135614776614'/><link rel='alternate' type='text/html' href='http://omgwtftdd.blogspot.com/2009/02/testing-datetimenow-introducing-wrap.html' title='Testing DateTime.Now - Introducing Wrap and Override'/><author><name>Erik Rydeman</name><uri>http://www.blogger.com/profile/04353346939599565563</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_-rXD_s1vAYE/SYIiIISIQuI/AAAAAAAAAQI/lnLGpafWiuM/S220/bluesky.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_-rXD_s1vAYE/SYbgvb1LvEI/AAAAAAAAARw/lwqjQGWbx3M/s72-c/datetimefail.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7888275152424656007.post-5147285396042541262</id><published>2009-02-01T05:55:00.000-08:00</published><updated>2009-02-01T15:06:53.884-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visual studio'/><category scheme='http://www.blogger.com/atom/ns#' term='examples'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Super mega quickstart for Unit Testing with Visual Studio .NET</title><content type='html'>&lt;div class="abstract"&gt;&lt;strong&gt;Abstract:&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;This is a quickstart for setting up a testing environment in Visual Studio&lt;/li&gt;&lt;li&gt;Step 1 - Create a new class libary for your tests.&lt;/li&gt;&lt;li&gt;Step 2 - Add a reference to &lt;a href="http://www.nunit.org/index.php?p=download"&gt;nunit.framework.dll&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Step 3 - Get a test runner like the one in &lt;a href="http://www.jetbrains.com/resharper/"&gt;Resharper&lt;/a&gt;, &lt;a href="http://www.exactmagic.com/"&gt;TestMatrix&lt;/a&gt; or &lt;a href="http://www.nunit.org/index.php?p=download"&gt;NUnit&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Step 4 - Start writing tests and run them with your test runner!&lt;/li&gt;&lt;li&gt;Step 7 - Here are some mocking frameworks: &lt;a href="http://ayende.com/projects/rhino-mocks.aspx"&gt;Rhino mocks&lt;/a&gt;, &lt;a href="http://www.nmock.org/"&gt;NMock&lt;/a&gt;, &lt;a href="http://typemock.com/"&gt;TypeMock&lt;/a&gt;, &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Step 10 - Profit!&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For the benefit on any beginners stumbling across this blog, here is what you need to get started writing Unit Tests on the .NET platform. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Step 1 - Create a new class library in Visual Studio &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Call it something along the lines of &lt;span class="Apple-style-span" style="font-style: italic;"&gt;YourProjectNamespace.Testing&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Step 2 - Download the NUnit framework.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The NUnit framework is pretty much the industry standard for running Unit Tests on the .NET platform.&lt;/div&gt;&lt;div&gt;Microsoft has created something called MSTest that nobody uses. To be honest I haven't looked into it very much and I see no reason to start now. :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Get NUnit here: &lt;a href="http://www.nunit.org/index.php?p=download"&gt;http://www.nunit.org/index.php?p=download&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://1.bp.blogspot.com/_-rXD_s1vAYE/SYW1y4b6ldI/AAAAAAAAARY/LSztvCMU-3M/s400/nunit-download.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5297840422418814418" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then copy bin/nunit.framework.dll to your test project bin folder (that is: add it to your ThridPartyLibraries folder and create a reference to it in your testing project)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Step 3 - Get a test runner&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;To run unit tests you need a program to run them, preferably one integrated with Visual Studio.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have found the test runner that comes with &lt;a href="http://www.jetbrains.com/resharper/"&gt;Resharper&lt;/a&gt; to be the nicest one out there right now.&lt;/div&gt;&lt;div&gt;Resharper is a plugin for Visual Studio that unfortunately is not free, but is probably one of the best investments you can make as a developer. Read all the hype on their homepage and give it a spin. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you don't want to use resharper to run your tests here are some alternatives:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.exactmagic.com/"&gt;TestMatrix&lt;/a&gt; - Another commercial tool that works.&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.nunit.org/index.php?p=download"&gt;NUnit&lt;/a&gt; - NUnit comes with a free test runner that is functional but crude. Only use it if you have to.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If none of these work for you use the power of google.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Step 4 - Create a unit test!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wohoo, let's get cracking!&lt;/div&gt;&lt;div&gt;As an example, let's take the testing of a class validating the format of an email address.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Start by creating a file in your test project called &lt;span class="Apple-style-span" style="font-style: italic;"&gt;EmailValidatorTests.cs&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Copy and paste this code into the file:&lt;/div&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; NUnit.Framework;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; OmgWtfTdd.Testing &lt;span class="rem"&gt;//You'll want to change this to match your project&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;[TestFixture] &lt;span class="rem"&gt;//This tells the test runner that this class contains tests&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EmailValidatorTests&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; EmailValidator _emailValidator;&lt;br /&gt;&lt;br /&gt;    [SetUp]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetUp()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="rem"&gt;// The code in SetUp will be run before the execution of each unit test.&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// Here we create things that will be used in multiple tests&lt;/span&gt;&lt;br /&gt;        _emailValidator = &lt;span class="kwrd"&gt;new&lt;/span&gt; EmailValidator();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [TearDown]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TearDown()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="rem"&gt;// The TearDown method is run after each test completes.&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// Use it to tear down anything not caught by normal garbage collection&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [Test] &lt;span class="rem"&gt;// &amp;lt;-- Look! A Test!&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestIsValidEmail_NoInput()&lt;br /&gt;    {&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(String.Empty));&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(&lt;span class="kwrd"&gt;null&lt;/span&gt;));&lt;br /&gt;        &lt;span class="rem"&gt;// Assert is a way of evaluating a condition&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// If the Assert is not fullfilled the test fails.&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// If an unexpected exception is thrown the test fails.&lt;/span&gt;&lt;br /&gt;    } &lt;span class="rem"&gt;// &amp;lt;-- If the test manages to get all the way to the end the test succeeds!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    [Test]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestIsValidEmail_TrueForValidEmails()&lt;br /&gt;    {&lt;br /&gt;        Assert.IsTrue(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"erik@thisisnotmyrealemail.com"&lt;/span&gt;));&lt;br /&gt;        Assert.IsTrue(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"erik@providerwithtwodots.co.uk"&lt;/span&gt;));&lt;br /&gt;        Assert.IsTrue(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"erik.rydeman@dotsinthename.com"&lt;/span&gt;));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [Test]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestIsValidEmail_Badformats()&lt;br /&gt;    {&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"@noname.com"&lt;/span&gt;));&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"noprovider@.com"&lt;/span&gt;));&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"noprovidertall@"&lt;/span&gt;));&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"nodomain@lol."&lt;/span&gt;));&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"erik@domain.reallylongtopdomain"&lt;/span&gt;));&lt;br /&gt;        Assert.IsFalse(_emailValidator.IsEmailValid(&lt;span class="str"&gt;"wheredidtheatgo.com"&lt;/span&gt;));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// This class would normally be placed somewhere in your project.&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// The classes in the Testing project is for testing only and not used in production code.&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EmailValidator&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsEmailValid(&lt;span class="kwrd"&gt;string&lt;/span&gt; email)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="rem"&gt;// This line is what you'd normally start out &lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// with writing your tests before your code:&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;//throw new NotImplementedException();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// I've cheated and started a bit. See if you can improve it!&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; email.Contains(&lt;span class="str"&gt;"@"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;That's a Unit Test for you! Actually that's three unit tests. Let's see if they work:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;To run the tests with Resharper:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Right click somewhere in &lt;span class="Apple-style-span" style="font-style: italic; "&gt;EmailValidatorTests &lt;/span&gt;and select&lt;span class="Apple-style-span" style="font-style: italic; "&gt; "Run Unit Tests" &lt;/span&gt;from the menu.&lt;/div&gt;&lt;div&gt;Or: In the top menu select &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Resharper/Unit Testing/Run All Tests From Solution&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;To run the tests with the NUnit Test Runner:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Compile the Testing project, open the NUnit Test runner and find the dll for the testing project.&lt;/div&gt;&lt;div&gt;Run the tests.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;The result should look like this:&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_-rXD_s1vAYE/SYXPEfMMHiI/AAAAAAAAARo/4pAz72ON1pI/s1600-h/firstrun.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 316px;" src="http://1.bp.blogspot.com/_-rXD_s1vAYE/SYXPEfMMHiI/AAAAAAAAARo/4pAz72ON1pI/s400/firstrun.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5297868212670307874" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;In order for you to be able to test your environment I have made on of the tests succeed already. Note that following the principle of writing tests first you should always see it fail before you fix it.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;IsEmailValid &lt;/span&gt;method is quite incomplete. As an exercise, try making the two other tests succeed!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Step 7 - Get a mocking framework!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since this post is about setting up your test environment let's skip ahead a few steps and briefly mention another thing you'd typically need to do in a project.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In any non trivial project you'll usually come accross the need to fake some classes in order to be able to test other classes. One way to do this is to create mock objects. We'll talk about this later, but here are some mocking frameworks you can use:&lt;/div&gt;&lt;div&gt;&lt;a href="http://ayende.com/projects/rhino-mocks.aspx"&gt;Rhino Mocks&lt;/a&gt; - My current favourite. Easy to use, powerful, strongly typed mocking.&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.nmock.org/"&gt;NMock&lt;/a&gt; - Uses strings to specify which methods to mock. Not too elegant but very easy to understand.&lt;/div&gt;&lt;div&gt;&lt;a href="http://typemock.com/"&gt;TypeMock&lt;/a&gt; - Very powerful and useful but a bit magical. Requires integration into the VS environment which can sometimes cause problems.&lt;/div&gt;&lt;div&gt;&lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; - Haven't tried it yet but it sure looks very nice.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;They all pretty much do the same thing so use the one you like!&lt;/div&gt;&lt;div&gt;If you wouldn't know what to do with any of them just yet, don't worry. Start writing some regular tests and we'll tackle mocking later!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Step 10 - Profit!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There, if you've completed all the steps above you now have the power to write Unit Tests!&lt;/div&gt;&lt;div&gt;Use it wisely.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7888275152424656007-5147285396042541262?l=omgwtftdd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://omgwtftdd.blogspot.com/feeds/5147285396042541262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omgwtftdd.blogspot.com/2009/02/super-mega-quickstart-for-unit-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/5147285396042541262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/5147285396042541262'/><link rel='alternate' type='text/html' href='http://omgwtftdd.blogspot.com/2009/02/super-mega-quickstart-for-unit-testing.html' title='Super mega quickstart for Unit Testing with Visual Studio .NET'/><author><name>Erik Rydeman</name><uri>http://www.blogger.com/profile/04353346939599565563</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_-rXD_s1vAYE/SYIiIISIQuI/AAAAAAAAAQI/lnLGpafWiuM/S220/bluesky.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_-rXD_s1vAYE/SYW1y4b6ldI/AAAAAAAAARY/LSztvCMU-3M/s72-c/nunit-download.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7888275152424656007.post-3292466894559920093</id><published>2009-01-30T14:50:00.001-08:00</published><updated>2009-01-31T17:02:08.265-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quality'/><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='separation of concerns'/><category scheme='http://www.blogger.com/atom/ns#' term='dog&apos;s bollocks'/><category scheme='http://www.blogger.com/atom/ns#' term='technical debt'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Test Driven Development - What is it good for?</title><content type='html'>&lt;div class="abstract"&gt;&lt;strong&gt;Abstract:&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;This post is an introduction to TDD and its impact on software projects&lt;/li&gt;&lt;li&gt;Test Driven Development is about writing your unit tests before you code, letting the tests act as a driving force of how your code is shaped.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;TDD is closely coupled with the practice of Refactoring. Having a test suite in place enables you to make &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;refactorings&lt;/span&gt; at the project level while capturing and fixing the functionality that gets broken by this.&lt;/li&gt;&lt;li&gt;The need to write isolated Unit Tests forces you to lower the dependency between your components. This makes code easier to reuse and understand.&lt;/li&gt;&lt;li&gt;The big benefits of TDD are of a long term nature but requires an initial &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;investment&lt;/span&gt; of time. Sacrificing practices such as TDD, that aim to improve project quality, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;incurs&lt;/span&gt; technical debt that you will eventually have to pay.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what is TDD? Here comes an overview and some thoughts about it.&lt;/div&gt;&lt;div&gt;This is ground that is already pretty well covered &lt;a href="http://www.google.com/search?q=test+driven+development"&gt;elsewhere&lt;/a&gt;, but I'm sure someone will find this useful or interesting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;What is Test Driven &lt;/span&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Development&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;TDD is the act of writing unit tests before you write code. When adding a new feature you follow these steps:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Red &lt;/span&gt;&lt;/span&gt;- Write a Unit Test that &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;exercise&lt;/span&gt; functionality that you want to exist before you create the classes or methods that will fulfill that functionality. This will probably result in your project not compiling. With the least possible effort you can, make it compile, then run the test and see it fail.&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 204, 0);"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Green &lt;/span&gt;&lt;/span&gt;- Make your test pass by modifying the classes and methods you're testing. Do not add any functionality that is not required to make the test work. If your current test does not test a desired piece of functionality make a note of it and write another test later.&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 204, 0);"&gt;Refactor &lt;/span&gt;&lt;/span&gt;- Since you've only done what is necessary to make your test work, chances are that your code is not very pretty. &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;Refactor&lt;/span&gt; the code to make it prettier, remove any duplication you can find etc, and run your test again to verify that the functionality you wrote the test for is still in place.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.agiledata.org/essays/tdd.html"&gt;This page&lt;/a&gt; goes into more detail, has some pretty diagrams and many wise things to say about it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=""&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;What are the benefits of Test Driven Development?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Kent Beck in the first sentence of his &lt;a href="http://www.amazon.co.uk/Test-Driven-Development-Addison-Wesley-signature/dp/0321146530/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1233359639&amp;amp;sr=8-1"&gt;classic book&lt;/a&gt; defines the goal of TDD as: &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Clean code that works&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This really sums it up quite nicely.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Clean code&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Since the unit tests drive the production code the code will only contain the functionality dictated by the tests. By adding only the necessary code in small increments we avoid creating a system that is overly generalized, containing speculative functionality that is designed before we're sure there's an actual need for it.&lt;/div&gt;&lt;div&gt;Now, if you're working in a big project you might find this way of doing things worrying. You may think that going into a project using no upfront design at all is surely a way of getting a tangled mess designed to work for the benefit of a short term solution to a series of isolated problems. This argument has merit, and here are a few important aspects to consider about how TDD and evolutionary design impacts project architecture:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=""&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Refactor&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;the third step of &lt;span class="Apple-style-span" style="color: rgb(255, 0, 0); "&gt;R&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 204, 0);"&gt;G&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0); "&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 204, 0);"&gt;R&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt; must not be forgotten. The design of software architecture is a tricky business. When you start a project you will do well to have a general structure that dictates where new classes will be created, and common problems often have well known solutions that are readily applicable. More often than not though, design is something you discover in your code as a project grows. You may find that duplication of code leads you to create common classes and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;superclasses&lt;/span&gt; to enable reuse and eliminate duplication. Having a suite of unit tests covering the requirements of your existing functionality enables you to change the structure into something that is more elegant and works better. Large &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;refactorings&lt;/span&gt; at the project level can be done with a greater degree of confidence if you have tests that will fail if a piece of functionality suddenly gets broken from a change. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0); "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0); "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;And how do you ensure that the unit tests will cover the existing functionality and catch errors with large &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;refactorings&lt;/span&gt;? Why by adhering strictly to the principle of not adding code that is not covered by unit tests. That is easier said than done as unit tests can be cumbersome to write, but keep in mind that the benefit they bring is not only at the micro level for the specific &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;functionality&lt;/span&gt; under test, but at the macro level enabling you to do some pretty funky stuff with your project architecture as development progresses.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Lowering dependencies&lt;/span&gt;&lt;/div&gt;&lt;div&gt;A Unit Test &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=126923"&gt;should&lt;/a&gt; by definition test a small unit of functionality. This is tricky. Classes tend to have dependencies on other classes, that in turn depend on other classes still. You may be able to create an instance of a &lt;a href="http://en.wikipedia.org/wiki/Business_object_(computer_science)"&gt;Business Object&lt;/a&gt; without creating an instance of anything else, but what about cases where you want to test a method combining logic that spans several &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;BOs&lt;/span&gt;, calls to the database, calling remote &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;APIs&lt;/span&gt; and websites, or simply accessing the web context not &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_12"&gt;available&lt;/span&gt; in a test?&lt;/div&gt;&lt;div&gt;The requirement to be able to write these kinds of unit tests without touching on external systems forces you to construct your architecture in a way that is &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_13"&gt;loosely&lt;/span&gt; &lt;a href="http://en.wikipedia.org/wiki/Coupling_(computer_science)"&gt;coupled&lt;/a&gt;, programming towards interfaces and abstractions rather than the actual objects themselves. Classes should move towards only having one well defined &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;responsibility&lt;/a&gt; which increase the &lt;a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)"&gt;cohesion&lt;/a&gt; between the classes of the system and makes them part of an easy to understand, powerful whole that is easy to weave together and reuse.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;...that works&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The most first benefit that springs to people's mind when they hear the word Unit Testing, is the verification that the system actually works correctly. As I have tried to outline above, the big impact of TDD on a project is more extensive than that, but the fact remains that the immediate result you will see from writing a unit test is that the code you have written works in the way outlined by the test. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;What is the cost of TDD and when is it not worth paying?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;So, in summary: Test Driven Development is the dog's bollocks and should always be used in all projects. Thank you for reading and... &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;HEY!&lt;/span&gt; What about the downside? Surely there is a price to pay?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is, and the price is time. And time is money. Writing tests before you write code usually takes more time initially than just writing code. TDD is something that requires a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_14"&gt;commitment&lt;/span&gt; at the team level in order to reap the full benefits from it, and initially you may have to spend time in getting your team members up to speed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Benefit talk again: The time spent on writing unit tests is time spent on building an asset: Your test suite. The gain is a long term one in the ability to refactor with confidence, fight &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_15"&gt;software&lt;/span&gt; rot, reduce the number of bugs in the system and the time spent looking for them. As is the way with &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_16"&gt;investments&lt;/span&gt;, you pay a high price in time &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_17"&gt;initially&lt;/span&gt; to free up time later. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Quick and dirty&lt;/span&gt; - There is another kind of &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_18"&gt;investment&lt;/span&gt; you can make: paying a small price in time initially with the consequence of having to invest more time later. There are numerous occasions on which this makes perfect sense. The trick is to know when those are. &lt;/div&gt;&lt;div&gt;The bottom line for software success is judged by the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_19"&gt;fulfillment&lt;/span&gt; of business requirements. Having a gorgeous test suite and fantastic structure but an unfinished system makes no sense at all. If the goal of the project is to produce something that is better than nothing in a short time you need to make compromises with the rigidity of practices you apply.&lt;/div&gt;&lt;div&gt;However, having an evolutionary project stagnate under software rot due to an endless series of quick fixes and shortcuts makes equally small sense. The concept of &lt;a href="http://www.martinfowler.com/bliki/TechnicalDebt.html"&gt;technical debt&lt;/a&gt; is a powerful metaphor for reasoning about these things. Don't take a loan if you can't afford to eventually pay it back.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;The road to hell is paved with good intentions&lt;/span&gt;&lt;/div&gt;&lt;div&gt;To apply TDD can be difficult and there are numerous things you can do with it that puts you in a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_20"&gt;straitjacket&lt;/span&gt; rather than giving you wings. It is quite possible to device inefficient tests that take ages to construct and ages to run, while providing minimal benefit. This however is a question of implementation and I will leave it for another day.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;So, in summary:&lt;/span&gt; Test Driven Development is the dog's bollocks, but should be applied as part of an overall strategy in projects where the aim is to build solutions of high quality that are easy to maintain and expand.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I suspect that for a large number of people this post has been preaching to the choir, but it would be interesting to hear more opinions and experiences of when TDD is not worth it. My own views are tainted by my very positive experience of TDD so I am bad at taking the other side of the argument. Drop a comment either way!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7888275152424656007-3292466894559920093?l=omgwtftdd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://omgwtftdd.blogspot.com/feeds/3292466894559920093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omgwtftdd.blogspot.com/2009/01/test-driven-development-what-is-it-good.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/3292466894559920093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/3292466894559920093'/><link rel='alternate' type='text/html' href='http://omgwtftdd.blogspot.com/2009/01/test-driven-development-what-is-it-good.html' title='Test Driven Development - What is it good for?'/><author><name>Erik Rydeman</name><uri>http://www.blogger.com/profile/04353346939599565563</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_-rXD_s1vAYE/SYIiIISIQuI/AAAAAAAAAQI/lnLGpafWiuM/S220/bluesky.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7888275152424656007.post-282300810496009325</id><published>2009-01-30T12:33:00.000-08:00</published><updated>2009-02-10T04:41:39.093-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTF'/><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='OMG'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>The first post - About the blog</title><content type='html'>&lt;div class="abstract"&gt;&lt;strong&gt;Abstract:&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Hello!&lt;/li&gt;&lt;li&gt;Every post in this blog will have an abstract like this to make stuff quickly graspable for people googling.&lt;/li&gt;&lt;li&gt;This blog is mainly about TDD, which I love. It is also about .NET and architecture.&lt;/li&gt;&lt;li&gt;The target audience is people new to TDD, as well as experienced practitioners interested in software architecture.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hi there &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;internet&lt;/span&gt; wanderer and welcome to my blog!&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since this is the first post here comes the mandatory introductory snippet, setting the tone for the posts that will follow.&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;What's it about?&lt;/span&gt;&lt;/span&gt;&lt;div&gt;As you may have guessed from the title, TDD will play a central part in the musings of this blog. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OMG&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;WTF&lt;/span&gt; will play a lesser part, sticking to the background. :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;Test Driven &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;Development&lt;/span&gt; is a big passion of mine, and in my work as a web developer I have practiced it daily for a long time, tackling obstacles with it, leaned on it, built both great and foolish things in its name, and felt the benefits of it through its presence and absence in various projects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this blog I will talk about the problems and solutions related to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;TTD&lt;/span&gt; I'm currently obsessing about, hopefully sparking discussion from other practitioners who've been there, and sparking ideas and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;questions&lt;/span&gt; in developers who haven't.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TDD is not something that lives in isolation however, and this blog will also be about software architecture, new technologies on the .NET platform and other interesting things. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Who is the blog for?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;TDD has become quite a fashionable doctrine to subscribe to in the past couple of years. For many organisations it is an integral part of the development process, and most books from learned men takes the presence of a test suite for granted. Something to lean on for refactoring, measure the code coverage of and use as a measure of the quality of the code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For many developers however, TDD is a buzzword, and writing unit tests is something they've heard they ought to be doing, but not something that's done in practise. Indeed, if you're not writing any unit tests, how do you begin? Most projects where unit testing is absent does not have an architecture that lends itself well to start writing tests, so how are the developers in the project supposed to learn unit testing even if they want to? Unit testing in such projects often requires you to break existing dependencies, something that is hard to do at the best of times.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The only real way to learn something is through practice. This blog aims to give practical examples of common ways to write Unit Tests, targeted at people with limited experience. I will try to provide examples of the basics, and show what you need to do to start incorporating tests into both your existing and new projects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For Test Driven people who are already flying, this blog aims to provide interesting material on architecture and ways to make your life and coding easier and more elegant. We'll see how that goes. :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7888275152424656007-282300810496009325?l=omgwtftdd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://omgwtftdd.blogspot.com/feeds/282300810496009325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omgwtftdd.blogspot.com/2009/01/first-post-about-blog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/282300810496009325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7888275152424656007/posts/default/282300810496009325'/><link rel='alternate' type='text/html' href='http://omgwtftdd.blogspot.com/2009/01/first-post-about-blog.html' title='The first post - About the blog'/><author><name>Erik Rydeman</name><uri>http://www.blogger.com/profile/04353346939599565563</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_-rXD_s1vAYE/SYIiIISIQuI/AAAAAAAAAQI/lnLGpafWiuM/S220/bluesky.jpg'/></author><thr:total>1</thr:total></entry></feed>
