<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Tim Barcz - Testing</title>
    <link>http://www.timbarcz.com/blog/</link>
    <description>My Code is My Craft</description>
    <image>
      <url>http://www.timbarcz.com/blog/content/binary/channelImage.jpg</url>
      <title>Tim Barcz - Testing</title>
      <link>http://www.timbarcz.com/blog/</link>
    </image>
    <language>en-us</language>
    <copyright>Tim Barcz</copyright>
    <lastBuildDate>Fri, 20 Mar 2009 04:01:26 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>blog@timbarcz.com</managingEditor>
    <webMaster>blog@timbarcz.com</webMaster>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=035917dc-7c8b-40ac-b40b-6b2461707481</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,035917dc-7c8b-40ac-b40b-6b2461707481.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,035917dc-7c8b-40ac-b40b-6b2461707481.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=035917dc-7c8b-40ac-b40b-6b2461707481</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you're serious about testing before long you'll bump into the need to do some mocking.
You can of course chose to write your own mocks but that is hardly time effective
or trivial.  More than likely you'll want to use a framework, but how do you
choose between the most popular options?
</p>
        <p>
There's been some discussion on <a href="http://www.twitter.com">Twitter</a> between <a href="http://www.twitter.com/timbarcz">myself</a> and <a href="http://www.clariusconsulting.net/blogs/kzu/">Daniel
Cazzulino</a><a href="http://www.twitter.com">(@kzu</a>), the creator of <a href="http://code.google.com/p/moq/">Moq</a> (pronounced
"Mock-you" or just "Mock"), a newer and popular .NET mocking,
about mocking frameworks and what goes into choosing a mocking framework.  Daniel
and I share a passion in mocking and by extension testing.  As the creator of
Moq, I hold him in very high regard.
</p>
        <p>
The discussion centered around some work that <a href="http://codevanced.net/">Andrew
Kazyrevich</a> has been doing recently.  Andrew is <a href="http://www.google.com/search?q=define%3Aardour">passionate</a> about
mocking.  As such he's created an <a href="http://code.google.com/p/mocking-frameworks-compare">open
source project</a> which compares the "big dawgs" of .NET mocking frameworks. 
In his <a href="http://codevanced.net/post/Mocking-Frameworks-Compare.aspx">introductory
post</a> he explains the intent, which is message I support and want to help spread:
</p>
        <blockquote>
          <p>
I've started a small open source project. It provides a unified set of tests written
against Moq, NMock2, Rhino Mocks and Typemock Isolator, so that you can easily compare
the frameworks and make an informed decision when picking one up. 
</p>
        </blockquote>
        <p>
In Andrew's <a href="http://codevanced.net/post/To-kill-a-mockingbird.aspx">most recent
post</a> he compares the execution time of the various frameworks.  My response
on the <a href="http://groups.google.com/group/RhinoMocks/browse_thread/thread/2f3bfbe688d95ae0">RhinoMocks
mailing list</a> was terse but sincere:
</p>
        <blockquote>
          <p>
Curious about speed in your tests, is the a first level concern when choosing a testing
framework?
</p>
        </blockquote>
        <p>
Daniel answered the question in a <a href="http://twitter.com/kzu/status/1354114894">tweet</a>:
</p>
        <blockquote>
          <p>
IMO, API design, usability and expressiveness is a much more valuable comparison.
#moq is not optimized for runtime perf.
</p>
        </blockquote>
        <p>
To which <a href="http://twitter.com/TimBarcz/statuses/1354369248">I responded</a>:
</p>
        <blockquote>
          <p>
I would also throw in documentation, discoverability, and community into your equation.
</p>
        </blockquote>
        <p>
So, fine blog reader, I have a question for you.  If you are using a mocking
framework, what are your first-level concerns when you chose your framework? 
For those who have yet to utilize a framework, what will you base your decision on
when you do choose?
</p>
        <ul>
          <li>
Execution Speed</li>
          <li>
API Design</li>
          <li>
Usability</li>
          <li>
Expressiveness</li>
          <li>
Documentation</li>
          <li>
Discoverability (possibly coincides with API Design)</li>
          <li>
Community</li>
          <li>
Other?</li>
        </ul>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=035917dc-7c8b-40ac-b40b-6b2461707481" />
      </body>
      <title>Choosing A Mocking Framework</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,035917dc-7c8b-40ac-b40b-6b2461707481.aspx</guid>
      <link>http://www.timbarcz.com/blog/ChoosingAMockingFramework.aspx</link>
      <pubDate>Fri, 20 Mar 2009 04:01:26 GMT</pubDate>
      <description>&lt;p&gt;
