<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Derik Whittaker : Agile</title><link>http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx</link><description>Tags: Agile</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Convention Binding to Ninject 3 -- Resolving ‘Value Cannot be Null’ Exception</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2012/08/12/convention-binding-to-ninject-3-resolving-value-cannot-be-null-exception.aspx</link><pubDate>Sun, 12 Aug 2012 12:26:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70273</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=70273</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=70273</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2012/08/12/convention-binding-to-ninject-3-resolving-value-cannot-be-null-exception.aspx#comments</comments><description>&lt;p&gt;Recently I was creating a new &lt;a href="http://www.asp.net/mvc/mvc4"&gt;MVC4&lt;/a&gt;&amp;nbsp; application and of course I wanted to use &lt;a href="http://devlicio.us/controlpanel/blogs/posteditor.aspx/www.ninject.org"&gt;Ninject&lt;/a&gt; as my IoC container.&amp;nbsp; The first thing I did was to download and install the following NuGet packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://nuget.org/packages/Ninject.MVC3"&gt;Ninject.MVC3&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/packages/ninject.extensions.conventions"&gt;Ninject.Extensions.Conventions&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/packages/CommonServiceLocator.NinjectAdapter"&gt;CommongServiceLocator.NinjectAdapter&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After I got these setup I opened up the NinjectWebCommon.cs class and started to add code to the RegisterServices method.&amp;nbsp; The first thing i did was to add the code below;&lt;/p&gt;
&lt;pre name="code" class="c#"&gt;            kernel.Bind(scanner =&amp;gt;
            {
                try
                {
                    scanner.FromAssemblyContaining()
                    .SelectAllClasses()
                    .BindDefaultInterface();

                    scanner.FromAssemblyContaining()
                        .SelectAllClasses()
                        .BindDefaultInterface();

                    scanner.FromAssemblyContaining()
                        .SelectAllClasses()
                        .BindDefaultInterface();
                }
                catch (Exception e) // added to try to get the exception message
                {
                    Debug.WriteLine(e);
                    throw;
                }
            });&lt;/pre&gt;
&lt;p&gt;The above code would step over the first scanner call w/ no issues, in fact if that was the ONLY statement it all worked as expected, however when it stepped onto the second scanner. call I would get the following error.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;System.ArgumentNullException: Value cannot be null. Parameter name: first&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Because I knew everything worked fine with only one scanner. call i decided to give it a go w/&amp;nbsp; creating a unique kernal.Bind for each assembly i wanted scanned as below:&lt;/p&gt;
&lt;pre name="code" class="c#"&gt;            kernel.Bind(scanner =&amp;gt; scanner.FromAssemblyContaining()
                                       .SelectAllClasses()
                                       .BindDefaultInterface());

            kernel.Bind(scanner =&amp;gt; scanner.FromAssemblyContaining()
                                       .SelectAllClasses()
                                       .BindDefaultInterface());

            kernel.Bind(scanner =&amp;gt; scanner.FromAssemblyContaining()
                                       .SelectAllClasses()
                                       .BindDefaultInterface());&lt;/pre&gt;
&lt;p&gt;This did the trick, I could now setup the bindings for multiple assemblies with no issues.&amp;nbsp; So it appears that with this version of the Extensions class for ninject you need to do each action as a unique .Bind method.&lt;/p&gt;
&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70273" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/ASP.Net+MVC/default.aspx">ASP.Net MVC</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Ninject/default.aspx">Ninject</category></item><item><title>Testing that EventHandlers were wired up correctly with NUnit and Rhino Mocks</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2010/08/24/testing-that-eventhandlers-were-wired-up-correctly-with-nunit-and-rhino-mocks.aspx</link><pubDate>Tue, 24 Aug 2010 11:04:04 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:61665</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=61665</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=61665</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2010/08/24/testing-that-eventhandlers-were-wired-up-correctly-with-nunit-and-rhino-mocks.aspx#comments</comments><description>&lt;p&gt;Today I was trying to wrap some code in some tests (I got lazy and did not create the tests first… shot me).&amp;#160; What I was trying to ensure was that my event handlers I passed into a method were actually being wired up for usage.&amp;#160; Now I searched around the net for a while to see if there was a elegant solution to this problem but I could not find one.&amp;#160; Below is the solution I came up with.&amp;#160; Mind you this may not be a great solution, hell it may just down right suck but it works for me.&lt;/p&gt;  &lt;p&gt;First things first, her is the method i was trying to provide coverage for&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;public void GetAppointments( DateTime? from, DateTime? to, 
    EventHandler localRequestStarted,
    EventHandler remoteRequestStarted,
    EventHandler&lt;object&gt;&amp;gt; requestFinsished )
{
    var currentUser = _sessionManager.GetValue();
    var dataRequest = new AppointmentDataRequest( new AppointmentParameterContext( currentUser.ResourceIds, from.Value, to.Value ) );

    dataRequest.LocalRequestStarted += localRequestStarted;
    dataRequest.RemoteRequestStarted += remoteRequestStarted;
    dataRequest.RequestFinished += requestFinsished;

    _dataManager.Fetch( dataRequest );
}
&lt;/pre&gt;

&lt;p&gt;As you can see there are 3 lines in the above code where the passed in EventHandlers are being attached.&amp;#160; I wanted to ensure this. But what you may also see is that I have no direct access to the dataRequest object which is being created in this method.&amp;#160; That is where our handy rhino mocks library comes in.&amp;#160; With Rhino Mocks I am able to get the pointer to the various values which are passed into methods.&amp;#160; Check out the test below and you will see how this is done.&lt;/p&gt;

&lt;p&gt;My unit test&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[Test]
public void GetAppointments_WhenCalled_EnsureWillWireupEventsCorrectly()
{
    var dataManager = MockRepository.GenerateMock&amp;lt;IDataManager&amp;gt;();
    var sessionManager = MockRepository.GenerateMock&amp;lt;ISessionManager&amp;gt;();

    var currentUser = new CurrentUser();
    sessionManager.Stub( x =&amp;gt; x.GetValue&amp;lt;CurrentUser&amp;gt;() ).Return( currentUser );

    var provider = new AppointmentProvider( dataManager, null, sessionManager, null );
    bool localWired = false, remoteWired = false, requestFinishedWired = false;

    EventHandler&amp;lt;LocalRequestStartedEventArgs&amp;gt; localRequest = ( s, arg ) =&amp;gt; { localWired = true; };
    EventHandler&amp;lt;RemoteRequestStartedEventArgs&amp;gt; remoteRequest = ( s, arg ) =&amp;gt; { remoteWired = true; };
    EventHandler&amp;lt;RequestFinishedEventArgs&amp;lt;object&amp;gt;&amp;gt; requestFinished = ( s, arg ) =&amp;gt; { requestFinishedWired = true; };

    provider.GetAppointments( DateTime.Now, DateTime.Now, localRequest, remoteRequest, requestFinished );

    IList&amp;lt;object[]&amp;gt; argumentsForCallsMadeOn = dataManager.GetArgumentsForCallsMadeOn( x =&amp;gt; x.Fetch( Arg&amp;lt;DataRequest&amp;gt;.Is.Anything ) );

    var dataRequest = (AppointmentDataRequest)argumentsForCallsMadeOn[ 0 ][ 0 ];

    dataRequest.RaiseLocalRequestStarted();
    dataRequest.RaiseRemoteRequestStarted();
    dataRequest.RaiseDataRequestFinished( DataRequestType.UserLogin, DataRequestResult.Unknown, null, null );

    Assert.That( localWired, Is.True );
    Assert.That( remoteWired, Is.True );
    Assert.That( requestFinishedWired, Is.True );

}&lt;/pre&gt;

