<?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>Test Driven Developer</title>
    <link>http://testdrivendeveloper.com/</link>
    <description>You got a TEST for that?</description>
    <language>en-us</language>
    <copyright>John E. Boal</copyright>
    <lastBuildDate>Mon, 28 Jun 2010 05:26:54 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8102.813</generator>
    <managingEditor>web_master1@TestDrivenDeveloper.com</managingEditor>
    <webMaster>web_master1@TestDrivenDeveloper.com</webMaster>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=34c7edfd-ba67-4eaa-9557-b58acb44dc5f</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,34c7edfd-ba67-4eaa-9557-b58acb44dc5f.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,34c7edfd-ba67-4eaa-9557-b58acb44dc5f.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=34c7edfd-ba67-4eaa-9557-b58acb44dc5f</wfw:commentRss>
      <title>Balance Between Test-Driven Design and Test Maintenance Overhead</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,34c7edfd-ba67-4eaa-9557-b58acb44dc5f.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2010/06/28/BalanceBetweenTestDrivenDesignAndTestMaintenanceOverhead.aspx</link>
      <pubDate>Mon, 28 Jun 2010 05:26:54 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;Test-driven Development/Design when practiced properly, yields organic design growth as tests cause feature code to be written in response to failing tests. In *proper* practice, the entire code base is refactored as needed to ensure that all code and design smells are eliminated (while keeping tests passing). This essentially causes the design at any given time to integrate all the features written up to that point. Once this process is completed, the feature code should be relatively complete, if the tests were written well to dictate the behavior required by the customer. If Acceptance-Test Driven Development is used, the Acceptance Tests for the feature passing will indicate that it’s ready to ship. At any given point, the code base that is checked in should withstand the scrutiny of an outside code reviewer, and should embody all the best design principles. If it doesn’t, the “refactor” stage has not yet been completed.&lt;/p&gt;  &lt;h4&gt;Refactoring to Remove Code and Design Smells&lt;/h4&gt;  &lt;p&gt;I find many teams that either poorly implement or flat-out skip the step of refactoring the code base and overall code design as part of this cycle. This kind of organic development - sticking a new feature on a code base without integrating it into the design and making changes as required is like sticking a wad of gum on a bowling ball. It tends to be the entire code base lumpy, obtuse, and generally not pretty to look at. Teams can get away with this kind of development for a while more or less successfully (unfortunately). However this behavior causes LARGE problems for the team or those inheriting maintenance and new feature work on this code base. Often the team will have to stop to rewrite the whole code base at some point, because it’s too problematic to maintain the bowling ball and gum code. In practical business situations, it’s far far easier to maintain the overall design and integrate features into the design, course-correcting the design as needed to absorb all of the features into a coherent architecture.&lt;/p&gt;  &lt;p&gt;This concept of going through the code base and refactoring all of it to embody all the features in it, and removing design and code smells does imply that if the design changes, so must the tests that correspond to the design. If the tests are tightly coupled to the code base, some design changes can be painful in terms of test maintenance overhead. There are methodologies that assist in decoupling the test from the code, and have the test just confirm the behavior without much knowledge of how the implementation is done. The use of polymorphism, mock objects to decouple behaviors from implementation, and the principle of dependency injection in general can assist with decoupling, and make test maintenance less painful (although perhaps somewhat tougher to write at the outset). There is overhead still however with design changes, and that should be expected, embraced, and *estimated* in planning…&lt;/p&gt;  &lt;h4&gt;Plan for Change&lt;/h4&gt;  &lt;p&gt;In iteration planning, changes to the design and implementation, along with test maintenance should be factored in to the estimates for work being done. When breaking out tasks for a story, I like to at least mention if not record a specific task for the design refactoring, and another for the test maintenance for design changes. I personally think these should be more or less estimable by most teams with at least rudimentary skills. If the team is new, add a task with a ballpark guess for the time, but be sure to add the tasks so they have visibility… Scoping the effort for the design changes and test maintenance will be easier and easier going forward as the team gains understanding of what impact new features have. And it is likely that for a team with a good solid design, these changes will be minimal if they are done incrementally.&lt;/p&gt;  &lt;p&gt;Some teams prefer to finish the tasks for the features and their tests, and then have a single story for the design and test maintenance per iteration, and keep copying it from one iteration to the next. This works too, however I have seen issues where the iteration tasks don’t get completed, and the maintenance story gets bumped off or not completed in the sprint. This engineering debt is carried forward, and the code that is checked in for “completed” features for the sprint now carries debt with it as well.&lt;/p&gt;  &lt;p&gt;In my experience, I have seen more success with making the elimination of design and code smells part of the “Done” criteria for each story, and in fact pre-check-in criteria. This way we can’t call a story “Done” [meaning completed, and shippable] until it *really* is. Design and test maintenance changes on a per-story level should be small, and usually bite-size enough for a team to be able to handle operating this way even in a short iteration period.&lt;/p&gt;  &lt;p&gt;Don’t omit the design and test maintenance, plan for it specifically each iteration. This practice will help keep engineering debt from accruing from iteration to iteration. It is a key practice that will help keep a team, a project, and a code base (and a business) all on a successful course for the short, and the longer term.&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=34c7edfd-ba67-4eaa-9557-b58acb44dc5f"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,34c7edfd-ba67-4eaa-9557-b58acb44dc5f.aspx</comments>
      <category>Mocks</category>
      <category>Refactoring</category>
      <category>TDD</category>
      <category>Unit Tests</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=51b0779e-f06c-418d-892d-9e1ba2a38300</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,51b0779e-f06c-418d-892d-9e1ba2a38300.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,51b0779e-f06c-418d-892d-9e1ba2a38300.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=51b0779e-f06c-418d-892d-9e1ba2a38300</wfw:commentRss>
      <title>Inversion of Control with Dependency Injection</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,51b0779e-f06c-418d-892d-9e1ba2a38300.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2010/04/13/InversionOfControlWithDependencyInjection.aspx</link>
      <pubDate>Tue, 13 Apr 2010 15:41:03 GMT</pubDate>
      <description>&lt;div&gt;When we are unit testing a piece of code, sometimes there are modules or even systems that we need to rely on outside the scope of the test. It is usually very difficult or expensive to spin up these large pieces just to test one small piece. Even attempting to do this can really slow down the execution of the tests, and that becomes a problem of its own. When possible, we'd like to separate the implementation from the caller's execution so that the control is really in the called module doing the work. This is the "Inversion of Control" or IoC principle, as it's often referred.&lt;br&gt;&lt;br&gt;Dependency Injection is one mechanism where we can design our code in this way.