If you're serious about testing before long you'll bump into the need to do some mocking.
You can of course chose to write your own mocks but that is hardly time effective
or trivial.&amp;#160; More than likely you'll want to use a framework, but how do you
choose between the most popular options?
&lt;/p&gt;
&lt;p&gt;
There's been some discussion on &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; between &lt;a href="http://www.twitter.com/timbarcz"&gt;myself&lt;/a&gt; and &lt;a href="http://www.clariusconsulting.net/blogs/kzu/"&gt;Daniel
Cazzulino&lt;/a&gt; &lt;a href="http://www.twitter.com"&gt;(@kzu&lt;/a&gt;), the creator of &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; (pronounced
&amp;quot;Mock-you&amp;quot; or just &amp;quot;Mock&amp;quot;), a newer and popular .NET mocking,
about mocking frameworks and what goes into choosing a mocking framework.&amp;#160; Daniel
and I share a passion in mocking and by extension testing.&amp;#160; As the creator of
Moq, I hold him in very high regard.
&lt;/p&gt;
&lt;p&gt;
The discussion centered around some work that &lt;a href="http://codevanced.net/"&gt;Andrew
Kazyrevich&lt;/a&gt; has been doing recently.&amp;#160; Andrew is &lt;a href="http://www.google.com/search?q=define%3Aardour"&gt;passionate&lt;/a&gt; about
mocking.&amp;#160; As such he's created an &lt;a href="http://code.google.com/p/mocking-frameworks-compare"&gt;open
source project&lt;/a&gt; which compares the &amp;quot;big dawgs&amp;quot; of .NET mocking frameworks.&amp;#160;
In his &lt;a href="http://codevanced.net/post/Mocking-Frameworks-Compare.aspx"&gt;introductory
post&lt;/a&gt; he explains the intent, which is message I support and want to help spread:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
I've started a small open source project. It provides a unified set of tests written
against Moq, NMock2, Rhino Mocks and Typemock Isolator, so that you can easily compare
the frameworks and make an informed decision when picking one up. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
In Andrew's &lt;a href="http://codevanced.net/post/To-kill-a-mockingbird.aspx"&gt;most recent
post&lt;/a&gt; he compares the execution time of the various frameworks.&amp;#160; My response
on the &lt;a href="http://groups.google.com/group/RhinoMocks/browse_thread/thread/2f3bfbe688d95ae0"&gt;RhinoMocks
mailing list&lt;/a&gt; was terse but sincere:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Curious about speed in your tests, is the a first level concern when choosing a testing
framework?
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Daniel answered the question in a &lt;a href="http://twitter.com/kzu/status/1354114894"&gt;tweet&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
IMO, API design, usability and expressiveness is a much more valuable comparison.
#moq is not optimized for runtime perf.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
To which &lt;a href="http://twitter.com/TimBarcz/statuses/1354369248"&gt;I responded&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
I would also throw in documentation, discoverability, and community into your equation.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
So, fine blog reader, I have a question for you.&amp;#160; If you are using a mocking
framework, what are your first-level concerns when you chose your framework?&amp;#160;
For those who have yet to utilize a framework, what will you base your decision on
when you do choose?
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Execution Speed&lt;/li&gt;
&lt;li&gt;
API Design&lt;/li&gt;
&lt;li&gt;
Usability&lt;/li&gt;
&lt;li&gt;
Expressiveness&lt;/li&gt;
&lt;li&gt;
Documentation&lt;/li&gt;
&lt;li&gt;
Discoverability (possibly coincides with API Design)&lt;/li&gt;
&lt;li&gt;
Community&lt;/li&gt;
&lt;li&gt;
Other?&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=035917dc-7c8b-40ac-b40b-6b2461707481" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,035917dc-7c8b-40ac-b40b-6b2461707481.aspx</comments>
      <category>Open Source Software</category>
      <category>Rhino Mocks</category>
      <category>Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=ace5ff49-6ad9-43af-b5c5-106daddd9bed</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,ace5ff49-6ad9-43af-b5c5-106daddd9bed.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,ace5ff49-6ad9-43af-b5c5-106daddd9bed.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ace5ff49-6ad9-43af-b5c5-106daddd9bed</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.biblegateway.com/passage/?search=I%20Thessalonians%205:21">1 Thessalonians
5:21</a>
        </p>
        <ul>
          <li>
"Test everything. Hold on to the good." (NIV) 
</li>
          <li>
"Prove all things; hold fast that which is good." (King James Version) 
</li>
        </ul>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=ace5ff49-6ad9-43af-b5c5-106daddd9bed" />
      </body>
      <title>Testing - Mandated By God!</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,ace5ff49-6ad9-43af-b5c5-106daddd9bed.aspx</guid>
      <link>http://www.timbarcz.com/blog/TestingMandatedByGod.aspx</link>
      <pubDate>Tue, 10 Feb 2009 14:22:33 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.biblegateway.com/passage/?search=I%20Thessalonians%205:21"&gt;1 Thessalonians
5:21&lt;/a&gt; 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&amp;quot;Test everything. Hold on to the good.&amp;quot; (NIV) 
&lt;/li&gt;
&lt;li&gt;
&amp;quot;Prove all things; hold fast that which is good.&amp;quot; (King James Version) 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=ace5ff49-6ad9-43af-b5c5-106daddd9bed" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,ace5ff49-6ad9-43af-b5c5-106daddd9bed.aspx</comments>
      <category>Humor</category>
      <category>Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=8a12ded7-7dd8-491b-9dbb-559cc3c516fa</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,8a12ded7-7dd8-491b-9dbb-559cc3c516fa.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,8a12ded7-7dd8-491b-9dbb-559cc3c516fa.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8a12ded7-7dd8-491b-9dbb-559cc3c516fa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Shhh...don't tell anyone but we don't unit test all of our code.  We're striving
to get all developers and managers on board with unit testing but we're not there
yet.  Despite our delinquency in writing tests one thing we do try our very best
to do is keep mistakes from happening again.  If we find a bug in the system,
before fixing it, we go and write a unit test for that problem.  We verify the
test fails, the go and write the code that fixes it.  This recognizes that bugs
will appear in the system, but once fixed we'll insulate ourselves from that bug happening
again.
</p>
        <p>
We had one such case last week.  We were getting a yellow-screen error after
a bunch of commits by developers.  The error stemmed from a component in Windsor
that did not have all of it's dependencies met.  In other words, we registered
a component which relied on another component which was not registered.  We already
had written a test to compile and test our Windsor configuration, however that test
was not mature enough and needed some tweaking.  
</p>
        <p>
In our application we leverage the new ASP.Net MVC.  We also take advantage of
the ability to leverage an IoC container, Windsor, to create controller instances
when a web request comes in.  When the application starts, we register all of
the controllers in the application into Windsor using reflection.  Therefore
our Windsor configuration at runtime is made up of two things, the XML configuration
and the controllers which are registered on startup.  The "bug" here
was that one of our controllers had a dependency on it that was not registered in
Windsor.  When you ran the test by itself, the test would pass, since it was
only loading up the components from the Windsor configuration.
</p>
        <p>
Wanting to protect us in the future, we acknowledged there was something missing from
our test and set out to find it.  To create the failing test was relatively simple. 
All that we needed to do replicate in our test what we were doing at runtime. 
Therefore we needed to register all implementers of IController, just like we do on
application startup.  Below I've 
</p>
        <p>