&lt;p&gt;As you can see this test has a lot going on, but let me explain some of this for you.&lt;/p&gt;

&lt;p&gt;1) First thing we need to do is create a few local variables which will hold the state of the event firing&lt;/p&gt;

&lt;p&gt;2) Next we want to create local copies of our event delegates in order to push them into our method&lt;/p&gt;

&lt;p&gt;3) Next is time for the Rhino Mock magic.&amp;#160; Notice how I am calling the GetargumentsForCallsMadeOn() method.&amp;#160; This is a method in Rhino Mocks which allows me to reach into the call stack and pull out the values which were pushed into a method when it was called.&amp;#160; I then cast the argument i want to its native type.&lt;/p&gt;

&lt;p&gt;4) In order to ensure the events were wired up I need to call the various ‘raise’ methods in order to trigger them.&amp;#160; Doing this should cause my local state holders for the events to be changed and this is what we actually want to ensure&lt;/p&gt;

&lt;p&gt;5) Ensure the event state variables were set to true.&lt;/p&gt;

&lt;p&gt;There you have it, a simple (well kinda) way to ensure that your events have been registered correctly in your code.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/object&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=61665" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/.Net/default.aspx">.Net</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Rhino+Mocks/default.aspx">Rhino Mocks</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/HowTo/default.aspx">HowTo</category></item><item><title>Do you have an Action Plan to Tackle your Technical Debt?</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2010/04/09/do-you-have-an-action-plan-to-tackle-your-technical-debt.aspx</link><pubDate>Fri, 09 Apr 2010 11:20:33 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56872</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=56872</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=56872</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2010/04/09/do-you-have-an-action-plan-to-tackle-your-technical-debt.aspx#comments</comments><description>&lt;p&gt;As a general rule all software development teams will create technical debt during the construction of their product.&amp;#160; Creating this debt is in no way an indicator that the team is bad or not talented, but rather is an indicator that they understand that there are always tradeoffs when building an application.&amp;#160; The fact of the matter is we are in the business of building applications which need to get to market and while building these applications we will be faced with decisions about trade off&amp;#39;s.&amp;#160; &lt;br /&gt;Now I stated that creating technical debt is not any indicator of talent, but I will say that not creating an action plan to resolve this technical debt is a major indicator of experience.&amp;#160; All software teams must maintain a list of items (non-business features) that need to be addressed at some point in the future.&amp;#160; They need to mandate that this list be reviewed on a regular basis and priority be put on each item along with an action plan.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What counts as technical debt? .... Anything :)&amp;#160; No really:&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Design trade offs you make&lt;/li&gt;    &lt;li&gt;Areas in code which could be simplified by the addition of a new tool or library (this may not have been a technical trade off at the time of construction, but new libraries could simplify the code.&lt;/li&gt;    &lt;li&gt;Areas in code &amp;#39;that are not to be touched for fear of breaking&amp;#39; (you KNOW your projects has these dark corners)&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Why Technical Debt is created?&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;   &lt;ol&gt;     &lt;li&gt;&lt;/li&gt; When faced with a decision in regards to &amp;#39;simple, quick, easy but not the best&amp;#39; or &amp;#39;longer, more complicated but right&amp;#39; many times we reach for the &amp;#39;easy button&amp;#39;.&amp;#160; Reaching for this easy button is ok, but only as long as you understand the tradeoffs.&lt;/ol&gt;    &lt;li&gt;Deadlines loom and we &amp;#39;cut to finish&amp;#39;.&lt;/li&gt;    &lt;li&gt;Poor decisions were made by the team&lt;/li&gt;    &lt;li&gt;The team lacks the experience to make good decisions (not normally the case, but it can be)     &lt;br /&gt;&lt;/li&gt; &lt;/strong&gt;  &lt;p&gt;&lt;strong&gt;Why Technical Debt is a burden on your project?&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It creates roadblocks for new development&lt;/li&gt;    &lt;li&gt;Can increase complexity in your codebase making new features more difficult to create&lt;/li&gt;    &lt;li&gt;Causes re-work to be performed in the future, which could take longer than had it been done &amp;#39;right&amp;#39; in the first place&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Why having the list is a good thing?&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Keeps the list visible and if it is visible it will receive attention&lt;/li&gt;    &lt;li&gt;Keeps people informed of bad (potentially bad) tradeoffs which were made in the past&lt;/li&gt;    &lt;li&gt;Keeps people informed of potential refactor points&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Why having the list is a bad thing?&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;   &lt;ol&gt;     &lt;li&gt;&lt;/li&gt; Admits to others (especially management) that your code may have flows (I actually see this as a good thing, but others do not)&lt;/ol&gt;    &lt;li&gt;Reminds you of all the bad decisions you made... wait that is bad... NO&lt;/li&gt; &lt;/strong&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;How we maintain our action plan for Technical Debt?:&lt;/strong&gt;    &lt;br /&gt;Our team has created a list in our team wiki and grouped the items in the list by product feature.&amp;#160; Each team is expected to add items to this list as they come across items in code which need to be addressed in the future.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;When we add our items we provide the following level of information:   &lt;br /&gt;&lt;em&gt;Short Description:     &lt;br /&gt;Original Reason for the debt (if known):      &lt;br /&gt;Risk of change: (high, meduim, low)      &lt;br /&gt;Risk if not changed:      &lt;br /&gt;Action Plan:      &lt;br /&gt;Date/Release Debt removed:&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;At the end of the day the code you build is the code you are going to be required to maintain over the long haul.&amp;#160; If you make the decision to not activily address your technical debt not only will your pain increase while working on your codebase but your customers will start to suffer because the cycle time to create new releases will increase and new features will flow slower and slower.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56872" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Craftsmanship/default.aspx">Craftsmanship</category></item><item><title>Depends vs Call, Do you know and understand the difference in NAnt?</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/11/20/depends-vs-call-do-you-know-and-understand-the-difference-in-nant.aspx</link><pubDate>Fri, 20 Nov 2009 11:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53805</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=53805</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=53805</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/11/20/depends-vs-call-do-you-know-and-understand-the-difference-in-nant.aspx#comments</comments><description>&lt;p&gt;This past week I was taking a look at one of our build scripts as it appeared to be taking a bit longer than everyone wanted.&amp;nbsp; Because I am very close to the file (authored about 50% of it) I decided that in place of just diving in and looking at the raw source I would instead run the script with the given options I needed and record the output (nant.exe -buildfile:Demo.xml SomeTargetName &amp;gt; Log.txt) and once the run was complete I would take a look at the output and look for &amp;lsquo;out of normal items&amp;rsquo;.&amp;nbsp; Within a few minutes of scanning the file I noticed something ODD, we were compiling all of our code twice (just to be double sure it compiled correctly of course).&lt;/p&gt;
&lt;p&gt;Now that I knew the issue, double compiling 5 solutions for each build, it was time to determine why we were doing this.&amp;nbsp; As I started to follow the call chain I noticed something that was a bit interesting to me.&amp;nbsp; It appeared that were we calling a target via a &amp;lt;Call&amp;gt; command vs a Depends command the entire call stack would be re-executed.&amp;nbsp; A quick google search lead me to this page (&lt;a href="http://nant.sourceforge.net/release/0.85-rc1/help/fundamentals/targets.html"&gt;here&lt;/a&gt;) which had the answer to my problem.&amp;nbsp; Per the Nant documentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a&gt;&lt;span style="color:#000000;"&gt;A target gets executed only once, even when more than one target depends on it (see the previous example). However, when the &lt;/span&gt;&lt;/a&gt;&lt;a href="http://nant.sourceforge.net/release/0.85-rc1/help/tasks/call.html"&gt;&lt;span style="color:#000000;"&gt;&amp;lt;call&amp;gt;&lt;/span&gt;&lt;/a&gt; task is used to execute a target, both the target and all its dependent targets will be re-executed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hum.. problem found, root caused determined.&amp;nbsp; Now it was simply a matter of resolving the issue. SWEET &lt;/p&gt;
&lt;p&gt;To better illustrate this scenario I have created a simple example (with screenshots to boot).&lt;/p&gt;
&lt;p&gt;Imagine you have the following Nant script (sorry, could not get the XML to not be &amp;lsquo;xml&amp;rsquo; and rather be code/text)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_16734779.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_1D2650FC.png" width="484" border="0" height="306" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If you take a look at the script above you will see 2 things.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I have a few targets that use Depends to call other targets&lt;/li&gt;
&lt;li&gt;I have one target (Target_Z) which simply does a call out to the other targets it needs&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In order to understand how &amp;lsquo;Depends&amp;rsquo; works and the fact that it will NOT double call a target lets take a look at the call stack if we invoke Target_A directly.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_1CBA1E07.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_1F62D9B8.png" width="484" border="0" height="313" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;As you can see from the image, each target is only invoked once even though that Target_C is referenced by both Target_A and Target_B&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now, to understand how &amp;lsquo;&amp;lt;Call&amp;gt;&amp;rsquo; works and the fact that it will double call targets let take a look at the call stack if were to invoke Target_Z directly. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_2615E33B.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_7EDB9A05.png" width="484" border="0" height="424" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see from the image above, Since Z calls both A &amp;amp; B we get the repeating of each of their targets, so Target_B and Target_C are each called multiple times and this could be really bad on performance.&lt;/p&gt;
&lt;p&gt;Now that you understand the difference between &amp;lt;Call&amp;gt; and &amp;lsquo;Depends&amp;rsquo; use this information wisely and with caution.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Oh, by not double calling our compile for all 5 solutions we shaved about 4-5 minutes off of our CI build&amp;hellip; NOT TOO BAD&lt;/p&gt;
&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53805" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Nant/default.aspx">Nant</category></item><item><title>Simple Kick Start Example using MEF (Preview 8)</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx</link><pubDate>Tue, 27 Oct 2009 10:34:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53159</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=53159</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=53159</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx#comments</comments><description>&lt;p&gt;If your application needs extension points what do you do? Building a plugin based system is not cutting edge, it is not rocket science.&amp;#160; However, it does take a little effort and can be a bit painful depending on your implementation.&amp;#160; The guys at MS (Glen Block and crew) has been working on this kickin framework for about a year now called the &lt;a href="http://mef.codeplex.com/"&gt;Managed Extensibility Framework&lt;/a&gt; (most commonly known as MEF).&amp;#160; The core goal of MEF is to simplify the creation of extensible applications. MEF offers discovery and composition capabilities that you can leverage to load application extensions.&lt;/p&gt;  &lt;p&gt;There are a metric crap-ton of samples out on the net which show how to get running with MEF, however many of the posts are based off of older previews and most are also incomplete in terms of the code they show you on screen.&amp;#160; What I would like to do is provide a detailed how-to on getting your first (simple) MEF application up and running.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Goal of the demo code?&lt;/b&gt;     &lt;br /&gt;For this demo code we are going to put together a very simple rules plug-in engine.&amp;#160; The goal is to be able to add in a new IRule at any point and have your application pick it up.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;What is needed?      &lt;br /&gt;&lt;/b&gt;If you have not already done so head out to &lt;a title="http://mef.codeplex.com/" href="http://mef.codeplex.com/"&gt;http://mef.codeplex.com/&lt;/a&gt; and grab the latest source download.&amp;#160; More than likely you will need to download and compile all the source in order to get working binaries (hey, it is a preview after all).&amp;#160; Once you have compiled the source you need to grab the output from the ComponentModel project (assembly name is System.ComponentModel.Composition) and include this into your project.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Putting it together?&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;Creating the rule Interface : IRule &lt;/i&gt;    &lt;br /&gt;This is needed because in order to define a plug-in you need to define what that plug-in looks like. &lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;public interface IRule
{
    void DoIt();
    string Name { get; }
    string Version { get; }
    string Description { get; }
}&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;i&gt;Creating a rule instance (or two) 
    &lt;br /&gt;&lt;/i&gt;Now that we have our rule interface we need to create specific instances of the rule and mark them for export.&amp;#160; Marking them for Export simply entails adding a attribute provided by the MEF framework and this attribute allows you to describe your plug-in to the MEF framework so it can pick it up. &lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[Export( typeof( IRule ) )]