Dependency injection [DI] is like "injecting" a small bit of test-controlled code into the main-line execution space while the test is running. The test can control the specific execution of the "dependency" code, and cause it to behave in a specific way so as to elicit a specific behavior from the mainline code under test.&lt;br&gt;&lt;br&gt;My favorite mechanism to accomplish DI is to refactor code under test, extracting the logic of the dependency into a class that implements an interface. Then, we can create a test mechanism that implements the interface and behaves in the way that the test can control. We then replace the mainline "real" code with the test version at test time, bypassing the dependency and allowing us to remain focused on the code under test.&lt;br&gt;We can implement this with simple classes, or with Mock objects. The mock object frameworks out there today are quite robust and relatively easy to use, given an interface to implement for the dependency class. Rhino Mocks and Moq are some examples of frameworks that can be used for this type of test.

Here is a simple example of some code under test:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;br&gt;&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;namespace&lt;/span&gt; DIexample&lt;br&gt;{&lt;br&gt;    &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;class&lt;/span&gt; ClassUnderTest&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;internal&lt;/span&gt; &lt;/span&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;IDependOnMe&lt;/span&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt; limit &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;new&lt;/span&gt; Limiter();&lt;br&gt;&lt;br&gt;        &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt; HasDependencyOnExternalClass(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt; value)&lt;br&gt;        {&lt;br&gt;            &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;if&lt;/span&gt; (value &amp;lt; 0)&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;return&lt;/span&gt; limit.LogicFunction(value);&lt;br&gt;            }&lt;br&gt;            &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;else&lt;/span&gt;
            {
                &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;return&lt;/span&gt; value;&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;interface&lt;/span&gt; IDependOnMe&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt; LogicFunction(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt; value);&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;class&lt;/span&gt; Limiter : IDependOnMe&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt; LogicFunction(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt; value)&lt;br&gt;        {&lt;br&gt;            &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;if&lt;/span&gt; (value &amp;lt; -10)&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;return&lt;/span&gt; value;&lt;br&gt;            }&lt;br&gt;            &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;else&lt;/span&gt;
            {
                &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px;"&gt;return&lt;/span&gt; -10;&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br&gt;At test time, we can replace the internal variable "limit" with a test-created instance of an object that implements the "DependOnMe" interface, and behaves in a specific way (like just returning the value perhaps).

The variable "limit" is declared as "internal" scope, because we want the test code to be able to access it and replace its "real" object instance with a test-specific version. I keep the test assembly separate from the mainline code. However, I don't like the idea of making these mechanisms public unless they need to be, so instead in the mainline code, I use the internals visible to assembly attribute like this:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Runtime.CompilerServices;&lt;/pre&gt;&lt;pre&gt;[&lt;font color="#0000ff"&gt;assembly&lt;/font&gt;: InternalsVisibleTo("TestAssembly")]&lt;/pre&gt;&lt;br&gt;This allows all "internal" scoped methods to be accessed by the test assembly, and keeps all the test code out of the mainline code, and maintains at least a level of security that being public doesn't offer.&lt;br&gt;&lt;br&gt;Mock frameworks can be a big help in this type of DI testing. Rhino Mocks is here: &lt;a href="http://ayende.com/projects/rhino-mocks.aspx"&gt;http://ayende.com/projects/rhino-mocks.aspx&lt;/a&gt; it's a good free framework and fully featured. I've not used it but heard good things about MOQ: &lt;a href="http://code.google.com/p/moq/"&gt;http://code.google.com/p/moq/&lt;/a&gt;

&lt;br&gt;&lt;br&gt;Remember to keep the execution isolated from the implementation whenever possible, and it will make unit testing much easier.&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=51b0779e-f06c-418d-892d-9e1ba2a38300"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,51b0779e-f06c-418d-892d-9e1ba2a38300.aspx</comments>
      <category>Mocks</category>
      <category>Unit Tests</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=931c108a-23c9-47be-b11e-f1f99a2aa284</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,931c108a-23c9-47be-b11e-f1f99a2aa284.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,931c108a-23c9-47be-b11e-f1f99a2aa284.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=931c108a-23c9-47be-b11e-f1f99a2aa284</wfw:commentRss>
      <title>C# Developer Tip: the Null-Coalescing Operator</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,931c108a-23c9-47be-b11e-f1f99a2aa284.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2010/03/29/CDeveloperTipTheNullCoalescingOperator.aspx</link>
      <pubDate>Mon, 29 Mar 2010 15:45:31 GMT</pubDate>
      <description>&lt;div&gt;Most everyone is familiar with the C# construct of the conditional operator:&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (binary expr) ? true_result : false_result&lt;br&gt;&lt;br&gt;However I've found that many people often overlook the null-coalescing operator ??. I see a lot of code that examines a string and assigns a value to it if it's null (like a default perhaps):&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;string &lt;/font&gt;s;&lt;br&gt;...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s = (title == &lt;font color="#0000ff"&gt;null&lt;/font&gt;) ? &lt;font color="#a52a2a"&gt;"default"&lt;/font&gt; : title;&lt;br&gt;&lt;br&gt;However, this can be written more simply using the ?? operator:&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s = title ?? &lt;font color="#a52a2a"&gt;"default"&lt;/font&gt;;&lt;br&gt;&lt;br&gt;This construct comes in handy when using nullable types and particularly converting them back into non-nullable types:&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;int&lt;/font&gt;? i = &lt;font color="#0000ff"&gt;null&lt;/font&gt;;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;int &lt;/font&gt;counter = i ?? 0;&lt;br&gt;&lt;br&gt;Enjoy Programming in C#! (and don't forget: You got a test for that??)&lt;br&gt;&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=931c108a-23c9-47be-b11e-f1f99a2aa284"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,931c108a-23c9-47be-b11e-f1f99a2aa284.aspx</comments>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=70de22b0-fc81-4a9a-97b0-b7d93850545a</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,70de22b0-fc81-4a9a-97b0-b7d93850545a.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,70de22b0-fc81-4a9a-97b0-b7d93850545a.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=70de22b0-fc81-4a9a-97b0-b7d93850545a</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>Testable Code</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,70de22b0-fc81-4a9a-97b0-b7d93850545a.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2010/02/15/TestableCode.aspx</link>
      <pubDate>Mon, 15 Feb 2010 16:21:07 GMT</pubDate>
      <description>&lt;div&gt;What is "testable" code? How do I know if my code is "testable" or not? There is a lot of talk in agile teams about making sure we have testable code, so what exactly does that mean? I will try to explain here some of the things that make code testable.&lt;br&gt;&lt;br&gt;TDD Methodology&lt;br&gt;If we are using test-driven development to write the code, it is inherently testable since the tests drove us to write it. However, it is still possible that over time, refactoring can be done in such a way to make it less so. This is not likely however since all the unit tests would be passing.&lt;br&gt;&lt;br&gt;Dependencies&lt;br&gt;If the code requires so many external dependencies that we must essentially spin up large parts of the system to test it, this is a clear red flag for testability. We should be able to mock out dependencies and isolate the code under test. If we can't do that, it's not testable. Our dependency relationships should be reasonable and sensible. If there is a "smell" here it probably means that there's work to do to make it testable.&lt;br&gt;&lt;br&gt;Internal States&lt;br&gt;If there are lots of internals and complex states without interfaces to access and manipulate them, this is another red flag that the code's not testable. If there is a lot of internal logic and things that happen based on state, this should all be unit tested. If there's not a unit test for each thing that goes on internally, it's not testable. Here again if code is written using TDD this usually doesn't become a problem.&lt;br&gt;&lt;br&gt;Setup&lt;br&gt;If the code requires a large amount of setup code to test it, this again is another red flag. I look at the amount of effort it takes to validate that a class does the one thing it's supposed to do. If the test code is more than the main code, it's probably a sign that it's not very testable. Databases are notorious for this issue. I have some database code that's a good example of this concept. The amount of code and data needed to get the database to the state to exercise the few procedures there greatly exceed the code itself. This is kind of combining both the dependencies and internal state concepts, and I think it's definitely not very testable.&lt;br&gt;&lt;br&gt;Testability is a goal we strive for, it helps us to be able to make sure the code operates successfully and is maintainable. Write good unit tests. Look for testability in the small, and that will help the overall system to be more testable as well.&lt;br&gt;&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=70de22b0-fc81-4a9a-97b0-b7d93850545a"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,70de22b0-fc81-4a9a-97b0-b7d93850545a.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=1415a1f9-6814-466d-bfcd-5e8b654ea70c</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,1415a1f9-6814-466d-bfcd-5e8b654ea70c.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,1415a1f9-6814-466d-bfcd-5e8b654ea70c.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=1415a1f9-6814-466d-bfcd-5e8b654ea70c</wfw:commentRss>
      <title>Find a BUG, Write A TEST</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,1415a1f9-6814-466d-bfcd-5e8b654ea70c.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2009/09/23/FindABUGWriteATEST.aspx</link>
      <pubDate>Wed, 23 Sep 2009 03:24:00 GMT</pubDate>
      <description>&lt;div&gt;There are many different kinds of bugs that we encounter in software development:&lt;br&gt;&lt;ul&gt;&lt;li&gt;missing functionality (doesn't do what's required)&lt;/li&gt;&lt;li&gt;unanticipated/undesired behavior (it did what??)&lt;br&gt;&lt;/li&gt;&lt;li&gt;failure to check boundaries (or boundary conditions [e.g null])&lt;/li&gt;&lt;li&gt;user-interface issues (usability)&lt;/li&gt;&lt;li&gt;miscalculations (and logic errors)&lt;/li&gt;&lt;li&gt;control flow errors (failing to break out of a loop, etc.)&lt;br&gt;&lt;/li&gt;&lt;li&gt;failure to handle errors (unhandled exceptions)&lt;br&gt;&lt;/li&gt;&lt;li&gt;security issues (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of privilege)&lt;br&gt;&lt;/li&gt;&lt;li&gt;data interpretation errors (what date is 11/12/13 anyway?)&lt;br&gt;&lt;/li&gt;&lt;li&gt;interoperability errors (sending/receiving incorrect messages or data)&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;and most likely lots of others. Each of these areas has bugs that are all examples of opportunities to write a test that were missed along the development path.&lt;br&gt;&lt;br&gt;Here is a simple real-world example. Today my Log file writing routine threw an unhandled exception when the file it was trying to write to was in use by another application (this is failure to handle errors, above). This caused the app to crash with an unhandled exception. In truth, I had written the code TDD, so it had tests, but none of them held the file open while it attempted to log data.&lt;br&gt;&lt;br&gt;This was an unanticipated condition, but probably one that should have been pretty obvious too. However, I was trying to keep the code as simple as possible, and it's not a multi-threaded app, so there wouldn't have been *internal* collisions anyway. Regardless, the app crashing because its log file is being edited is probably not the desired behavior. So (being the test driven developer) I wrote this test first, to illustrate the bug:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;[&lt;/font&gt;&lt;font color="#7fffd4" face="Courier New"&gt;Test&lt;/font&gt;&lt;font face="Courier New"&gt;]&lt;br&gt;&lt;font color="#0000ff"&gt;public void&lt;/font&gt; TestLogFileInUse()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (&lt;/font&gt;&lt;font color="#7fffd4" face="Courier New"&gt;FileStream &lt;/font&gt;&lt;font face="Courier New"&gt;stream = &lt;/font&gt;&lt;font color="#7fffd4" face="Courier New"&gt;File&lt;/font&gt;&lt;font face="Courier New"&gt;.OpenWrite(&lt;/font&gt;&lt;font color="#7fffd4" face="Courier New"&gt;Utilities&lt;/font&gt;&lt;font face="Courier New"&gt;.LogFileName))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#7fffd4" face="Courier New"&gt;Utilities&lt;/font&gt;&lt;font face="Courier New"&gt;.Log(&lt;font color="#a52a2a"&gt;"test"&lt;/font&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;br&gt;it's really simple, but it definitely did fail when the Log() method threw an exception because his file was being held open by the test. Only after I had a failing test, did I then modify the code to catch the IOException and handle it without crashing the application. I could also check for an event log entry if the file write fails, if that was the desired behavior.&lt;br&gt;&lt;br&gt;The test is fast and simple, and it now guarantees not only that I fixed the bug by making the test pass [not crashing, the only requirement here] but also that the issue will never come back again.&lt;br&gt;&lt;br&gt;This may be an almost trivial case, but it does illustrate how to use TDD when fixing bugs. I shouldn't really ever be adding new functionality to the mainline code without a failing test of some kind. Refactoring doesn't count, because we only refactor when all the tests are passing. Refactoring doesn't add any new functionality, it is just reorganizing the existing code to make it better.&lt;br&gt;&lt;br&gt;The worst thing about fixing bugs is when they pop back up later... We hate regressions, because then we have to re-do re-done work YET AGAIN... Lean says that defects are waste, and if they come back after being fixed, then that makes the time spent on fixing them the second time even more wasteful.&lt;br&gt;&lt;br&gt;This method of "find a bug &amp;gt;&amp;gt; write a test" is a Test-Driven approach to solving issues and making sure they never come back. Let's make regressions an artifact of history, and never fix a bug without having a failing test first!&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=1415a1f9-6814-466d-bfcd-5e8b654ea70c"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,1415a1f9-6814-466d-bfcd-5e8b654ea70c.aspx</comments>
      <category>TDD</category>
      <category>Bugs</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=c21e8214-e9be-4f9b-98ce-5c713d9f3cce</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,c21e8214-e9be-4f9b-98ce-5c713d9f3cce.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,c21e8214-e9be-4f9b-98ce-5c713d9f3cce.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c21e8214-e9be-4f9b-98ce-5c713d9f3cce</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>When NOT to use TDD</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,c21e8214-e9be-4f9b-98ce-5c713d9f3cce.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2009/08/07/WhenNOTToUseTDD.aspx</link>
      <pubDate>Fri, 07 Aug 2009 05:11:13 GMT</pubDate>
      <description>&lt;div&gt;Test driven development is a great practice. But, sometimes we definitely should NOT use it.&lt;br&gt;&lt;br&gt;right. who's this guy and where's John??&lt;br&gt;&lt;br&gt;Really, sometimes the practice of TDD isn't in the best interest of the business. TDD has pro's and con's.&lt;br&gt;&lt;br&gt;Pro's&lt;br&gt;&lt;ul&gt;&lt;li&gt;better quality code&lt;/li&gt;&lt;li&gt;actually does what the developer wanted it to do&lt;/li&gt;&lt;li&gt;can safely change/refactor without worrying if we broke it&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;Con's&lt;br&gt;&lt;ul&gt;&lt;li&gt;test code costs time and money to write&lt;br&gt;&lt;/li&gt;&lt;li&gt;test code is overhead, it has to be maintained in addition to the main line code&lt;/li&gt;&lt;li&gt;some test code can be complex and harder to understand than the code it tests&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;The reason we test software is to mitigate risk. The risks we mitigate can be many, but we ought to have business value in mitigating a risk before we write a test. Some projects are so small and temporary that it doesn't justify writing tests. The business isn't interested in mitigating too much risk from the small project or temporary utility that isn't already covered by the standard things programmers do to run their programs before they call them finished.&lt;br&gt;&lt;br&gt;Unit Testing is a great way to document functionality and illustrate that it works as intended. But the time and effort spent on writing the tests must be of value to the business - in the form of risk mitigation. For shipping products and tools that decisions will be based on, yes it makes sense to test it all thoroughly. The risk of customer problems and complaints, or bad decisions based on erroneous data are too high to leave un-mitigated. So we need to test them well to mitigate the risk and give that value to the business. Other times we can say a risk is just mitigated by the fact that we are "willing to accept" the risk. Acceptable Risk is a term I have heard used in threat modeling - indicating that the risk is so small or the problem so unlikely that we recognize it, but live with the risk that it may someday occur.&lt;br&gt;&lt;br&gt;Testing is overhead, so make sure that the testing done is appropriate. Make sure that there is recognized and enumerable risk that can be mitigated by each test. Make sure that all the tests (unit, integration, functional, etc.) are warranted for the software being tested. I don't recommend under-testing either.&lt;br&gt;&lt;br&gt;In Agile, one of our fundamental tenets is that we always strive to deliver value to the customer. For me, I strive to deliver value with each and every line of code, both main-line and in tests. Test the right things, and only at the right time.&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=c21e8214-e9be-4f9b-98ce-5c713d9f3cce"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,c21e8214-e9be-4f9b-98ce-5c713d9f3cce.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=27d85768-3c56-481c-9205-bdc2565a2259</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,27d85768-3c56-481c-9205-bdc2565a2259.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,27d85768-3c56-481c-9205-bdc2565a2259.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=27d85768-3c56-481c-9205-bdc2565a2259</wfw:commentRss>
      <title>Red, Green, Done.</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,27d85768-3c56-481c-9205-bdc2565a2259.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2009/06/04/RedGreenDone.aspx</link>
      <pubDate>Thu, 04 Jun 2009 20:17:50 GMT</pubDate>
      <description>&lt;div&gt;TDD is a great practice to use for code success, as long as the *entire* process is followed...&lt;br&gt;&lt;br&gt;write tests&lt;br&gt;write code&lt;br&gt;refactor&lt;br&gt;all tests green&lt;br&gt;we're done right?&lt;br&gt;&lt;br&gt;Refactoring is the Key to Successful TDD.&lt;br&gt;We need to look at the changes we made as part of the whole, NOT just in the small. We may have just added a method to a class that makes the class now responsible for more than just the one thing it was before... That's now a code smell (or design smell). When we've refactored the code to make it testable, we're not really done...&lt;br&gt;&lt;br&gt;We now need to take a step back, and look at the overall design, the archtecture, and how our implementation is satisfying the problems we are solving. We should make sure at this point in time that we can say everything is "well-designed" and "well-implemented."&lt;br&gt;&lt;br&gt;So many teams that are new to TDD, or that just practice test-first development, tend to forget this CRUCIALLY IMPORTANT step... It's not done, it's not estimated, and often the consequences are simply ignored until it gets to the point that the entire code base is impossible to maintain. This Technical Debt or Engineering Debt goes unaccounted in so many cases. Sometimes, this result ends up being one of the factors that teams use to stop using TDD. When compared to traditional waterfall design models, the output of teams that omit this critical step does not nearly measure up to the designs of waterfall methodology.&lt;br&gt;&lt;br&gt;There's no free lunch... We still need to have time in our plan for DESIGN. In waterfall, it's all up-front. With TDD and refactoring, we need to do it after we have written the code. We can't just "omit it" - otherwise we're not really "done."&lt;br&gt;&lt;br&gt;Each time I complete a story, part of my done criteria is to hold up the entire system to a bright light, and look through it for code and design smells. If there are any, it really isn't Done Done Done. I may check in the working code, but I don't close the story as complete until this task is finished.&lt;br&gt;&lt;br&gt;I estimate in a guess at least for time for sniffing out code and design smells on each story. My guideline for this is at least 10% of the time the rest of the tasks on the story take. Sometimes this clearly isn't enough, as when a story or feature causes significant re-design, or the adaption of an existing design to a new strategy. Use judgement on the estimate, but *AT LEAST* include the task for each story, even if it doesn't get estimated. This method will keep the issue out in the open and remind everyone that it still needs to be done.&lt;br&gt;&lt;br&gt;If your product owner balks at this additional time (and they most always do) remind them that its a little penalty now, or a HUGE one later. Unless it's a very short-term project on a temporary system, this is almost always a required task, so that maintenance and upkeep - even in the next sprint - aren't blown out of proportion.&lt;br&gt;&lt;br&gt;At the end of the day, the TEAM is responsible for deciding the best course of action to satifsy the the stakeholders, and even if the PO resists, the development management chain is *still* a stakeholder... As professional developers we really should have the ability to push back on a resistant PO with good quality engineering standards.&lt;br&gt;&lt;br&gt;Educate your PO's. Make sure people understand how important this critical step is in the story. Place a task on each story for design refactoring. And, last but not least, you can always place a large poster of a nose with a red line through it in the team space and caption it *No Code Smells*" ...&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=27d85768-3c56-481c-9205-bdc2565a2259"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,27d85768-3c56-481c-9205-bdc2565a2259.aspx</comments>
      <category>Refactoring</category>
      <category>TDD</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=9f5eeb1e-b674-4ae6-abd5-8073de4e03df</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,9f5eeb1e-b674-4ae6-abd5-8073de4e03df.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,9f5eeb1e-b674-4ae6-abd5-8073de4e03df.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=9f5eeb1e-b674-4ae6-abd5-8073de4e03df</wfw:commentRss>
      <title>SQL Server Queues PRINT output</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,9f5eeb1e-b674-4ae6-abd5-8073de4e03df.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2009/05/06/SQLServerQueuesPRINTOutput.aspx</link>
      <pubDate>Wed, 06 May 2009 17:00:43 GMT</pubDate>
      <description>&lt;div&gt;Ideally, SQL queries are executed really fast (sub-second). However there are times when it takes many seconds, even many minutes to execute each step. We have traditionally used the PRINT statement in SQL to output trace type information to the console so we can see what's happening.&lt;br&gt;&lt;br&gt;Recently I noticed that the PRINT statement output wasn't coming out when I expected it should. In doing some research on the issue, I discovered that the PRINT statement output is queued and batched rather than real-time.&lt;br&gt;&lt;br&gt;The solution for this problem is to use the RAISEERROR statement instead. Here is an example:&lt;br&gt;&lt;br&gt;DECLARE @msg NVARCHAR(MAX) = 'status message'&lt;br&gt;RAISERROR (@msg, 0, 1) WITH NOWAIT&lt;br&gt;&lt;br&gt;The severity of 0 tells SQL that everything is still fine, and NOWAIT instruction tells SQL not to queue it but to output immediately. The 1 is a locator that can be used to tell someone where to find the source of a particular message, if they are kept unique throughout the code.&lt;br&gt;&lt;br&gt;So, for long-running queries, use RAISEERROR and get those status messages out in real-time!&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=9f5eeb1e-b674-4ae6-abd5-8073de4e03df"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,9f5eeb1e-b674-4ae6-abd5-8073de4e03df.aspx</comments>
      <category>SQL</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=3672cae1-a523-409d-a5a3-0e032b6f8ebb</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,3672cae1-a523-409d-a5a3-0e032b6f8ebb.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,3672cae1-a523-409d-a5a3-0e032b6f8ebb.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3672cae1-a523-409d-a5a3-0e032b6f8ebb</wfw:commentRss>
      <title>&lt; Rant &gt;</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,3672cae1-a523-409d-a5a3-0e032b6f8ebb.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2009/04/08/.aspx</link>
      <pubDate>Wed, 08 Apr 2009 19:05:23 GMT</pubDate>
      <description>&lt;div&gt;OK people. STOP putting cowboy code on my desk. Seriously. TEST your software. REALLY. Please STOP writing BRAND NEW LEGACY code.&lt;br&gt;&amp;lt; /Rant &amp;gt;&lt;br&gt;&lt;br&gt;OK I feel better. But not really. Just because a system is not considered to be a "production release" (meaning that people outside the particular organization or business won't have access to it) it DOES NOT mean that we can cowboy it up and plop a steaming pile of untested code out there for our colleagues or coworkers to consume.&lt;br&gt;&lt;br&gt;ALL CODE NEEDS TESTS. Period.&lt;br&gt;&lt;br&gt;Untested code is NOT finished. Please don't just assume that if the code "works" that it's ready to inflict on other people (or even yourself). Self-inflicted legacy code casualties are the second highest cause of career paralysis, according to 4 out of 5 dentists. By definition, code is "legacy" if it doesn't have tests.&lt;br&gt;&lt;br&gt;Here's a plan to get your tests caught up.&lt;br&gt;&lt;br&gt;Start Small&lt;br&gt;At least we need a set of "sanity" checks... if nothing else. Create a "test suite." Use xUnit or the like, keep it simple. Start with the checks for the obvious output... if that doesn't show up, then something is clearly broken.&lt;br&gt;&lt;br&gt;Add Some More&lt;br&gt;One at a time if you have to, add another test for something. Any kind of test will do... unit, functional, acceptance... I recommend starting with acceptance and working backward. We already blew the op to be able to do TDD and get unit testing done, so now let's just make sure the surface behavior is adequate. Definitely do go in deeper if time permits.&lt;br&gt;&lt;br&gt;New Feature&lt;br&gt;Each time a new feature is added, update the test suite to make sure everything is happy with changes that ripple out from the effect of the feature. Again - at least make sure that the obvious functionality is tested on the new code. Don't slack on it, keep at least the new code from being legacy.&lt;br&gt;&lt;br&gt;Lather, Rinse, Repeat&lt;br&gt;Pick a time each week (say 4:30PM on Wednesdays) to put in a half-hour on writing one new test. Schedule it. Block the time out on your calendar so someone can't schedule a meeting... And hide if you have to - to avoid distractions.&lt;br&gt;&lt;br&gt;What to Write&lt;br&gt;Focus on happy-path code tests only if there are none for that feature. Otherwise, do alternate and failure path tests, so that the behavior of the system is understood in circumstances other than the best-case. 90% of bugs occur in the not-happy path.&lt;br&gt;&lt;br&gt;Using this strategy will get testing started, and contribute to a more robust and reliable product, no matter what it is. Remember that most "side projects" or "utilities" that are developed in-house will be used by your own people. We want them to have the best.&lt;br&gt;&lt;br&gt;"But it's just a spreadsheet." OK, yes it is. I say we need to make sure
to test even the lowly spreadsheet. Because, next week someone in
Finance is going to discover it and begin to use it for their payroll
planning... if there is a critical flaw in it, it might be YOUR
paycheck that gets eliminated!&lt;br&gt;
&lt;br&gt;We should realize that even internal tools and web sites are usually used to make business decisions of some kind. We want to make sure that they are made using reliable tools, to the extent possible. Business relies on its data, now more than ever. Competition is fierce in a down economy - even small mistakes can be a big problem.&lt;br&gt;&lt;br&gt;"Bread's not done until it's baked" - and neither is code! SO PLEASE: Test it. Bake it. Slice it... and don't get burned!&lt;br&gt;&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=3672cae1-a523-409d-a5a3-0e032b6f8ebb"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,3672cae1-a523-409d-a5a3-0e032b6f8ebb.aspx</comments>
      <category>TDD</category>
      <category>Testing</category>
      <category>Unit Tests</category>
    </item>
  </channel>
</rss>