Before:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span> IWindsorContainer
container = <span style="color: #0000ff">new</span> WindsorContainer(<span style="color: #006080">"windsor.config.xml"</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span>
              <span style="color: #0000ff">foreach</span> (var
handler <span style="color: #0000ff">in</span> container.Kernel.GetAssignableHandlers(<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">object</span>)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 5:</span> Console.WriteLine(<span style="color: #006080">"{0}\n\t-
{1}"</span>, handler.ComponentModel.Service, handler.ComponentModel.Implementation);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span> container.Resolve(handler.ComponentModel.Service);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 7:</span> }</pre>
          </div>
        </div>
        <p>
After:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span> IWindsorContainer
container = <span style="color: #0000ff">new</span> WindsorContainer(<span style="color: #006080">"windsor.config.xml"</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span> var
assm = <span style="color: #0000ff">new</span> HomeController(<span style="color: #0000ff">null</span>).GetType().Assembly;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span>
              <span style="color: #008000">//add
all controllers</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 5:</span>
              <span style="color: #0000ff">foreach</span> (Type
type <span style="color: #0000ff">in</span> assm.GetTypes())</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 7:</span>
              <span style="color: #0000ff">if</span> (<span style="color: #0000ff">typeof</span>(IController).IsAssignableFrom(type)
&amp;&amp; !type.IsAbstract)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 8:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 9:</span> container.AddComponent(type.Name.ToLower(),
type);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 10:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 11:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 12:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 13:</span>
              <span style="color: #0000ff">foreach</span> (var
handler <span style="color: #0000ff">in</span> container.Kernel.GetAssignableHandlers(<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">object</span>)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 14:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 15:</span> Console.WriteLine(<span style="color: #006080">"{0}\n\t-
{1}"</span>, handler.ComponentModel.Service, handler.ComponentModel.Implementation);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 16:</span> container.Resolve(handler.ComponentModel.Service);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 17:</span> }</pre>
          </div>
        </div>
        <p>
Now that this test is in place, I am much more confident that we won't see the error
we were seeing in product again, we've got a test which warns us if something isn't
quite right.  Our initial test didn't quite get it all right.  <strong>Mistakes/bugs
in code will happen, hopefully few and far between, but when a bug does show up, go
write a test that verifies the bug before going off an fixing it.  Then make
the test pass, which should fix the bug.</strong></p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=8a12ded7-7dd8-491b-9dbb-559cc3c516fa" />
      </body>
      <title>Windsor Components, the ASP.NET MVC Framework, and Bug Verification Tests</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,8a12ded7-7dd8-491b-9dbb-559cc3c516fa.aspx</guid>
      <link>http://www.timbarcz.com/blog/WindsorComponentsTheASPNETMVCFrameworkAndBugVerificationTests.aspx</link>
      <pubDate>Fri, 14 Nov 2008 16:44:22 GMT</pubDate>
      <description>&lt;p&gt;
Shhh...don't tell anyone but we don't unit test all of our code.&amp;#160; We're striving
to get all developers and managers on board with unit testing but we're not there
yet.&amp;#160; Despite our delinquency in writing tests one thing we do try our very best
to do is keep mistakes from happening again.&amp;#160; If we find a bug in the system,
before fixing it, we go and write a unit test for that problem.&amp;#160; We verify the
test fails, the go and write the code that fixes it.&amp;#160; This recognizes that bugs
will appear in the system, but once fixed we'll insulate ourselves from that bug happening
again.
&lt;/p&gt;
&lt;p&gt;
We had one such case last week.&amp;#160; We were getting a yellow-screen error after
a bunch of commits by developers.&amp;#160; The error stemmed from a component in Windsor
that did not have all of it's dependencies met.&amp;#160; In other words, we registered
a component which relied on another component which was not registered.&amp;#160; We already
had written a test to compile and test our Windsor configuration, however that test
was not mature enough and needed some tweaking.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
In our application we leverage the new ASP.Net MVC.&amp;#160; We also take advantage of
the ability to leverage an IoC container, Windsor, to create controller instances
when a web request comes in.&amp;#160; When the application starts, we register all of
the controllers in the application into Windsor using reflection.&amp;#160; Therefore
our Windsor configuration at runtime is made up of two things, the XML configuration
and the controllers which are registered on startup.&amp;#160; The &amp;quot;bug&amp;quot; here
was that one of our controllers had a dependency on it that was not registered in
Windsor.&amp;#160; When you ran the test by itself, the test would pass, since it was
only loading up the components from the Windsor configuration.
&lt;/p&gt;
&lt;p&gt;
Wanting to protect us in the future, we acknowledged there was something missing from
our test and set out to find it.&amp;#160; To create the failing test was relatively simple.&amp;#160;
All that we needed to do replicate in our test what we were doing at runtime.&amp;#160;
Therefore we needed to register all implementers of IController, just like we do on
application startup.&amp;#160; Below I've 
&lt;/p&gt;
&lt;p&gt;
Before:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; IWindsorContainer
container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WindsorContainer(&lt;span style="color: #006080"&gt;&amp;quot;windsor.config.xml&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var
handler &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; container.Kernel.GetAssignableHandlers(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;)))&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;{0}\n\t-
{1}&amp;quot;&lt;/span&gt;, handler.ComponentModel.Service, handler.ComponentModel.Implementation);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; container.Resolve(handler.ComponentModel.Service);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
After:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; IWindsorContainer
container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WindsorContainer(&lt;span style="color: #006080"&gt;&amp;quot;windsor.config.xml&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; var
assm = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HomeController(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;).GetType().Assembly;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; &lt;span style="color: #008000"&gt;//add
all controllers&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (Type
type &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; assm.GetTypes())&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IController).IsAssignableFrom(type)
&amp;amp;&amp;amp; !type.IsAbstract)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; container.AddComponent(type.Name.ToLower(),
type);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var
handler &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; container.Kernel.GetAssignableHandlers(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;)))&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;{0}\n\t-
{1}&amp;quot;&lt;/span&gt;, handler.ComponentModel.Service, handler.ComponentModel.Implementation);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; container.Resolve(handler.ComponentModel.Service);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Now that this test is in place, I am much more confident that we won't see the error
we were seeing in product again, we've got a test which warns us if something isn't
quite right.&amp;#160; Our initial test didn't quite get it all right.&amp;#160; &lt;strong&gt;Mistakes/bugs
in code will happen, hopefully few and far between, but when a bug does show up, go
write a test that verifies the bug before going off an fixing it.&amp;#160; Then make
the test pass, which should fix the bug.&lt;/strong&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=8a12ded7-7dd8-491b-9dbb-559cc3c516fa" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,8a12ded7-7dd8-491b-9dbb-559cc3c516fa.aspx</comments>
      <category>ASP.NET MVC Framework</category>
      <category>Caslte</category>
      <category>Testing</category>
      <category>Windsor</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=e67100d4-0863-496d-aca2-e097a5f847c2</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,e67100d4-0863-496d-aca2-e097a5f847c2.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,e67100d4-0863-496d-aca2-e097a5f847c2.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e67100d4-0863-496d-aca2-e097a5f847c2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/3afe3ed16348_1232C/image_2.png">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="330" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/3afe3ed16348_1232C/image_thumb.png" width="433" align="right" border="0" />
          </a> This