internal class RuleInstance1 : IRule
{
    public void DoIt() {}

    public string Name
    {
        get { return &amp;quot;Rule Instance 1&amp;quot;; }
    }

    public string Version
    {
        get { return &amp;quot;1.0.0.0&amp;quot;; }
    }

    public string Description
    {
        get { return &amp;quot;Some Rule Instance&amp;quot;; }
    }
}

[Export( typeof( IRule ) )]
public class RuleInstance2 : IRule
{
    public void DoIt() {}

    public string Name
    {
        get { return &amp;quot;Rule Instance 3&amp;quot;; }
    }

    public string Version
    {
        get { return &amp;quot;1.1.0.0&amp;quot;; }
    }

    public string Description
    {
        get { return &amp;quot;Some Rule Instance&amp;quot;; }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;i&gt;Creating the holder for all your plug-ins 
    &lt;br /&gt;&lt;/i&gt;In order to have your application know about the plug-ins that MEF has found you need to define a storage location for them.&amp;#160; We will do this by creating a property of IList&amp;lt;IRule&amp;gt; which will hold each instance.&amp;#160; When we create this storage location we need to tell MEF that we are going to use this as a storage location and to do this you need to mark it with the ImportMany (use this attribute if you want a collection, use Import for only a single instance) attribute.&amp;#160; This is another special attribute provided by the MEF framework. &lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[ImportMany( typeof( IRule ) )]
internal IList&amp;lt;IRule&amp;gt;: _rules { get; set ;}&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;i&gt;Creating the logic to load the plugin 
    &lt;br /&gt;&lt;/i&gt;Now that we have all the heavy lifting out of the way in terms of defining our Imports and Exports it is time to setup our application to consume the data.&amp;#160; It is here where you tell MEF where to look to find your exports (plug-ins) and what to do with them once you have found them. &lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public void Init()
{
    var catalog = new AggregateCatalog();
    var container = new CompositionContainer( catalog );
    var batch = new CompositionBatch();
    batch.AddPart( this );
    // because all our types are in the same assembly we simply use the current one.    
    catalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );
    container.Compose( batch );
    foreach ( var rule in _rules )
    {
        Debug.WriteLine( rule.Name );
    }
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Wrapping it up 
    &lt;br /&gt;&lt;/b&gt;As you can see getting a simple example of MEF up and running is a pretty simple task (great job MEF team).&amp;#160; You should be able to get this up and running in about 10 minutes.&amp;#160; You should also have all the code you need in order to get this running.&amp;#160; I hope this helps kick-start someone’s learning and adoption of MEF.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53159" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Testing only the code of value</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/10/07/testing-only-the-code-of-value.aspx</link><pubDate>Wed, 07 Oct 2009 11:48:25 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:52340</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=52340</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=52340</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/10/07/testing-only-the-code-of-value.aspx#comments</comments><description>&lt;p&gt;I am 99% sure I have had a post like this in the past, but my google-foo was weak today and I could not find it.&amp;#160; Do not let anyone blow smoke up your back side, testing is expensive, testing takes time but most importantly testing &lt;em&gt;can&lt;/em&gt; help improve the quality of your code.&lt;/p&gt;  &lt;p&gt;If you are going to spend the time and money to create automated, rerun-able unit tests make sure you spend your time/money wisely.&amp;#160; Make sure you test the code that matters, test the code which is complicated (keep in mind a LOC count does NOT equal complexity).&lt;/p&gt;  &lt;p&gt;Today when scanning some code in another part of our project I came across this tests:&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;public void AdminSetIDTest()
{
	var target = new CreateTaskActivity();
	int expected = 50;
	int actual;
	target.AdminSetID = expected;
	actual = target.AdminSetID;
	Assert.AreEqual(expected, actual);
}&lt;/pre&gt;

&lt;p&gt;When I looked at this tests 2 bells immediately went off in my mind&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The name of this tests SUCKS BALLS and does not clearly convey the intent of the test&lt;/li&gt;

  &lt;li&gt;This is testing that a property getter works (no, there is NO logic behind the getter/setter)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;If you disregard #1 from above for now (but remember clear/concise names do matter) and focus on #2 this tests adds no value to the test suite.&amp;#160; All this test is doing is ensuring that the .Net framework does its job.&amp;#160; This test is a total waste of time and energy and can actually cost you more time/money in the long run because you may have to change the useless test over time as you refactor.&lt;/p&gt;

&lt;p&gt;The key take away from this is simple.&amp;#160; You always have limited time and money when trying to get a product out the door.&amp;#160; Unit testing IMO can always help you to create a better product, but make sure you use your time and money in a way in which will allow you to maximize your ROI.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=52340" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Opinion/default.aspx">Opinion</category></item><item><title>Your unit test may smell if…….!</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/09/09/your-unit-test-may-smell-if.aspx</link><pubDate>Wed, 09 Sep 2009 17:28:30 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:51179</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=51179</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=51179</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/09/09/your-unit-test-may-smell-if.aspx#comments</comments><description>&lt;p&gt;If you find yourself using reflection in your unit test to push &amp;#39;stub’ data into it your test just may smell.&amp;#160; Now there are times (especially when dealing with legacy code) that you need use reflection to crack open a class to push/pull values but I would strongly suggest you consider the solutions I am going to suggest.&lt;/p&gt;  &lt;p&gt;Utilizing the wrap method (see &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052"&gt;Working with Legacy Code&lt;/a&gt;) to accomplish your goal.&amp;#160; &lt;/p&gt;  &lt;p&gt;Lets assume you have the following class which you want to test:&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;  public class SomeClass 
  {
    private DateTime _lastVerified;
    private DateTime _lastActivated;
   }&lt;/pre&gt;

&lt;p&gt;Now one way to push data into these fields would be to do the following:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;    [Test]
    public void IsTimeToActivateTrueLastActivatedTheDayBeforeCurrentTimeAfterActivationTimeTest()
    {
      SomeClass accessor = new SomeClass 

      Type type = SomeClass 

      FieldInfo field2 = type.GetField(&amp;quot;_lastActivated&amp;quot;, BindingFlags.Instance | BindingFlags.NonPublic);
      field2.SetValue(accessor, new DateTime(2008, 2, 29, 10, 5, 0));

      FieldInfo field3 = type.GetField(&amp;quot;_lastVerified&amp;quot;, BindingFlags.Instance | BindingFlags.NonPublic);
      field3.SetValue(accessor, new DateTime(2008, 3, 1, 10, 0, 0));
    
      DateTime currentDateTime = new DateTime(2008, 3, 1, 10, 10, 0);

      MethodInfo method = type.GetMethod(&amp;quot;SomeMethod&amp;quot;, BindingFlags.Instance | BindingFlags.NonPublic);
      object result = method.Invoke(accessor, new object[1] { currentDateTime });

      bool isTime = (bool)result;

      Assert.AreEqual(true, isTime);
      Assert.AreEqual(currentDateTime, field3.GetValue(accessor));
    }&lt;/pre&gt;

&lt;p&gt;Now this works, but if you do this over and over again you will kill yourself with reflection code.&lt;/p&gt;

&lt;p&gt;Option 1) Create a subclass of your class and hide the reflection inside your subclass&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public class MySubclassOfSomeClass : SomeClass
  {
    public void SetLastActivatedTime( DateTime value )
    {
    	// set the value via reflection here
    {
	
    public void SetLastVerifiedTime( DateTime value )
    {
    	// set the value via reflection here
    {
   }&lt;/pre&gt;

&lt;p&gt;The code above will still use reflection to set the value, but it will hide the usage of reflection from your unit test and will present a less noisy test to future developers&lt;/p&gt;

&lt;p&gt;Option 2) Change the scope of the fields and subclass and extend&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;  public class SomeClass 
  {
    protected DateTime _lastVerified;
    protected DateTime _lastActivated;
   }

public class MySubclassOfSomeClass : SomeClass
  {
    public void SetLastActivatedTime( DateTime value )
    {
    	_lastActivated = value;
    {
	
    public void SetLastVerifiedTime( DateTime value )
    {
    	_lastVerified = value;
    {
   &lt;/pre&gt;

&lt;p&gt;If you change the scope of the fields to protected you could subclass the original class and do the same as option 1, but because you have access to the fields via inheritance there is no need to use reflection.&lt;/p&gt;

&lt;p&gt;So, remember that tests are code to and if you feel pain writing test you may be doing it wrong.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=51179" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Opinion/default.aspx">Opinion</category></item><item><title>Quantity is NOT a measure of Quality</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/08/21/quantity-is-not-a-measure-of-quality.aspx</link><pubDate>Fri, 21 Aug 2009 14:08:15 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:50163</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=50163</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=50163</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/08/21/quantity-is-not-a-measure-of-quality.aspx#comments</comments><description>&lt;p&gt;Today I was asked what I thought about asking each of our feature teams to report the total number of new unit tests created during their iteration.&amp;#160; My knee-jerk reaction was to ask the person WTF were they thinking.&amp;#160; However, my better sense (yea, I have a little common sense) kicked in.&lt;/p&gt;  &lt;p&gt;Before I started to explain my point of view, I asked the person what the intent of this requirement was?&amp;#160; Their reasons were below:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;With this in place it will keep the developers inline in terms of knowing that creating tests is important&lt;/li&gt;    &lt;li&gt;More tests == more coverage which SHOULD increase code quality&lt;/li&gt;    &lt;li&gt;Simple measurement tool to track work items&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Once all the points were stated, only then did I state my view.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Reason: With this in place it will keep the developers inline in terms of knowing that creating tests is important&lt;/strong&gt;      &lt;br /&gt;I am ok with this being a goal as it is important for each developer to clearly understand what is expected of them when creating code.&amp;#160; However, I would rather show them why creating unit tests should lead to better code with less bugs rather than force them to write tests or else.&amp;#160; &lt;br /&gt;      &lt;br /&gt;We as a profession need to start taking the stance that we must &lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2008/11/04/removing-words-like-convince-convert-and-persuade-from-our-vocabulary.aspx"&gt;convince or persuade&lt;/a&gt; developers, but rather show them why one way may be preferred or better.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Reason: More tests == more coverage which SHOULD increase code quality&lt;/strong&gt;      &lt;br /&gt;In general principle I agree with this statement, however unit test count is NOT a good measure.&amp;#160; Here is why:      &lt;br /&gt;      &lt;br /&gt;I could spend 2-3 hours creating a single unit test that proves out a extremely critical path in code which adds great value or I can spend 2-3 hours created 20+ test that add little to no value.&amp;#160; It is because of this single fact that count of tests (like lines of code count) can be a very, very useless measure.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Reason: Simple measurement tool to track work items&lt;/strong&gt;      &lt;br /&gt;Well, I guess there is only one thing I could say for this one….When should I turn in my TPS reports       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Anyway, If you are reading this and can take anything away, it should be this. Measurements are good, but make sure you are measuring the right metric.&amp;#160; In terms of measuring code, lines of code and count of tests may not be the best measurement.&amp;#160; &lt;/p&gt;  &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=50163" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Opinion/default.aspx">Opinion</category></item><item><title>Tests are not ‘Tasks’ you put on a backlog…</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/07/27/tests-are-not-tasks-you-put-on-a-backlog.aspx</link><pubDate>Tue, 28 Jul 2009 00:57:50 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:49581</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=49581</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=49581</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/07/27/tests-are-not-tasks-you-put-on-a-backlog.aspx#comments</comments><description>&lt;p&gt;Today I had a conversation with our ‘scrum of scrum’ masters (we have 7 different scrum teams on our product team of 60+) and he asked me why someone would provide ‘developer tests’ as a task for the backlog?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Before I go any further, this is NOT a bait type of email, simply my opinion.&amp;#160; If you do not buy into the testing (either TDD or test after) then you can disregard this post.&amp;#160; But if you do buy into the testing concepts keep reading.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In order to gain a better understanding of the context I asked my SoS master for more background on this project and what they were doing.&amp;#160; After a brief conversation I became very clear to me that this developer did not think of testing as part of his requirement of building out a feature, but rather as a stand alone deliverable that he needed to deliver at the end of the sprint.&lt;/p&gt;  &lt;p&gt;I explained that all developers on our team need to stop thinking in this way and to start looking at tests as ‘first class citizens’ when creating code.&amp;#160; I believe the exact statement I gave him was:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;When developers are creating a feature, the unit tests which prove the feature as being valid is just as critical as the code which implements the feature.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Quite simply, IN MY OPINION if you buy into the testing concepts stop thinking about tests as a second class citizen and start thinking about them as part of your deliverable.&lt;/p&gt;  &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=49581" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Opinion/default.aspx">Opinion</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Craftsmanship/default.aspx">Craftsmanship</category></item><item><title>Throw away and rebuild or refactor from within</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/07/13/throw-away-and-rebuild-or-refactor-from-within.aspx</link><pubDate>Mon, 13 Jul 2009 19:39:19 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:49367</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=49367</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=49367</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/07/13/throw-away-and-rebuild-or-refactor-from-within.aspx#comments</comments><description>&lt;p&gt;The other day on Twitter there was a stream whether it is better to completely scrap an applications code base and start over, or refactor from within.&amp;#160; Now I do want to state right now:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The information here is based on my experiences and is simply my opinion.&amp;#160; I know this is almost on par with the average biblical debate so lets just agree to disagree now.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Anyway, now that I have put on the standard disclaimer lets continue on with the post.&amp;#160; As I stated there was a debate on which was better, rewrite or refactor…..&lt;/p&gt;  &lt;p&gt;Once upon a time I thought that without a doubt that rewriting that crap filled, unmanageable and unextendable code was the ONLY way to succeed.&amp;#160; However, during my career I have come to the conclusion that rewriting was actually the wrong decision and refactor from within is the right one.&amp;#160; Here are some of my thoughts as to why&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Re-Writing     &lt;br /&gt;Pros:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You get to scrap that old code that smells.&lt;/li&gt;    &lt;li&gt;You get to build a better, more maintainable architecture going forward.&lt;/li&gt;    &lt;li&gt;You get to use the latest technologies and this is always the best thing.&lt;/li&gt;    &lt;li&gt;We know the business better now, this will allow us to create a better, more flexible application&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is the business going to actually stop innovating or changing long enough to let you completly rewrite the application?&amp;#160; NO&lt;/li&gt;    &lt;li&gt;If they are not going to stop moving forward this means there is going to be a maintance team doing this type of work.&amp;#160; This means you are coding against a moving set of requirements that will change daily… FAIL&lt;/li&gt;    &lt;li&gt;What makes you think that you can write it better the second time around?&amp;#160; If you wrote unmaintable crap the first time why do you think you are better now (ok, assuming you did write it the first time).&amp;#160; &lt;/li&gt;    &lt;li&gt;More than likely you are simply going to pile on the latest tech because you can.&amp;#160; Because you are an ego freak and the only way to write good code is to use new tech&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Refactor from Within     &lt;br /&gt;Pros:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You have the ability to continue delivering new versions of the application with new features.&lt;/li&gt;    &lt;li&gt;You actually increase your knowledge of what ‘crappy’ code looks like and how to fix it.&lt;/li&gt;    &lt;li&gt;You can learn how to refactor your legacy code with minimal risk and learn how to do it a way that allows you to deliver new code&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;This is NOT easy&lt;/li&gt;    &lt;li&gt;This is NOT slow&lt;/li&gt;    &lt;li&gt;There is always the thought that you will never actually be complete and that the refactor effort will be dropped at some point in the future.&amp;#160; If this is true, rest assured that your application will be better off anyway.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ok, there you have it, my list of pros/cons for each (this is not an all encompassing list, just some of my random thoughts).&amp;#160; In my opinion the refactor is a better, safer choice.&amp;#160; But this is not as sexy and takes a ton more effort and patience.&amp;#160; However, I believe in the long run you will be better off.&lt;/p&gt;  &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=49367" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Opinion/default.aspx">Opinion</category></item><item><title>What I expect my Continuous Integration server to do for me.</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/06/04/what-i-expect-my-continuous-integration-server-to-do-for-me.aspx</link><pubDate>Fri, 05 Jun 2009 01:02:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:47676</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=47676</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=47676</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/06/04/what-i-expect-my-continuous-integration-server-to-do-for-me.aspx#comments</comments><description>&lt;p&gt;Recently I had a post where I made the statement &lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2009/05/19/to-ci-or-not-to-ci-did-not-realize-it-was-still-even-a-question.aspx"&gt;&amp;lsquo;To CI or not to CI, did not realize it was still even a question?&amp;rsquo;&lt;/a&gt;.&amp;nbsp; The intent of the post was to assert that I did not realize that having some sort of CI (Continuous Integration)/Build Server was not considered the norm for a development shop.&amp;nbsp; I that post I stated that your CI setup could be as simple as a cron job running a script or be a full fledge product such as &lt;a href="http://www.jetbrains.com/teamcity/index.html"&gt;Team City&lt;/a&gt;, &lt;a href="https://hudson.dev.java.net/"&gt;Hudson&lt;/a&gt; or &lt;a href="http://ccnet.thoughtworks.com/"&gt;CC.Net&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Since I went out and did a rant about how there was no excuse for a team to NOT have a build server I thought I would put together a post on the various things I would expect to see from a CI server.&amp;nbsp; Now I am NOT saying that if your CI setup does not do all these things you are doing the right thing.&amp;nbsp; What I am saying is that the list below (and I am sure I will miss something) are some of the things I expect my CI setup to do for me (in no real particular order).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monitor my source repository and build on changes&lt;/li&gt;
&lt;li&gt;Run my unit tests&lt;/li&gt;
&lt;li&gt;Run various static analysis metrics
&lt;ul&gt;
&lt;li&gt;Code Coverage&lt;/li&gt;
&lt;li&gt;FXCop/Style Cop&lt;/li&gt;
&lt;li&gt;Any of the metrics from NDepend&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Publish assemblies for usage (could be to a test server, a file server or ftp server)&lt;/li&gt;
&lt;li&gt;Build a clean copy of the database from my setup scripts (we have a running list of alters we use to perform upgrades)&lt;/li&gt;
&lt;li&gt;Be able to commit versioned assemblies back into the repository for other teams to use (if that is something your team needs)&lt;/li&gt;
&lt;li&gt;Create some sort of visual graphs/trends for tracking&lt;/li&gt;
&lt;li&gt;Be able to run a build which creates and packages an installer (for deployment)&lt;/li&gt;
&lt;li&gt;Send notifications (emails/post to discussion boards, twits, etc) when there are issues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now I know this is an extensive list.&amp;nbsp; I also know that trying to do all of these things at one time is both daunting and not practical.&amp;nbsp; But these should be the goal.&amp;nbsp; What I will say is this, start small and build.&amp;nbsp; Your goal should be to incorporate these things into your build over time and if htat is your goal you will be amazed what happens.&lt;/p&gt;
&lt;p&gt;Happy building&lt;/p&gt;
&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=47676" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Best+Practice/default.aspx">Best Practice</category></item><item><title>To CI or not to CI, did not realize it was still even a question?</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/05/19/to-ci-or-not-to-ci-did-not-realize-it-was-still-even-a-question.aspx</link><pubDate>Tue, 19 May 2009 20:22:44 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46942</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>17</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=46942</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=46942</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/05/19/to-ci-or-not-to-ci-did-not-realize-it-was-still-even-a-question.aspx#comments</comments><description>&lt;p&gt;Over the past few weeks I have been presenting at a few .Net user groups and one of the questions I asked prior to each session was the number of people who have some sort of CI/build server for their team.&amp;#160; Now keep in mind I qualified this question by stating that this build server could be a cron job, a build script of some sort or a full fledged CI product (team city, Hudson, TFS, etc).&lt;/p&gt;  &lt;p&gt;I continued to be amazed by the number of people who have no CI type of process on their teams.&amp;#160;&amp;#160; I thought (and I &lt;strike&gt;guess &lt;/strike&gt;know that I am wrong) that having some way to ensure your product builds and integrates was just common sense.&lt;/p&gt;  &lt;p&gt;It is little things like this which keeps our profession in the dark ages.&amp;#160; To all the shops out there who do not have a CI process.&amp;#160; GET OFF YOUR ASS AND BUILD ONE.&lt;/p&gt;  &lt;p&gt;&amp;lt;RANT&amp;gt;   &lt;br /&gt;I’m sorry, but if your team does not care about the little details which make your product better what the hell makes you think you will get the big details right?&lt;/p&gt;  &lt;p&gt;Ok, before anyone flames this post with ‘we can do CI because…’ I have a few items&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Use free products (NAnt, CC.Net, Hudson, NUnit, etc)&lt;/li&gt;    &lt;li&gt;Start simple.&amp;#160; Only compile your code… screw the rest&lt;/li&gt;    &lt;li&gt;It does not take that long, really it does not.&amp;#160; A complete noob should be able to get a simple Nant script running as a hourly process in a single day&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;lt;/RANT&amp;gt;&lt;/p&gt;  &lt;p&gt;Ok, rant over.&amp;#160; Really, if your team does not have a CI process add one.&amp;#160; You WILL thank me for it in the long run.&lt;/p&gt;  &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=46942" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Best+Practice/default.aspx">Best Practice</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Rant/default.aspx">Rant</category></item><item><title>Teaching someone to test using an Isolation Framework</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2008/12/30/teaching-someone-to-test-using-an-isolation-framework.aspx</link><pubDate>Tue, 30 Dec 2008 17:21:12 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43560</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=43560</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=43560</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2008/12/30/teaching-someone-to-test-using-an-isolation-framework.aspx#comments</comments><description>&lt;p&gt;Part of my job at work is to teach and mentor other developers on our team.&amp;nbsp; Right now I am in the process of teaching two of our developers how to create unit tests (notice I did NOT say integration tests because most anyone can do those).&amp;nbsp; We are also learning how to create our tests by utilizing an Isolation Framework (aka mocking framework).&lt;/p&gt; &lt;p&gt;I am really excited for this opportunity because I firmly believe that you create better software when you do it by creating tests to prove your code works.&amp;nbsp; I am also excited because both of the developer buy into the idea of testing and are extremely eager to learn how to to better test their code.&lt;/p&gt; &lt;p&gt;Because we had a few days of downtime because of the Christmas holiday before our 1st sprint on our project we thought it would be a good time to do some pairing (guess it would be better called tri-pairing).&amp;nbsp; Our plan of attack was to start to flush out some of the features in our system but do it in a total TDD manor.&amp;nbsp; We were also going to be utilizing the Rhino Mock Isolation framework in our tests.&lt;/p&gt; &lt;p&gt;So over the next 2 days we spent about 12 hours or so working building out our code.&amp;nbsp; Over this time we actually were able to create an complete end to end &amp;#39;version&amp;#39; (I say version because we did not fill in all the functionality of the code but were able to get all the major pieces stubbed out) which allowed us to flush out many, many more business requirement and build a simple, yet flexible code base.&lt;/p&gt; &lt;p&gt;I hope both of my co-workers learned a ton from this exercise, I know I did.&amp;nbsp; This was the first time where I had actually spent any significant amount of time teaching someone who was new to testing how to do so.&amp;nbsp; Sure I had spent an hour here or an hour there, but nothing like this.&amp;nbsp; &lt;/p&gt; &lt;p&gt;What I really wanted to share with everyone is what I learned form this experience.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Slowdown, slowdown, slowdown&lt;br /&gt;&lt;/strong&gt;The first thing you should do when teaching something how to do anything is SLOWDOWN.&amp;nbsp; You have to remember that if you are talking/teaching to someone who is new to this they have to not only try to process the information so they can understand it, they also have to try to remember it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Make NO assumptions, teach as if they know nothing&lt;br /&gt;&lt;/strong&gt;This one was the most important thing I learned.&amp;nbsp; You cannot make assumptions on anything.&amp;nbsp; Anytime you say anything make sure you fully explain it.&amp;nbsp; If you use an acronym EXPLAIN IT.&amp;nbsp; Any time you mention a buzz word EXPLAIN IT.&amp;nbsp; Plan and simple EXPLAIN EVERYTHING&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Have them drive&lt;br /&gt;&lt;/strong&gt;During the teaching part it is critical that you have then code, have them tell you what to do.&amp;nbsp; It is ok for you to &amp;#39;lead&amp;#39; them in the right direction, but you must not always drive.&amp;nbsp; This will really help to drive home the concepts.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Provide examples both with and without the Isolation framework&lt;br /&gt;&lt;/strong&gt;In our case because I was trying to teach them testing using an Isolation framework it really helped when I would create a test (aka integration) with no mocks and then re-create it with mocks.&amp;nbsp; Doing this really helped to explain to them how using the Isolation framework removed dependencies.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Don&amp;#39;t let them skate by&lt;br /&gt;&lt;/strong&gt;Don&amp;#39;t let them simply nod their head as if they understand.&amp;nbsp; Make sure you keep asking them if there is anything you can clear up or explain better.&amp;nbsp; At first they are going to simply say no, they are good.&amp;nbsp; But as you keep asking and start having them drive they WILL start to ask more questions, I promise.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Turn off any coding tools such as ReSharper (or the likes) and do NOT use shortcuts&lt;br /&gt;&lt;/strong&gt;This may have been the biggest issue for us at first.&amp;nbsp; I am pretty good with ReSharper (if I can toot my own horn here) and I was coding with it as I would do if I were by myself.&amp;nbsp; On more than one occasion the would look at me cross-eyed and ask &amp;#39;what the hell just happened&amp;#39;.&amp;nbsp; Finally I simply stopped using it for the first day.&amp;nbsp; On the second day I went back to using R#, but I turned on &lt;a href="http://weblogs.asp.net/rosherove/archive/2007/06/03/train-to-be-a-keyboard-master-with-keyboard-jedi.aspx"&gt;Keyboard Jedi&lt;/a&gt; so they could see what was going on.&amp;nbsp; Even though I turned on Keyboard Jedi, I tried my best to make sure to explain what just happened when used R#.&lt;/p&gt; &lt;p&gt;Anyway, I have rambled on long enough and I think I have pretty much gotten my thoughts out there.&amp;nbsp; I really enjoyed working with these guys and I am looking forward to doing so again when we get back from break.&lt;/p&gt; &lt;p&gt;Hope this helps, &lt;/p&gt; &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43560" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Rhino+Mocks/default.aspx">Rhino Mocks</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Opinion/default.aspx">Opinion</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/HowTo/default.aspx">HowTo</category></item><item><title>StructureMap and Loaded Plugins Gotcha</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2008/12/18/structuremap-and-loaded-plugins-gotcha.aspx</link><pubDate>Fri, 19 Dec 2008 02:33:14 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43448</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=43448</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=43448</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2008/12/18/structuremap-and-loaded-plugins-gotcha.aspx#comments</comments><description>&lt;p&gt;One of the really great things about the latest release of StructureMap is that I do not need to register objects by default if they follow a standard convention (i.e. if I want to register a controller called ‘AuthorController’ and accessed via ‘AuthorController’ I do not need to do anything, SM is smart enough to map this for me).&amp;#160; However, as great as this is, there is one slight issue (may be a bug, do not know need to follow up with Jeremy).&lt;/p&gt;  &lt;p&gt;In the Dimecasts codebase I put the logic to register routes for each controller into each controller.&amp;#160; I then at startup time I loop though all the controllers and register each route.&lt;/p&gt;  &lt;p&gt;The code below is the logic I do for performing this registration&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;	
	var controllerInstances = ObjectFactory.Model.PluginTypes.Where(x =&amp;gt; typeof(BaseController).IsAssignableFrom(x.PluginType));

	foreach (var controllerInstance in controllerInstances) 
	{ 

	var instance = (BaseController)ObjectFactory.GetInstance(controllerInstance.PluginType); 

	instance.RegisterRoutes(RouteTable.Routes); 

	}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;All of this works and works well but when i added a new controller to the application and did not manually register it (aka using the convention of configuration feature) I was not able to load the new controller.&amp;#160; I was a little stumped at first, but then it downed on me that since i am not pre-registering the controller with StructureMap it may not now how to find it.&amp;#160; To test this theory i simply manually registered the controller and bam, all worked.&lt;/p&gt;

&lt;p&gt;I thought I would share this incase anyone else had the same issue.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;

&lt;p&gt;[--- Remember to check out &lt;a href="http://www.dimecasts.net"&gt;www.dimecasts.net&lt;/a&gt; ---]&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43448" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/.Net/default.aspx">.Net</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/StructureMap/default.aspx">StructureMap</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/ASP.Net+MVC/default.aspx">ASP.Net MVC</category></item><item><title>Testing is hard but debugging just sucks A$$</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2008/11/14/testing-is-hard-but-debugging-just-sucks-a.aspx</link><pubDate>Fri, 14 Nov 2008 23:58:05 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43064</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>23</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=43064</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=43064</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2008/11/14/testing-is-hard-but-debugging-just-sucks-a.aspx#comments</comments><description>&lt;p&gt;In my last post (&lt;a href="http://feeds.feedburner.com/~r/Devlicious/~3/451762368/talking-mocks-at-trinug-what-a-great-time-what-a-great-group.aspx"&gt;here&lt;/a&gt;) I was giving a wrap up of&amp;nbsp;the Mocking session I recently did at &lt;a href="http://www.trinug.org"&gt;TriNug&lt;/a&gt;.&amp;nbsp; In that post I gave some of the reasons (sorry, I meant excuses) people gave for not doing any type of automated testing during their dally development ritual (notice I am staying away from TDD at this point).&amp;nbsp; I thought that those topics would be better suited to be broken out into their own post.&lt;/p&gt; &lt;p&gt;At the users group I asked the question to the group &amp;#39;who creates automated tests as part of their daily development cycle?&amp;#39;.&amp;nbsp; After I asked this question I followed it up with, and if you don&amp;#39;t WHY, WHY, WHY, WHY......&amp;nbsp; Below are some of the answers I received (btw, not the first time I have heard these reasons).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reason #1 - It is too hard to get started:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Point:&lt;/strong&gt; This statement is nothing new, I hear this all the time.&amp;nbsp; To be honest I agree with them, testing is hard.&amp;nbsp; It takes time and effort to learn how to do it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Counter Point: &lt;/strong&gt;But if you think learning to write tests and learning how to create testable code is hard, then what do you do when you need to learn a new product?&amp;nbsp; I can break it down like this.&amp;nbsp; Testing == Coding and Coding == REAL FREAKING HARD.&amp;nbsp; Stop using &amp;#39;testing is hard&amp;#39; as a crutch and just give it a shot.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reason #2&amp;nbsp;- My client/company is not paying me to write tests:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Point: &lt;/strong&gt;This one always make me laugh.&amp;nbsp; Since testing does take time (not going to sugar coat this at all), and can slow down your pace of development, many people feel that they are not being paid to create tests.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Counter Point:&amp;nbsp; &lt;/strong&gt;This one is real simple, ask your self these two questions.&amp;nbsp; &lt;/p&gt; &lt;ol&gt; &lt;li&gt;Am I being paid to produce quality or crap?&amp;nbsp; &lt;/li&gt; &lt;li&gt;Am I being paid to debug?&amp;nbsp; &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I am going to assume that both of those answers are NO, and if they are not then I would suggest you stop reading this post as it does not get any better from here.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Now that we are on the same page and we understand you are being paid to produce quality code why would you not want to do everything you can to bake that&amp;nbsp;quality into your code up front?&amp;nbsp; This can happen with tests.&amp;nbsp; Take the time, take the challenge and create some tests.&amp;nbsp; Trust me, no one ever got fired for being a bit late with an application that was freaking solid from a quality standpoint (and if you do get fired because of it just look at it this way, you have a new&amp;nbsp;and marketable skill to help you find your new job).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reason #3 - I do not have time&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Point: &lt;/strong&gt;Testing takes time, and when time is short people throw every &amp;#39;non-critical&amp;#39; functions out the window.&amp;nbsp; And sadly people think that quality is a non-critical function.&amp;nbsp; To prove this point just take a look at 90% of the applications out there... they suck ASS&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Counter Point:&amp;nbsp; &lt;/strong&gt;Just ask yourself this question.&amp;nbsp; Would I rather spend what little time I have creating tests to help ensure I have quality or would I rather spend time later stepping through code via the debugger looking for the bug I could have caught/fixed earlier?&amp;nbsp; If you would rather spend time in the debugger, then more power to you.&lt;br /&gt;&lt;br /&gt;NOTE: Do NOT take the above statement as me saying that testers NEVER debug, they do but just a TON less than others.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reason #4 - My code will not allow me to tests&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Point:&lt;/strong&gt;&amp;nbsp; This is one may be the only excuse that has some merit.&amp;nbsp; Poor code is hard to test.&amp;nbsp; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Counter Point:&amp;nbsp; &lt;/strong&gt;Simply because you do not need to retrofit your entire code base at one time.&amp;nbsp; If you have &amp;#39;bad&amp;#39; code that is easy to test that is fine.&amp;nbsp; Start testing with NEW code.&amp;nbsp; Hopefully you will not be creating bad code once you understand your current code is not the best.&amp;nbsp; You will also come to understand that when you start testing your code will start to get a little cleaner.&amp;nbsp; Finally, if you really want to start to test your legacy code, go out and pick up &amp;#39;&lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052"&gt;Working Effectively w/ Legacy Code&lt;/a&gt;&amp;#39; by Michael Feathers&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;As you can tell from my tone, I do not buy into any of these reasons, sorry excuses.&amp;nbsp; I wish that when I ask people this question and they gave me a response they would simply state the truth.&amp;nbsp; And the truth is people do not test for the following 2 reasons&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reason #1 - They do not believe that creating tests will improve their code&lt;br /&gt;&lt;/strong&gt;If this is what you really think, that is fine.&amp;nbsp; You are allowed to have your beliefs and I am allowed to have mine.&amp;nbsp; As long as we understand each other we can get along just fine.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reason #2 - They are lazy&lt;br /&gt;&lt;/strong&gt;Not sure I need to explain this one.&lt;/p&gt; &lt;p&gt;Let the flames begin :)&lt;/p&gt; &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43064" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Opinion/default.aspx">Opinion</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Rant/default.aspx">Rant</category></item></channel></rss>