<?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 - Unit Tests</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=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>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=e36a37f3-53c9-460d-8042-ee50090f0ad0</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,e36a37f3-53c9-460d-8042-ee50090f0ad0.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,e36a37f3-53c9-460d-8042-ee50090f0ad0.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e36a37f3-53c9-460d-8042-ee50090f0ad0</wfw:commentRss>
      <title>Unit Testing and Test Driven Development - a Practical Guide</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,e36a37f3-53c9-460d-8042-ee50090f0ad0.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2008/11/15/UnitTestingAndTestDrivenDevelopmentAPracticalGuide.aspx</link>
      <pubDate>Sat, 15 Nov 2008 21:08:59 GMT</pubDate>
      <description>&lt;div&gt;Here is a presentation I wrote on what Unit Testing is all about, and how TDD fits into the ATDD cycle.&lt;br&gt;&lt;br&gt;There are specific things here on testing the UI code with Selenium and JSUnit, and recommendations on how to do unit testing on your database code.&lt;br&gt;&lt;br&gt;This presentation is in PDF format, but I can post the PPTX format also if needed.&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;a href="http://testdrivendeveloper.com/content/binary/A%20Practical%20Guide%20to%20Unit%20Testing1.pdf"&gt;A Practical Guide to Unit Testing1.pdf (503.29 KB)&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=e36a37f3-53c9-460d-8042-ee50090f0ad0"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,e36a37f3-53c9-460d-8042-ee50090f0ad0.aspx</comments>
      <category>ATDD</category>
      <category>Mocks</category>
      <category>Refactoring</category>
      <category>Selenium</category>
      <category>TDD</category>
      <category>Testing</category>
      <category>Unit Tests</category>
      <category>SQL</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=10a8368d-9191-4f9c-bc29-ca957bb111e5</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,10a8368d-9191-4f9c-bc29-ca957bb111e5.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,10a8368d-9191-4f9c-bc29-ca957bb111e5.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=10a8368d-9191-4f9c-bc29-ca957bb111e5</wfw:commentRss>
      <title>More Tips for Unit Testing in Iron Python</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,10a8368d-9191-4f9c-bc29-ca957bb111e5.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2008/10/07/MoreTipsForUnitTestingInIronPython.aspx</link>
      <pubDate>Tue, 07 Oct 2008 16:09:49 GMT</pubDate>
      <description>&lt;div&gt;Do you ever wonder why there is an extra "False" printed at the end of each run for unit tests?&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;C:\Code\sample&amp;gt;ipy UnitTests.py&lt;br&gt;.....&lt;br&gt;----------------------------------------------------------------------&lt;br&gt;Ran 5 tests in 0.395s&lt;br&gt;&lt;br&gt;OK&lt;br&gt;False&lt;/font&gt;&lt;br&gt;&lt;br&gt;It looks like there is an exit statement buried inside the unit test framework. We can eliminate the problem pretty easily with the addition of a try/except around the unit test execution. Here is the code to put at the end of your unit test script:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt; __name__ &lt;font color="#0000ff"&gt;==&lt;/font&gt; '&lt;font color="#a9a9a9"&gt;__main__&lt;/font&gt;':&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;try&lt;/font&gt;:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; unittest.main&lt;font color="#0000ff"&gt;()&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;except&lt;/font&gt; SystemExit:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;pass&lt;/font&gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;This catches and eats the SystemExit exception, and runs without printing the "False" at the end of the execution:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;C:\Code\sample&amp;gt;ipy UnitTests.py&lt;br&gt;.....&lt;br&gt;----------------------------------------------------------------------&lt;br&gt;Ran 5 tests in 0.387s&lt;br&gt;&lt;br&gt;OK&lt;br&gt;&lt;/font&gt;&lt;br&gt;cheers!&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=10a8368d-9191-4f9c-bc29-ca957bb111e5"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,10a8368d-9191-4f9c-bc29-ca957bb111e5.aspx</comments>
      <category>Python</category>
      <category>Testing</category>
      <category>Unit Tests</category>
    </item>
    <item>
      <trackback:ping>http://testdrivendeveloper.com/Trackback.aspx?guid=43b275ad-d66d-4544-b378-822d75adfe9e</trackback:ping>
      <pingback:server>http://testdrivendeveloper.com/pingback.aspx</pingback:server>
      <pingback:target>http://testdrivendeveloper.com/PermaLink,guid,43b275ad-d66d-4544-b378-822d75adfe9e.aspx</pingback:target>
      <dc:creator>John E. Boal</dc:creator>
      <wfw:comment>http://testdrivendeveloper.com/CommentView,guid,43b275ad-d66d-4544-b378-822d75adfe9e.aspx</wfw:comment>
      <wfw:commentRss>http://testdrivendeveloper.com/SyndicationService.asmx/GetEntryCommentsRss?guid=43b275ad-d66d-4544-b378-822d75adfe9e</wfw:commentRss>
      <title>Testing SQL Tables</title>
      <guid isPermaLink="false">http://testdrivendeveloper.com/PermaLink,guid,43b275ad-d66d-4544-b378-822d75adfe9e.aspx</guid>
      <link>http://TestDrivenDeveloper.com/2008/01/14/TestingSQLTables.aspx</link>
      <pubDate>Mon, 14 Jan 2008 16:15:53 GMT</pubDate>
      <description>&lt;div&gt;&lt;div&gt;Have you ever wanted to test a table in the database for the correct structure? Ever had someone make a column nullable that shouldn't have been? ever have someone make a column VARCHAR instead of NVARCHAR? INT instead of BIGINT? SMALLDATETIME instead of DATETIME? This is an easy way for bugs to creep in - when the code is written for one version of the database and then someone makes a change... So if you haven't been testing your tables (SQL&amp;nbsp;should be TDD'd too), perhaps you should...&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Here is a handy stored procedure you could use that describes a table in an easy-to-test way.&lt;/div&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;/font&gt;&lt;div&gt;&lt;font color="#0000ff" size="2"&gt;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;


&lt;div&gt;&lt;font color="#0000ff" size="2"&gt;&lt;font face="Courier New"&gt;CREATE &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff" size="2"&gt;PROCEDURE&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt; describe &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;@table_name &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;varchar&lt;/font&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;90&lt;/font&gt;&lt;font color="#808080" size="2"&gt;))&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt; &lt;/font&gt;&lt;/div&gt;

&lt;div&gt;&lt;font color="#0000ff" size="2"&gt;&lt;font face="Courier New"&gt;AS&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font color="#0000ff" size="2"&gt;&lt;font face="Courier New"&gt;SELECT &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff" size="2"&gt;DISTINCT&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;

&lt;div&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&amp;nbsp; sc&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;column_id &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;as&lt;/font&gt;&lt;font size="2"&gt; ColumnNumber&lt;/font&gt;&lt;font color="#808080" size="2"&gt;,&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/div&gt;

&lt;div&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&amp;nbsp; cols&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;column_name &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;as&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;Name&lt;/font&gt;&lt;font color="#808080" size="2"&gt;,&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/div&gt;

&lt;div&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&amp;nbsp; cols&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;data_type &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;as&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;Type&lt;/font&gt;&lt;font color="#808080" size="2"&gt;,&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#ff00ff" size="2"&gt;&amp;nbsp; ISNULL&lt;/font&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;cols&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;character_maximum_length&lt;/font&gt;&lt;font color="#808080" size="2"&gt;,&lt;/font&gt;&lt;font size="2"&gt; 0&lt;/font&gt;&lt;font color="#808080" size="2"&gt;)&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;as&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;Length&lt;/font&gt;&lt;font color="#808080" size="2"&gt;,&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/div&gt;

&lt;div&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&amp;nbsp; cols&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;is_nullable &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;as&lt;/font&gt;&lt;font size="2"&gt; Nullable&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2" face="Courier New"&gt; &lt;/font&gt;&lt;/div&gt;

&lt;div&gt;&lt;font color="#0000ff" size="2" face="Courier New"&gt;FROM&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;&lt;font color="#008000" size="2" face="Courier New"&gt;&amp;nbsp; information_schema.columns&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;&lt;font face="Courier New"&gt; cols&lt;/font&gt;&lt;font face="Times New Roman"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;&amp;nbsp; INNER&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;JOIN&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#008000" size="2"&gt;sys.columns&lt;/font&gt;&lt;font color="#000000" size="2"&gt; sc &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;ON&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;br&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cols&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;column_name &lt;/font&gt;&lt;font color="#808080" size="2"&gt;=&lt;/font&gt;&lt;font size="2"&gt; sc&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;name&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#808080" size="2"&gt;AND&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff00ff" size="2"&gt;OBJECT_NAME&lt;/font&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;sc&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font color="#ff00ff" size="2"&gt;object_id&lt;/font&gt;&lt;font color="#808080" size="2"&gt;)&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;=&lt;/font&gt;&lt;font size="2"&gt; @table_name&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt; &lt;/font&gt;&lt;/p&gt;


&lt;div&gt;&lt;font color="#0000ff" size="2"&gt;&lt;font face="Courier New"&gt;ORDER &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff" size="2"&gt;BY&lt;/font&gt;&lt;font color="#000000" size="2"&gt; sc&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;column_id&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000" size="3"&gt; &lt;/font&gt;&lt;/div&gt;

&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Just call it with the table name and&amp;nbsp;it produces a nice format the tests can use to extract the info they need to check.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;# Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Length Nullable&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;1 Id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NO&lt;br&gt;2&amp;nbsp;TypeId&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NO&lt;br&gt;3&amp;nbsp;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nvarchar&amp;nbsp;50&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NO&lt;br&gt;4&amp;nbsp;Description&amp;nbsp; nvarchar&amp;nbsp;1500&amp;nbsp;&amp;nbsp; NO&lt;br&gt;5&amp;nbsp;CreateDate&amp;nbsp;&amp;nbsp; datetime&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NO&lt;br&gt;6&amp;nbsp;UpdateDate&amp;nbsp;&amp;nbsp; datetime&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; YES&lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font size="3" face="Times New Roman"&gt;just employ a data reader to read the data in the test, and your unit tests&amp;nbsp;can ensure that all of the tables have the right structure.&lt;/font&gt;&lt;/div&gt;&lt;img width="0" height="0" src="http://testdrivendeveloper.com/aggbug.ashx?id=43b275ad-d66d-4544-b378-822d75adfe9e"/&gt;&lt;/div&gt;</description>
      <comments>http://testdrivendeveloper.com/CommentView,guid,43b275ad-d66d-4544-b378-822d75adfe9e.aspx</comments>
      <category>SQL</category>
      <category>Tools</category>
      <category>Unit Tests</category>
    </item>
  </channel>
</rss>