past weekend I attended the <a href="http://www.kaizenconf.com">Continuous Improvement
in Software Development Conference</a> in Austin, Texas.  This conference brought
together many brilliant minds in the .NET community for the expressed purpose of continuous
improvement.  The conference was very good, but some of the best chances for
learning happened outside the conference sessions at dinner or sitting around a table
at the hotel bar.  One such discussion seemed to point out one problem we have
in our community, minutiae.
</p>
        <p>
I will preface the remainder of this post by saying I tend to be a purist at times
and must always remind myself what the ultimate goal is.  Acknowledging my tunnel
vision, sometimes purists, can miss the point if we're not careful.  One evening
a few of us got on the discussion of test-driven development.  Someone at the
table used the phrase test-first development in the conversation.  That person
was quickly halted by others at the table because the terms, in their opinion are
quite different and should not be used interchangeably.  If I were to ask you
define both, could you adequately define the difference?  Should you be able
to?  Does it really matter?
</p>
        <p>
I would say that for the development community out there that the differences, if
in fact they do exist, don't matter.  A quick and informal poll revealed that
8 of 10 developers I know aren't unit testing at all.  I readily admit that my
sampling is probably an inaccurate representation of the total developer population. 
I don't think though that my sample poll is off by an enormous amount.  Think
of the developers you know; are they testing at all?  I'm not talking TDD, but
plain old unit tests?  Chances are good that you know a few that aren't testing
at all.  Are they served by the bantering back and forth about differences between
TDD and TFD?  Absolutely not.
</p>
        <p>
The important thing to remember is that fundamentally the TDD and the TFD practitioner
believe the same thing, that is, you need to be testing your code. They may disagree
about small things, but those small things should take a back seat to the fundamentals. 
We don't have to look far to see another example of this type of behavior.  Think
of two Christian denominations, both of which are trying to convert nonbelievers to
Christianity, bickering among themselves about whether children should be baptized
or not.  The debate becomes so ardent, that neither camp accomplishes their original
goal or converting nonbelievers because they're too focused on each other.  I
fear the same outcome will befall those of us preaching testing.  We get so religious
about the non-essential aspects of testing that we miss the people we intended to
target, the people who aren't testing their code at all.
</p>
        <p>
I think we could all take a page from St. Augustine who had it right over 1600 years
ago: "In essentials, unity; in non-essentials, liberty; in all things, charity."
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=e67100d4-0863-496d-aca2-e097a5f847c2" />
      </body>
      <title>Test First or Test Driven, Who Cares?</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,e67100d4-0863-496d-aca2-e097a5f847c2.aspx</guid>
      <link>http://www.timbarcz.com/blog/TestFirstOrTestDrivenWhoCares.aspx</link>
      <pubDate>Tue, 04 Nov 2008 04:41:06 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/3afe3ed16348_1232C/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="330" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/3afe3ed16348_1232C/image_thumb.png" width="433" align="right" border="0" /&gt;&lt;/a&gt; This
past weekend I attended the &lt;a href="http://www.kaizenconf.com"&gt;Continuous Improvement
in Software Development Conference&lt;/a&gt; in Austin, Texas.&amp;#160; This conference brought
together many brilliant minds in the .NET community for the expressed purpose of continuous
improvement.&amp;#160; The conference was very good, but some of the best chances for
learning happened outside the conference sessions at dinner or sitting around a table
at the hotel bar.&amp;#160; One such discussion seemed to point out one problem we have
in our community, minutiae.
&lt;/p&gt;
&lt;p&gt;
I will preface the remainder of this post by saying I tend to be a purist at times
and must always remind myself what the ultimate goal is.&amp;#160; Acknowledging my tunnel
vision, sometimes purists, can miss the point if we're not careful.&amp;#160; One evening
a few of us got on the discussion of test-driven development.&amp;#160; Someone at the
table used the phrase test-first development in the conversation.&amp;#160; That person
was quickly halted by others at the table because the terms, in their opinion are
quite different and should not be used interchangeably.&amp;#160; If I were to ask you
define both, could you adequately define the difference?&amp;#160; Should you be able
to?&amp;#160; Does it really matter?
&lt;/p&gt;
&lt;p&gt;
I would say that for the development community out there that the differences, if
in fact they do exist, don't matter.&amp;#160; A quick and informal poll revealed that
8 of 10 developers I know aren't unit testing at all.&amp;#160; I readily admit that my
sampling is probably an inaccurate representation of the total developer population.&amp;#160;
I don't think though that my sample poll is off by an enormous amount.&amp;#160; Think
of the developers you know; are they testing at all?&amp;#160; I'm not talking TDD, but
plain old unit tests?&amp;#160; Chances are good that you know a few that aren't testing
at all.&amp;#160; Are they served by the bantering back and forth about differences between
TDD and TFD?&amp;#160; Absolutely not.
&lt;/p&gt;
&lt;p&gt;
The important thing to remember is that fundamentally the TDD and the TFD practitioner
believe the same thing, that is, you need to be testing your code. They may disagree
about small things, but those small things should take a back seat to the fundamentals.&amp;#160;
We don't have to look far to see another example of this type of behavior.&amp;#160; Think
of two Christian denominations, both of which are trying to convert nonbelievers to
Christianity, bickering among themselves about whether children should be baptized
or not.&amp;#160; The debate becomes so ardent, that neither camp accomplishes their original
goal or converting nonbelievers because they're too focused on each other.&amp;#160; I
fear the same outcome will befall those of us preaching testing.&amp;#160; We get so religious
about the non-essential aspects of testing that we miss the people we intended to
target, the people who aren't testing their code at all.
&lt;/p&gt;
&lt;p&gt;
I think we could all take a page from St. Augustine who had it right over 1600 years
ago: &amp;quot;In essentials, unity; in non-essentials, liberty; in all things, charity.&amp;quot;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=e67100d4-0863-496d-aca2-e097a5f847c2" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,e67100d4-0863-496d-aca2-e097a5f847c2.aspx</comments>
      <category>Rant</category>
      <category>Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IowaCodeCampNovember8_1421C/image_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="122" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IowaCodeCampNovember8_1421C/image_thumb.png" width="437" align="right" border="0" />
          </a>
        </p>
        <p>
I want to invite any of you who are within a few hours of <a href="http://maps.google.com/maps?q=Des+Moines,+Iowa&amp;ie=UTF8&amp;oe=utf-8&amp;client=firefox-a&amp;t=h&amp;z=12&amp;iwloc=addr">Des
Moines, Iowa</a> to attend the second <a href="http://www.iowacodecamp.com">Iowa Code
Camp</a> on November 8th.  The first Iowa Code Camp back in May was a huge success.
From <a href="http://devlicio.us/blogs/derik_whittaker/archive/2008/05/04/iowa-code-camp-in-the-rear-view-mirror.aspx">Derik's
write-up</a>:
</p>
        <blockquote>
          <p>
Yesterdays event was awesome.  They had about 125-150 people show up for the
first ever Code Camp in Iowa.  The venue could not have been any nicer and setup
any better.
</p>
        </blockquote>
        <p>
I will be giving one presentation on using RhinoMocks and one workshop on TDD. 
Below are the abstracts.  If you have the chance, take part, and <a href="http://iowacodecamp.com/">register
today</a>.
</p>
        <p>
          <b>TDD: A Workshop in Driving Your Design with Tests</b>
        </p>
        <p>
If you've heard about Test Driven Development (TDD) and wondered what it was or how
to do it, then this workshop is for you.  We'll take a practical, introductory
approach to getting started with TDD.  We'll introduce fundamental object-oriented
design principles including separation of concerns, dependency injection/inversion,
and more.  This will be a hands on lab, so bring your laptops and a copy of Visual
Studio 2008 and expect to learn. 
</p>
        <p>
          <b>Easing your Testing With RhinoMocks 
<br /></b>
        </p>
        <p>
When learning about testing you'll see trivial examples illustrating how to write
tests. However most production code is non-trivial, making calls to configuration
files or to a database which makes testing in isolation hard.  The use of mock
objects allows you to isolate code you want to test by providing fake objects to your
methods, allowing you to set up complex scenarios to test specific conditions. 
In this session we'll first dig into some code that is not very testable and refactor
it to make it more testable.  After the refactoring we'll use and explore RhinoMocks
to see how we can test different scenarios in our code and verify our code is working
as it should.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc" />
      </body>
      <title>Iowa Code Camp - November 8</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc.aspx</guid>
      <link>http://www.timbarcz.com/blog/IowaCodeCampNovember8.aspx</link>
      <pubDate>Wed, 08 Oct 2008 03:56:31 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IowaCodeCampNovember8_1421C/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="122" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IowaCodeCampNovember8_1421C/image_thumb.png" width="437" align="right" border="0" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
I want to invite any of you who are within a few hours of &lt;a href="http://maps.google.com/maps?q=Des+Moines,+Iowa&amp;amp;ie=UTF8&amp;amp;oe=utf-8&amp;amp;client=firefox-a&amp;amp;t=h&amp;amp;z=12&amp;amp;iwloc=addr"&gt;Des
Moines, Iowa&lt;/a&gt; to attend the second &lt;a href="http://www.iowacodecamp.com"&gt;Iowa Code
Camp&lt;/a&gt; on November 8th.&amp;#160; The first Iowa Code Camp back in May was a huge success.
From &lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2008/05/04/iowa-code-camp-in-the-rear-view-mirror.aspx"&gt;Derik's
write-up&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Yesterdays event was awesome.&amp;#160; They had about 125-150 people show up for the
first ever Code Camp in Iowa.&amp;#160; The venue could not have been any nicer and setup
any better.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I will be giving one presentation on using RhinoMocks and one workshop on TDD.&amp;#160;
Below are the abstracts.&amp;#160; If you have the chance, take part, and &lt;a href="http://iowacodecamp.com/"&gt;register
today&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;TDD: A Workshop in Driving Your Design with Tests&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
If you've heard about Test Driven Development (TDD) and wondered what it was or how
to do it, then this workshop is for you.&amp;#160; We'll take a practical, introductory
approach to getting started with TDD.&amp;#160; We'll introduce fundamental object-oriented
design principles including separation of concerns, dependency injection/inversion,
and more.&amp;#160; This will be a hands on lab, so bring your laptops and a copy of Visual
Studio 2008 and expect to learn. 
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Easing your Testing With RhinoMocks 
&lt;br /&gt;
&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
When learning about testing you'll see trivial examples illustrating how to write
tests. However most production code is non-trivial, making calls to configuration
files or to a database which makes testing in isolation hard.&amp;#160; The use of mock
objects allows you to isolate code you want to test by providing fake objects to your
methods, allowing you to set up complex scenarios to test specific conditions.&amp;#160;
In this session we'll first dig into some code that is not very testable and refactor
it to make it more testable.&amp;#160; After the refactoring we'll use and explore RhinoMocks
to see how we can test different scenarios in our code and verify our code is working
as it should.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,fcfbaf3e-b3c8-4c9d-bb7a-19721b7153fc.aspx</comments>
      <category>Announcement</category>
      <category>Community</category>
      <category>CRIneta</category>
      <category>Rhino Mocks</category>
      <category>Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=f97b11c0-b2d4-49e3-bac1-c584512d372a</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,f97b11c0-b2d4-49e3-bac1-c584512d372a.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,f97b11c0-b2d4-49e3-bac1-c584512d372a.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f97b11c0-b2d4-49e3-bac1-c584512d372a</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Often times I get the sense that others think I'm a nut for testing.  There are
plenty of others out there who are far more dogmatic about testing than I am. 
In fact right now I'd be ashamed to share with you the test coverage of our current
project.  I will say that the old codebase from which we are migrating had 0%
coverage and I'm proud to say, confidently, that we're beating that number handily.
</p>
        <p>
Testing, at it's very core, for me, is about ensuring correctness.  Whether you're
testing using an automated testing framework such as <a href="http://www.nunit.org">NUnit</a>, <a href="http://www.mbunit.com">MbUnit</a>,
or <a href="http://www.codeplex.com/xunit">xUnit</a> or you test by hitting F5 and
running your project, you're seeking correctness.  For the moment forget words
such as "Unit Test", "Integration Test", or "System Test". 
Those terms only indicate different scopes on which you can test for correctness. 
Often they confuse more than they clarify.  They have their place, just not here
right now.
</p>
        <p>
I came across the following code the other day:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span> public
Address GetBillToAddress()</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span> return
shippingAddress;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span> }</pre>
          </div>
        </div>
        <p>
See the problem?  Yeah, it was an easy one.  This code, as it sat, was not
tested.  The problem with the code above is that it's so simple that it's easy
to think it doesn't need to be tested.  Most users use the same billing address
as their shipping address, thus masking the error for the vast majority of users. 
The danger lies in a simple bug like this masquerading as something more insidious. 
For example, this method is part of the "User" class in an eCommerce application. 
The application verifies the users credit card by sending credit card information
along with billing address to a credit card validation component.  We've already
said that most users would have the same billing address as their shipping address. 
However, imagine when a user comes by who has different shipping and billing addresses
and now the user is being told that their credit card cannot be validated due to the
billing address not matching the address on the file with the card.  I see a
couple of scenarios happening but two that I want to address specifically:
</p>
        <ul>
          <li>
In the worst scenario, the user will just go to a different site, knowing their credit
card is good and assuming our site is wrong.  We lose the sale and are not alerted
to the problem on the site. 
</li>
          <li>
The second, less likely scenario is that the user calls our customer service department
to tell us the problem.  The customer service department verifies the problem
and gets in touch with the manager of the eCommerce department.  The eCommerce
manager verifies the problem as well and gets with one of the developers to find/fix
the problem.  The developer then begins to research the problem and may find
it immediately or may start looking in the wrong place, the credit card authorization
component. 
</li>
        </ul>
        <p>
While I'm being a bit overly dramatic here, it's for good reason.  How hard,even
if you know very little about testing or are new to automated testing, do you think
it is to test the method above?  5 minutes? 10 minutes? An hour?  Compare
any of those estimates for putting an automated test in place versus the money lost
in the first scenario or the time spent in second scenario.
</p>
        <p>
Too often people look at testing for only the non-trivial functions, for example their
custom implementation of the <a href="http://en.wikipedia.org/wiki/Great_circle_distance">Great-circle
distance algorithm</a>.  It's easy to discount testing the simple stuff. 
However, a simple bug like this making it's way to production validates the point <a href="http://www.stevemcconnell.com/">Steve
McConnell</a> makes in <a href="http://www.cc2e.com/">Code Complete</a>; the later
a bug is found the more it costs to fix it.
</p>
        <p>
If you aren't testing your code, start.  Don't worry about whether or not you're
doing it right or not if you're new to testing.  <strong>Any test is better than
none</strong>, despite what many in the business will tell you.  I'd take 10
badly written "unit tests" (that zealots are quick to point out are really
integration tests) rather than one well-written one.  Testing isn't an all or
nothing proposition.  It's about ensuring correctness.  It's about continuous
improvement, being better than you were yesterday.  Testing a bit more than you
were yesterday.  Go on, take that first step, write a test or two.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=f97b11c0-b2d4-49e3-bac1-c584512d372a" />
      </body>
      <title>Testing - It's About Ensuring Correctness</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,f97b11c0-b2d4-49e3-bac1-c584512d372a.aspx</guid>
      <link>http://www.timbarcz.com/blog/TestingItsAboutEnsuringCorrectness.aspx</link>
      <pubDate>Wed, 01 Oct 2008 02:44:08 GMT</pubDate>
      <description>&lt;p&gt;
Often times I get the sense that others think I'm a nut for testing.&amp;#160; There are
plenty of others out there who are far more dogmatic about testing than I am.&amp;#160;
In fact right now I'd be ashamed to share with you the test coverage of our current
project.&amp;#160; I will say that the old codebase from which we are migrating had 0%
coverage and I'm proud to say, confidently, that we're beating that number handily.
&lt;/p&gt;
&lt;p&gt;
Testing, at it's very core, for me, is about ensuring correctness.&amp;#160; Whether you're
testing using an automated testing framework such as &lt;a href="http://www.nunit.org"&gt;NUnit&lt;/a&gt;, &lt;a href="http://www.mbunit.com"&gt;MbUnit&lt;/a&gt;,
or &lt;a href="http://www.codeplex.com/xunit"&gt;xUnit&lt;/a&gt; or you test by hitting F5 and
running your project, you're seeking correctness.&amp;#160; For the moment forget words
such as &amp;quot;Unit Test&amp;quot;, &amp;quot;Integration Test&amp;quot;, or &amp;quot;System Test&amp;quot;.&amp;#160;
Those terms only indicate different scopes on which you can test for correctness.&amp;#160;
Often they confuse more than they clarify.&amp;#160; They have their place, just not here
right now.
&lt;/p&gt;
&lt;p&gt;
I came across the following code the other day:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; public
Address GetBillToAddress()&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; return
shippingAddress;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
See the problem?&amp;#160; Yeah, it was an easy one.&amp;#160; This code, as it sat, was not
tested.&amp;#160; The problem with the code above is that it's so simple that it's easy
to think it doesn't need to be tested.&amp;#160; Most users use the same billing address
as their shipping address, thus masking the error for the vast majority of users.&amp;#160;
The danger lies in a simple bug like this masquerading as something more insidious.&amp;#160;
For example, this method is part of the &amp;quot;User&amp;quot; class in an eCommerce application.&amp;#160;
The application verifies the users credit card by sending credit card information
along with billing address to a credit card validation component.&amp;#160; We've already
said that most users would have the same billing address as their shipping address.&amp;#160;
However, imagine when a user comes by who has different shipping and billing addresses
and now the user is being told that their credit card cannot be validated due to the
billing address not matching the address on the file with the card.&amp;#160; I see a
couple of scenarios happening but two that I want to address specifically:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
In the worst scenario, the user will just go to a different site, knowing their credit
card is good and assuming our site is wrong.&amp;#160; We lose the sale and are not alerted
to the problem on the site. 
&lt;/li&gt;
&lt;li&gt;
The second, less likely scenario is that the user calls our customer service department
to tell us the problem.&amp;#160; The customer service department verifies the problem
and gets in touch with the manager of the eCommerce department.&amp;#160; The eCommerce
manager verifies the problem as well and gets with one of the developers to find/fix
the problem.&amp;#160; The developer then begins to research the problem and may find
it immediately or may start looking in the wrong place, the credit card authorization
component. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
While I'm being a bit overly dramatic here, it's for good reason.&amp;#160; How hard,even
if you know very little about testing or are new to automated testing, do you think
it is to test the method above?&amp;#160; 5 minutes? 10 minutes? An hour?&amp;#160; Compare
any of those estimates for putting an automated test in place versus the money lost
in the first scenario or the time spent in second scenario.
&lt;/p&gt;
&lt;p&gt;
Too often people look at testing for only the non-trivial functions, for example their
custom implementation of the &lt;a href="http://en.wikipedia.org/wiki/Great_circle_distance"&gt;Great-circle
distance algorithm&lt;/a&gt;.&amp;#160; It's easy to discount testing the simple stuff.&amp;#160;
However, a simple bug like this making it's way to production validates the point &lt;a href="http://www.stevemcconnell.com/"&gt;Steve
McConnell&lt;/a&gt; makes in &lt;a href="http://www.cc2e.com/"&gt;Code Complete&lt;/a&gt;; the later
a bug is found the more it costs to fix it.
&lt;/p&gt;
&lt;p&gt;
If you aren't testing your code, start.&amp;#160; Don't worry about whether or not you're
doing it right or not if you're new to testing.&amp;#160; &lt;strong&gt;Any test is better than
none&lt;/strong&gt;, despite what many in the business will tell you.&amp;#160; I'd take 10
badly written &amp;quot;unit tests&amp;quot; (that zealots are quick to point out are really
integration tests) rather than one well-written one.&amp;#160; Testing isn't an all or
nothing proposition.&amp;#160; It's about ensuring correctness.&amp;#160; It's about continuous
improvement, being better than you were yesterday.&amp;#160; Testing a bit more than you
were yesterday.&amp;#160; Go on, take that first step, write a test or two.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=f97b11c0-b2d4-49e3-bac1-c584512d372a" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,f97b11c0-b2d4-49e3-bac1-c584512d372a.aspx</comments>
      <category>Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=be7953f5-7018-4d43-8811-3ff070cb3253</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=be7953f5-7018-4d43-8811-3ff070cb3253</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_4.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_thumb_1.png" width="260" align="right" border="0" />
          </a>In
church last week we were talking about evolution when the term "Irreducible Complexity"
came up.  For those who aren't familiar with the concept <a href="http://en.wikipedia.org/wiki/Irreducible_complexity">irreducible
complexity</a> is a term coined by Michael Behe to illustrate that complex system
could not have evolved and therefore must have been created intelligently.  Behe
defines irreducible complexity as:
</p>
        <blockquote>
          <p>
A single system which is composed of several interacting parts that contribute to
the basic function, and where the removal of any one of the parts causes the system
to effectively cease functioning. (<i><a href="http://en.wikipedia.org/wiki/Darwin%27s_Black_Box">Darwin's
Black Box</a></i> p39 in the 2006 edition)
</p>
        </blockquote>
        <p>
In his book Behe uses a mousetrap to illustrate an irreducible complex system.  
</p>
        <blockquote>
          <p>
"If any one of the components of the mousetrap (the base, hammer, spring, catch,
or holding bar) is removed, then the trap does not function. In other words, the simple
little mousetrap has no ability to trap a mouse until several separate parts are all
assembled. Because the mousetrap is necessarily composed of several parts, it is irreducibly
complex." (Behe, 1996).
</p>
        </blockquote>
        <p>
(This post does not seek to discuss the controversy of evolution vs. creationism vs.
intelligent design)
</p>
        <p>
How does this translate to software?  An irreducibly complex software is software
that cannot be easily tested.  The "removal of any one of the parts causes
the system to effectively cease functioning" really points to dependencies in
software.  Do your tests rely on a database being there?  Do you get emails
whenever some piece of code runs because as part of the method an email is sent?
</p>
        <h2>
        </h2>
        <h2>Creationist Design
</h2>
        <p>
How often have you stepped into some code and have seen a method calling database,
sending an email, doing some validation, and then returning some value.  Here's
an example I pulled from <a href="http://www.lostechies.com/blogs/jimmy_bogard/">Jimmy
Bogard's</a> <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/06/19/separation-of-concerns-by-example-part-1.aspx">post
on separation of concerns</a>:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span> [DataObjectMethod(DataObjectMethodType.Select, <span style="color: #0000ff">false</span>)]</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">static</span> List&lt;Customer&gt;
GetCustomers(<span style="color: #0000ff">int</span> startRowIndex, <span style="color: #0000ff">int</span> maximumRows)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span> List&lt;Customer&gt;
customers = <span style="color: #0000ff">null</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 5:</span>
              <span style="color: #0000ff">string</span> key
= <span style="color: #006080">"Customers_Customers_"</span> + startRowIndex
+ <span style="color: #006080">"_"</span> + maximumRows;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 7:</span>
              <span style="color: #0000ff">if</span> (HttpContext.Current.Cache[key]
!= <span style="color: #0000ff">null</span>)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 8:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 9:</span> customers
= (List&lt;Customer&gt;) HttpContext.Current.Cache[key];</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 10:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 11:</span>
              <span style="color: #0000ff">else</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 12:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 13:</span> customers
=</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 14:</span> (</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 15:</span> from</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 16:</span> c <span style="color: #0000ff">in</span> DataGateway.Context.Customers</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 17:</span> orderby</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 18:</span> c.CustomerID
descending</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 19:</span> select</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 20:</span> c</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 21:</span> ).Skip(startRowIndex).Take(maximumRows).ToList();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 22:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 23:</span>
              <span style="color: #0000ff">if</span> ((customers
!= <span style="color: #0000ff">null</span>) &amp;&amp; (customers.Count &gt; 0))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 24:</span> HttpContext.Current.Cache.Insert(key,
customers, <span style="color: #0000ff">null</span>, DateTime.Now.AddDays(1), TimeSpan.Zero);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 25:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 26:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 27:</span>
              <span style="color: #0000ff">return</span> customers;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 28:</span> }</pre>
          </div>
        </div>
        <p>
The code above will work however it's a bear to test, the code absolutely requires
other items (database, HttpContext, ect) to be there in order to work.  I would
venture to say that the person who wrote it did not build up the code through small
iterations, but rather wrote it all in one fell swoop.
</p>
        <h2>Evolutionary Design
</h2>
        <p>
In software, <strong>reducible complexity</strong> should be a goal.  A reducible
complex system allows for pieces to be substituted for others so you can focus on
one particular area.  Don't have a database in place, no problem, simply put
a placeholder object in for all calls made to the database.  (Yes I'm alluding
to mocking).  You can approach creating a reducibly complex system in two ways:
</p>
        <ul>
          <li>
Create the system as a whole, then reduce it's complexity 
</li>
          <li>
Create the system incrementally 
</li>
        </ul>
        <p>
I prefer the former to the latter as I'm working on my TDD skillz.
</p>
        <h2>Conclusion
</h2>
        <p>
While the analogies used here are not quite perfect, I do feel they illustrate the
point adequately.  As a developer your goal shouldn't be to simply write code. 
You should concern yourself with the lifetime of your application/code base. 
Irreducibly complex systems, while working, can also have short life spans. 
Think about the last time you've ever seen someone fix a broken mousetrap.  All
the parts are too interconnected, the mousetrap is simply replaced.  If you're
not careful your code may be viewed <a href="http://devlicio.us/blogs/tim_barcz/archive/2008/08/11/the-tortoise-and-the-hare.aspx">too
difficult and time consuming to fix, and simply replaced</a>.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=be7953f5-7018-4d43-8811-3ff070cb3253" />
      </body>
      <title>Irreducible Complexity and Evolutionary Design</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</guid>
      <link>http://www.timbarcz.com/blog/IrreducibleComplexityAndEvolutionaryDesign.aspx</link>
      <pubDate>Tue, 02 Sep 2008 14:49:36 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_thumb_1.png" width="260" align="right" border="0" /&gt;&lt;/a&gt;In
church last week we were talking about evolution when the term &amp;quot;Irreducible Complexity&amp;quot;
came up.&amp;#160; For those who aren't familiar with the concept &lt;a href="http://en.wikipedia.org/wiki/Irreducible_complexity"&gt;irreducible
complexity&lt;/a&gt; is a term coined by Michael Behe to illustrate that complex system
could not have evolved and therefore must have been created intelligently.&amp;#160; Behe
defines irreducible complexity as:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
A single system which is composed of several interacting parts that contribute to
the basic function, and where the removal of any one of the parts causes the system
to effectively cease functioning. (&lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Darwin%27s_Black_Box"&gt;Darwin's
Black Box&lt;/a&gt;&lt;/i&gt; p39 in the 2006 edition)
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
In his book Behe uses a mousetrap to illustrate an irreducible complex system.&amp;#160; 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&amp;quot;If any one of the components of the mousetrap (the base, hammer, spring, catch,
or holding bar) is removed, then the trap does not function. In other words, the simple
little mousetrap has no ability to trap a mouse until several separate parts are all
assembled. Because the mousetrap is necessarily composed of several parts, it is irreducibly
complex.&amp;quot; (Behe, 1996).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
(This post does not seek to discuss the controversy of evolution vs. creationism vs.
intelligent design)
&lt;/p&gt;
&lt;p&gt;
How does this translate to software?&amp;#160; An irreducibly complex software is software
that cannot be easily tested.&amp;#160; The &amp;quot;removal of any one of the parts causes
the system to effectively cease functioning&amp;quot; really points to dependencies in
software.&amp;#160; Do your tests rely on a database being there?&amp;#160; Do you get emails
whenever some piece of code runs because as part of the method an email is sent?
&lt;/p&gt;
&lt;h2&gt;
&lt;/h2&gt;
&lt;h2&gt;Creationist Design
&lt;/h2&gt;
&lt;p&gt;
How often have you stepped into some code and have seen a method calling database,
sending an email, doing some validation, and then returning some value.&amp;#160; Here's
an example I pulled from &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/"&gt;Jimmy
Bogard's&lt;/a&gt;&amp;#160;&lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/06/19/separation-of-concerns-by-example-part-1.aspx"&gt;post
on separation of concerns&lt;/a&gt;:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; [DataObjectMethod(DataObjectMethodType.Select, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; List&amp;lt;Customer&amp;gt;
GetCustomers(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; startRowIndex, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; maximumRows)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; List&amp;lt;Customer&amp;gt;
customers = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key
= &lt;span style="color: #006080"&gt;&amp;quot;Customers_Customers_&amp;quot;&lt;/span&gt; + startRowIndex
+ &lt;span style="color: #006080"&gt;&amp;quot;_&amp;quot;&lt;/span&gt; + maximumRows;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (HttpContext.Current.Cache[key]
!= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; customers
= (List&amp;lt;Customer&amp;gt;) HttpContext.Current.Cache[key];&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; customers
=&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; from&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; DataGateway.Context.Customers&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; orderby&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; c.CustomerID
descending&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; select&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; c&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; ).Skip(startRowIndex).Take(maximumRows).ToList();&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((customers
!= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (customers.Count &amp;gt; 0))&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; HttpContext.Current.Cache.Insert(key,
customers, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, DateTime.Now.AddDays(1), TimeSpan.Zero);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; customers;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
The code above will work however it's a bear to test, the code absolutely requires
other items (database, HttpContext, ect) to be there in order to work.&amp;#160; I would
venture to say that the person who wrote it did not build up the code through small
iterations, but rather wrote it all in one fell swoop.
&lt;/p&gt;
&lt;h2&gt;Evolutionary Design
&lt;/h2&gt;
&lt;p&gt;
In software, &lt;strong&gt;reducible complexity&lt;/strong&gt; should be a goal.&amp;#160; A reducible
complex system allows for pieces to be substituted for others so you can focus on
one particular area.&amp;#160; Don't have a database in place, no problem, simply put
a placeholder object in for all calls made to the database.&amp;#160; (Yes I'm alluding
to mocking).&amp;#160; You can approach creating a reducibly complex system in two ways:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Create the system as a whole, then reduce it's complexity 
&lt;/li&gt;
&lt;li&gt;
Create the system incrementally 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I prefer the former to the latter as I'm working on my TDD skillz.
&lt;/p&gt;
&lt;h2&gt;Conclusion
&lt;/h2&gt;
&lt;p&gt;
While the analogies used here are not quite perfect, I do feel they illustrate the
point adequately.&amp;#160; As a developer your goal shouldn't be to simply write code.&amp;#160;
You should concern yourself with the lifetime of your application/code base.&amp;#160;
Irreducibly complex systems, while working, can also have short life spans.&amp;#160;
Think about the last time you've ever seen someone fix a broken mousetrap.&amp;#160; All
the parts are too interconnected, the mousetrap is simply replaced.&amp;#160; If you're
not careful your code may be viewed &lt;a href="http://devlicio.us/blogs/tim_barcz/archive/2008/08/11/the-tortoise-and-the-hare.aspx"&gt;too
difficult and time consuming to fix, and simply replaced&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=be7953f5-7018-4d43-8811-3ff070cb3253" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</comments>
      <category>Agile</category>
      <category>Musings</category>
      <category>Testing</category>
    </item>
  </channel>
</rss>