<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" 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:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>Scott C. Reynolds</title>
        <link>http://scottcreynolds.com/Default.aspx</link>
        <description>Working to improve software development</description>
        <language>en-US</language>
        <copyright>Scott C. Reynolds</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <image>
            <title>Scott C. Reynolds</title>
            <url>http://scottcreynolds.com/images/RSS2Image.gif</url>
            <link>http://scottcreynolds.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <geo:lat>29.166186</geo:lat><geo:long>-82.170279</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.0/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/scottcreynolds" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
            <title>Hang in there baby birds, I'll feed you</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/yQ6XYkkEfCE/613.aspx</link>
            <description>&lt;p&gt;Quick housekeeping note - How We Do Things series is not cancelled, I haven't given up on it or run out of steam, it will still press forward.&lt;/p&gt;
&lt;p&gt;Trying to get a lot wrapped up both at home and at work in preparation for my move to New York, so I lapsed a bit, but I will be back on it soon.&lt;/p&gt;&lt;img src="http://scottcreynolds.com/aggbug/613.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=yQ6XYkkEfCE:UOKtnfQSfNU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=yQ6XYkkEfCE:UOKtnfQSfNU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=yQ6XYkkEfCE:UOKtnfQSfNU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=yQ6XYkkEfCE:UOKtnfQSfNU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=yQ6XYkkEfCE:UOKtnfQSfNU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=yQ6XYkkEfCE:UOKtnfQSfNU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=yQ6XYkkEfCE:UOKtnfQSfNU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=yQ6XYkkEfCE:UOKtnfQSfNU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=yQ6XYkkEfCE:UOKtnfQSfNU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/yQ6XYkkEfCE" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/11/05/613.aspx</guid>
            <pubDate>Thu, 05 Nov 2009 20:19:40 GMT</pubDate>
            <wfw:comment>http://scottcreynolds.com/comments/613.aspx</wfw:comment>
            <comments>http://scottcreynolds.com/archive/2009/11/05/613.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/613.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/613.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/11/05/613.aspx</feedburner:origLink></item>
        <item>
            <title>My Favorite System Deploy Story</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/NGGJG1nffzk/612.aspx</link>
            <description>&lt;p&gt;I just remembered this and regaled the newer members of the team with this amazing story that happened when we rolled out our new enterprise lab management system a few years ago.&lt;/p&gt;
&lt;p&gt;The end result of all of our processes basically is a pretty report that goes to our client doctors and gives a diagnosis.&lt;/p&gt;
&lt;p&gt;We were up in New York for a month of 20 hour days getting the system finalized and deployed. It was a wholesale changeover from old system to new.&lt;/p&gt;
&lt;p&gt;Literally the day before deployment day I was up all night creating the reporting engine and finalizing report layout. Everything was happening under great pressure.&lt;/p&gt;
&lt;p&gt;We rolled the system out the next morning, and things seemed to be going smoothly, until a client called us frantically claiming that there was a picture of a MONKEY on their report they just received.&lt;/p&gt;
&lt;p&gt;This put us into panic mode. What did we do wrong? Did some bogus image from test make it into production? Did I do something incredibly strange when I was creating these reports on no sleep? What went wrong?&lt;/p&gt;
&lt;p&gt;We immediately dropped everything and started searching databases and code to see what could have happened. This was basically the first report generated by the new system, and somehow it had a MONKEY on it!&lt;/p&gt;
&lt;p&gt;After unsuccessfully trying to find the phantom monkey in the system, we asked the client to fax us a copy of the report. We waited with bated breath, the whole team huddled around the fax machine.&lt;/p&gt;
&lt;p&gt;After a few minutes, paper started to come out...&lt;/p&gt;
&lt;p&gt;I snatched it from the machine...&lt;/p&gt;
&lt;p&gt;There was indeed a monkey. The page also said "HP LaserJet Printer Test Page".&lt;/p&gt;
&lt;p&gt;Sigh.&lt;/p&gt;&lt;img src="http://scottcreynolds.com/aggbug/612.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=NGGJG1nffzk:RQ4Ro90vj8k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=NGGJG1nffzk:RQ4Ro90vj8k:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=NGGJG1nffzk:RQ4Ro90vj8k:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=NGGJG1nffzk:RQ4Ro90vj8k:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=NGGJG1nffzk:RQ4Ro90vj8k:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=NGGJG1nffzk:RQ4Ro90vj8k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=NGGJG1nffzk:RQ4Ro90vj8k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=NGGJG1nffzk:RQ4Ro90vj8k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=NGGJG1nffzk:RQ4Ro90vj8k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/NGGJG1nffzk" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/13/612.aspx</guid>
            <pubDate>Tue, 13 Oct 2009 17:33:00 GMT</pubDate>
            <wfw:comment>http://scottcreynolds.com/comments/612.aspx</wfw:comment>
            <comments>http://scottcreynolds.com/archive/2009/10/13/612.aspx#feedback</comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/612.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/612.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/13/612.aspx</feedburner:origLink></item>
        <item>
            <title>How We Do Things - Testing Part 2</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/9Utazx5Du4c/611.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;This content comes solely from my experience, study, and a lot of trial and error (mostly error). I make no claims stating that which works for me will work for you. As with all things, your mileage may vary, and you will need to apply all knowledge through the filter of your context in order to strain out the good parts for you. Also, feel free to call BS on anything I say. I write this as much for me to learn as for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is part 5 of the &lt;a href="http://scottcreynolds.com/archive/2009/10/04/605.aspx"&gt;How We Do Things&lt;/a&gt; series.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In the last installment I talked about our the evolution of our TDD/BDD Practice. In this one, I will talk more specifically about the tools we use, where we apply TDD, and other testing practices we employ.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;n.b. I'll use "specification" interchangeably with "test" here, so when you see it, don't think "spec document".&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;.Net Testing&lt;/h3&gt;
&lt;p&gt;In our .net applications we employ TDD/BDD with a combination of &lt;a href="http://www.nunit.org/index.php"&gt;NUnit&lt;/a&gt;, &lt;a href="http://testdriven.net/"&gt;TestDriven.net&lt;/a&gt;, &lt;a href="http://www.jetbrains.com/resharper/index.html"&gt;ReSharper&lt;/a&gt;, and a sprinkling of extension methods and abstract base classes inspired by &lt;a href="http://blog.scottbellware.com/"&gt;Scott Bellware's&lt;/a&gt; &lt;a href="http://code.google.com/p/specunit-net/"&gt;SpecUnit.net&lt;/a&gt; project (now defunct, if you are looking for a more full context/specification framework, check out the excellent &lt;a href="http://github.com/machine/machine.specifications"&gt;Machine.Specifications (MSpec)&lt;/a&gt; from &lt;a href="http://codebetter.com/blogs/aaron.jensen/default.aspx"&gt;Aaron Jensen&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Our standard abstract base class for a specification looks a bit like this:
&lt;/p&gt;&lt;pre class="brush: csharp"&gt;
    [TestFixture]
    public abstract class SpecificationBase
    {
        protected virtual void Because(){}
        protected abstract void Before_All();
        protected virtual void After_All(){}    
		 
        [TestFixtureSetUp]
        public void context_before_all_specs()
        {
            Before_All();
            Because();
        }
        [TestFixtureTearDown]
        public void teardown_after_all_specs()
        {
            After_All();
        }
    }&lt;/pre&gt;
That's it, pretty simplistic. With this base we try to "encourage" context to get set up in [TestFixtureSetup] rather than [SetUp], the idea being that if a context is going to fit a whole specification (testfixture) then it's more efficient to set up once. We don't provide a base for [SetUp] and [TearDown] because we want to see those ugly tags in our specification class to remind us to question if we really are breaking up our context appropriately.
&lt;p&gt;We also make heavy use of extension methods to wrap assertions, so that we can do things like &lt;/p&gt;&lt;pre&gt;observedState.ShouldBeTrue();&lt;/pre&gt;
&lt;p&gt;As for the test runner, the R# test runner is great, and pretty, and we will fall back to that to get a nice output list of specs at the end of implementing something, but for the sake of speed and flow, while we're actually implementing we tend to prefer the TD.Net runner. This isn't mandated though, and some guys stick to the R# runner for everything.&lt;/p&gt;
&lt;h3&gt;Higher up the stack in .Net&lt;/h3&gt;
&lt;p&gt;As it stands today, we do not do any web development in .net. We only have WinForms and a smattering of WPF.&lt;/p&gt;
&lt;p&gt;We don't use a FIT tool, or a scenario tool like NGourd, because we haven't really felt a need for this. We do intend to examine StoryTeller and see if it adds value to our process, and when we do, I'll write about it.&lt;/p&gt;
&lt;p&gt;We've found that using separated presentation patterns (such as Model-View-Presenter) allows us to very easily drive out everything but the actual UI forms with NUnit and context/specification.&lt;/p&gt;
&lt;p&gt;For UI test automation in .net we use &lt;a href="http://www.codeplex.com/white"&gt;Project White&lt;/a&gt;. We do this similar to how you would run Selenium or Watin tests, carving out chunks of functionality to test as a unit and automating it. Usually these test units are organized around a given MMF because it feels like a natural fit.&lt;/p&gt;
&lt;p&gt;We do not have anywhere near 100% coverage for automated UI testing at present because the cost to do so immediately can't be justified, so we move forward putting new things under test in this fashion and backfill as we have time. It took us a long time to find a tool we could use (note I didn't say "that we were happy with") and Project White fits the bill well enough, but, simply, there's just a lot of things you can do in a WinForms UI that makes it &lt;strong&gt;extremely difficult&lt;/strong&gt; to test in an automated fashion.&lt;/p&gt;
&lt;h3&gt;TDD/BDD in Ruby and Rails&lt;/h3&gt;
&lt;p&gt;In our new and still evolving rails practice, we utilize &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; and &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; for TDD and for higher-level automation tests. We do context/specification style BDD for our models, and typically do not test-drive our controllers at that level. We will drop down and put some unit tests around our controllers when we feel like we have a hole, or something complicated, but we usually take that as a sign to either move functionality to a model or simplify design.&lt;/p&gt;
&lt;p&gt;We started using &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; for scenario tests, but were not happy with the workflow. The tool itself is great, but the workflow didn't get us where we wanted to go. We felt like we were repeating motion on a lot of specification between Cucumber scenarios and RSPec-driven model specs, and that was wasteful.&lt;/p&gt;
&lt;p&gt;Instead of that, we test-drive scenarios in RSPec by automating Selenium. This is what covers our controllers and views and sets the expectations of the feature. We do this in context/spec style as well, and the specs (tests) are created as part of the story exploration process, ahead of code being written.&lt;/p&gt;
&lt;h3&gt;Manual QA and "Acceptance" Testing&lt;/h3&gt;
&lt;p&gt;We do have a manual QA process, and I'm not sure that you can safely get away from that in a non-trivial system.&lt;/p&gt;
&lt;p&gt;The trick is to make it so that the manual exploratory testing is &lt;em&gt;strictly&lt;/em&gt; exploratory, and that by the time a feature gets to this stage TDD and higher-level automated tests are covering the &lt;em&gt;correctness&lt;/em&gt; of the expected execution paths.&lt;/p&gt;
&lt;p&gt;We combine manual exploratory testing with manual acceptance testing, and the idea here is that any work coming back should be in the realm of usability concerns and slight functional tweaks, not actual bugs. I feel like we've hit a pretty sweet stride here actually, and the ratio of bugs found at this stage to usability issues found at this stage is about 1 to 10. This is a good thing. This means that we have done our due diligence ahead of time with automated tests and our manual testing is concerned with what manual testing should be concerned with - usability - 90% of the time.&lt;/p&gt;
&lt;h3&gt;Tests as Documentation&lt;/h3&gt;
&lt;p&gt;We never have had a reason to show test output in any form to a user or other business person, so we haven't invested a lot of time into getting nice runner output formatted anywhere (and that's also why cucumber and FIT don't really have much of a value proposition for us). Our tests themselves are constructed so that both the testers and business analysts can read them and understand the specifications, and the testers, business analysts, and developers all collaborate ahead of time to actually scaffold out the specifications.&lt;/p&gt;
&lt;p&gt;By involving the full team in creating the specifications we ensure that they have value beyond the developer desk, and that we are reinforcing among all parties the expectations about the system. This is all about communication, and it's the key to any agile or lean development process.&lt;/p&gt;

&lt;h3&gt;When we *don't* TDD&lt;/h3&gt;
&lt;p&gt;We do not practice TDD 100% of the time. There. I said it.&lt;/p&gt;
&lt;p&gt;We don't typically TDD spikes. Rather, we don't mandate it. If you want to TDD a spike go for it. Sometimes I do, sometimes I don't. Depends on the context.&lt;/p&gt;
&lt;p&gt;I already said we don't TDD our rails controllers or views, and we don't TDD the actual forms of our WinForms apps. This is a choice where we figure the cost/benefit ratio is not there. YMMV.&lt;/p&gt;
&lt;p&gt;There are certain areas of our system that don't end up getting TDD treatment when we add to them. This happens for various reasons, part of which is that it's just hard to TDD them, and part of which is that it doesn't add much value anyway. One such scenario is in places where we export our data into a common xml format for integrations with other healthcare systems. In these scenarios, the code to generate the xml was done with TDD, and the format is standard. The actual generating and manipulating of the data to feed to the xml builder involves a lot of copy/paste functionality and one-off tweaking on a line-by-line basis. This is all kept black-box to the system at large, uses a known (and tested) api to grab the data, and just doesn't make sense to TDD. There's a lot of copy/paste because the exporters operate independently and need to have 90% of the same functionality across the board but with variability in how the data is modeled. It works, even though it sounds like it could be constructed better on the surface. You'll just have to trust me.&lt;/p&gt;
&lt;p&gt;We also don't TDD our reports. Much like forms, there's too much tweaking and fiddling to get them to lay out right, and TDD just doesn't work for us there. But as in the previous example, the api's from which the reports get their data have been driven out by tests.&lt;/p&gt;
&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/how                   0e                  11o                   8t" rel="tag"&gt;how we do it&lt;/a&gt;, &lt;a href="http://technorati.com/tag/improvement" rel="tag"&gt;improvement&lt;/a&gt;, &lt;a href="http://technorati.com/tag/lean" rel="tag"&gt;lean&lt;/a&gt;, &lt;a href="http://technorati.com/tag/management" rel="tag"&gt;management&lt;/a&gt;, &lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://technorati.com/tag/team" rel="tag"&gt;team&lt;/a&gt;, &lt;a href="http://technorati.com/tag/planning" rel="tag"&gt;planning&lt;/a&gt;
&lt;a href="http://technorati.com/tag/TDD" rel="tag"&gt;TDD&lt;/a&gt;
&lt;a href="http://technorati.com/tag/BDD" rel="tag"&gt;BDD&lt;/a&gt;
&lt;a href="http://technorati.com/tag/testing" rel="tag"&gt;testing&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/611.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=9Utazx5Du4c:fS6eOWC4VNo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=9Utazx5Du4c:fS6eOWC4VNo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=9Utazx5Du4c:fS6eOWC4VNo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=9Utazx5Du4c:fS6eOWC4VNo:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=9Utazx5Du4c:fS6eOWC4VNo:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=9Utazx5Du4c:fS6eOWC4VNo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=9Utazx5Du4c:fS6eOWC4VNo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=9Utazx5Du4c:fS6eOWC4VNo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=9Utazx5Du4c:fS6eOWC4VNo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/9Utazx5Du4c" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/11/611.aspx</guid>
            <pubDate>Mon, 12 Oct 2009 00:07:30 GMT</pubDate>
            <wfw:comment>http://scottcreynolds.com/comments/611.aspx</wfw:comment>
            <comments>http://scottcreynolds.com/archive/2009/10/11/611.aspx#feedback</comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/611.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/611.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/11/611.aspx</feedburner:origLink></item>
        <item>
            <title>How We Do Things - Evolving our TDD/BDD Practice</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/jBY9QWr33iE/610.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;This content comes solely from my experience, study, and a lot of trial and error (mostly error). I make no claims stating that which works for me will work for you. As with all things, your mileage may vary, and you will need to apply all knowledge through the filter of your context in order to strain out the good parts for you. Also, feel free to call BS on anything I say. I write this as much for me to learn as for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is part 4 of the &lt;a href="http://scottcreynolds.com/archive/2009/10/04/605.aspx"&gt;How We Do Things&lt;/a&gt; series.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Today we're going to talk about how we evolved our TDD practice, the troubles we faced along the way, and where we stand now.&lt;/p&gt;
&lt;p&gt;I already mentioned that when we started this project oh so many years ago we did not construct it with TDD, and I've mentioned how well (from the user perspective anyway) it turned out. So, let's dispel any notions that I've ever said that no software can be successful that wasn't built with TDD, because the flagship of my career was.&lt;/p&gt;
&lt;p&gt;However, I will qualify that by saying that now, when the team has to go into that old code to modify it, we curse ourselves constantly for not having done TDD. I can say with confidence that had the system been designed with TDD as we practice it now that changes would be easier to make, and the code would be easier to understand 5 years later.&lt;/p&gt;
&lt;p&gt;But practices evolve, and that's what this series is about, non?&lt;/p&gt;
&lt;h3&gt;Many False Starts&lt;/h3&gt;
&lt;div style="text-align:center;"&gt;&lt;img src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scottcreynolds/DarthTesting.png" alt="DarthTesting.png" border="0" width="350" height="300" /&gt;&lt;/div&gt;
&lt;p&gt;Now we started with every intention of doing TDD. We made an effort, but it fell by the wayside very quickly as pressures mounted. At the time I had only a very surface understanding of TDD and had not been a full-time practitioner at any point. The other programmer on the team at the time was a fresh out of high school kid with very little experience. We weren't pair programming, and I lacked the knowledge and experience to mentor the TDD practice, so it was essentially a non-starter.&lt;/p&gt;
&lt;p&gt;For a while we did do unit and integration testing in test-after (TAD) form, but that fell apart as well. We fell into the trap of optimizing the "code complete" workflow at the expense of test coverage.&lt;/p&gt;
&lt;p&gt;As time went on my understanding of TDD grew. I got more involved in the community and started practicing more on my own. I credit &lt;a href="http://blog.scottbellware.com/"&gt;Scott Bellware&lt;/a&gt;, &lt;a href="http://codebetter.com/blogs/david_laribee/"&gt;Dave Laribee&lt;/a&gt;, &lt;a href="http://codebetter.com/blogs/raymond.lewallen/default.aspx"&gt;Ray Lewallen&lt;/a&gt;, and &lt;a href="http://codebetter.com/blogs/jeremy.miller/default.aspx"&gt;Jeremy Miller&lt;/a&gt; primarily for either directly or indirectly influencing and increasing my knowledge of the practice.&lt;/p&gt;
&lt;p&gt;When adopting any advanced practice it is incredibly important to have masters to learn from. This is true in programming and elsewhere. These guys, whether via their blogs, or conversations, or actually sharing code helped me immensely in bootstrapping my testing practice.&lt;/p&gt;
&lt;p&gt;As a team leader, it's also important that you have the tools to mentor your team in a new practice. My folly the first few times we started (and quickly stopped) doing TDD was not being able to do that mentoring, but trying anyway. It broke down quickly.&lt;/p&gt;
&lt;p&gt;Eventually we started picking up TDD again. It wasn't a 100% thing, but we were making the effort, and I was doing a much better job leading the way. I was actually working with my team to help them write tests rather than simply giving the directive and some links to read. I was educating them on OO principles that would help them understand how tests can drive design, rather than letting them flounder.&lt;/p&gt;
&lt;p&gt;This is all not to say that I did everything perfectly, in fact rather the opposite. I didn't understand how many disciplines were at play for successful TDD adoption at first, and I take full blame for not having the leadership ability to get them there sooner.&lt;/p&gt;
&lt;p&gt;We went along like this doing TDD, though at times very fragile and naïve TDD, on new development where it was easy. It wasn't until after Scott introduced me to Context/Specification (c/s) at one of the early alt.net events that everything seemed to click. I came back from that event and gathered my team, which had grown to 3, in a room where we pair programmed as a group for several days and explored c/s and BDD together. By the end of that week it was as if a light went on for us collectively, and our testing practice from that point on was much more robust.&lt;/p&gt;
&lt;p&gt;As new members joined the team we immediately went into mentoring on c/s. At the time we weren't pair programming as a rule yet though, so it was difficult. We also were still dealing with a significant legacy code problem and putting tests around new things to interact with old things that weren't all that testable was difficult to say the least.&lt;/p&gt;
&lt;p&gt;Frustration finally set in for us and we set about making our legacy codebase more testable. We didn't have time or budget to do this all in one fell swoop, so we did what any good team does...refactored as we went. Slowly but surely we started getting comfortable with a few patterns that we could employ to refactor our legacy code for tests while adding new features or fixing bugs, and our TDD practice really started to get teeth.&lt;/p&gt;
&lt;h3&gt;The Catalyst - Pair Programming&lt;/h3&gt;
&lt;div style="text-align:center;"&gt;&lt;img src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scottcreynolds/pairpong.png" alt="pairpong.png" border="0" width="350" height="300" /&gt;&lt;/div&gt;
&lt;p&gt;When we finally introduced pair programming as a regular practice (more on this in a later post) we started to see a real uptick in the understanding and appropriate application of TDD and c/s. Mentoring by the more experienced team members was happening in real-time, as code was being written, and understanding skyrocketed. There were other benefits to pairing as well, but again, that's a later post in the series.&lt;/p&gt;
&lt;p&gt;Suffice it to say, if I had to do it over again we would have introduced pair programming far earlier, and our testing practice wouldn't have suffered from so many false starts for so long.&lt;/p&gt;
&lt;h3&gt;a_monkey_wrench&lt;/h3&gt;
&lt;p&gt;We were sailing along pretty well with our TDD and c/s practice in our c# WinForms applications, which was the bulk of what we did. Then we had some shifts in corporate priorities that saw us doing a lot more web work. Rather than go with the .net platform, we chose Ruby on Rails for this. We'll talk about how we choose tech in a later part of this series as well.&lt;/p&gt;
&lt;p&gt;The thing with going RoR was that it was totally new for us on a lot of levels. We hadn't done any significant web-based work in years. I hadn't touched the web since 2001 myself. Plus we were a total .net shop up until that point, and this was a completely new language, on a completely new platform. We had to learn ruby, rails, ajax, apache, linux, and a whole slew of related technologies.&lt;/p&gt;
&lt;p&gt;It turned out that trying to throw RSpec and TDD into the mix was just too much for us, and we were at near zero productivity. We were under pressure to produce this first project, and prove that Rails was going to be a viable option for us going forward, so I made the call to suspend TDD for this project.&lt;/p&gt;
&lt;p&gt;Some of you may call this a weak decision, and I totally get that. However, I had to make a choice, and the choice was very difficult. At the end, I chose to suspend a practice that we believe strongly in to get some velocity on learning all this new stuff and producing code.&lt;/p&gt;
&lt;p&gt;By the end of the project, we were feeling the pain of a no-test environment. We got through it, and once again we definitely produced some working, amazing (to the user) software. But the combination of not being experienced with ruby and rails and not having tests took its toll toward the end as we found ourselves struggling to maintain and add to what we had done.&lt;/p&gt;
&lt;h3&gt;Asking for help&lt;/h3&gt;
&lt;p&gt;After the successful completion of the pilot project, we knew we would be moving forward with rails for a major web project that would have a big impact on the business.&lt;/p&gt;
&lt;p&gt;We also knew we didn't want to move forward with this major project without having our BFF TDD at our side, so we needed help to bootstrap the practice in ruby and rails to match what we did in c# and .net.&lt;/p&gt;
&lt;p&gt;We started going down the road of learning RSpec and using Cucumber for acceptance testing, but the workflow felt foreign to us, and we weren't able to find a rhythm that we liked.&lt;/p&gt;
&lt;p&gt;We called Scott Bellware and brought him down to give a day of intense training for the full team in context/specification for rails with RSpec and Selenium.&lt;/p&gt;
&lt;p&gt;Scott came in and gave us a great day of training and helped us solidify our practices in web testing and TDD for ruby and rails. By the end of the day we were all exhausted, but we had a great start down what we felt was the right path (I owe you a guest post on this too Scott, I haven't forgotten).&lt;/p&gt;
&lt;p&gt;Now this new project is moving forward rapidly, with TDD happening. The spot we've found that we like (for now) is that we do c/s in rspec for models, but don't really TDD our controllers. The controllers get tested by the higher level selenium-driven scenario tests, and if they're being constructed right, they should just be middlemanning things between the view and the model. We write the selenium scenarios in c/s style ahead of time to drive out what's expected to happen, so for us, this practice appears to be working fairly well. I think we will be revisiting it however, in the spirit of continuous improvement, as we come up against places where we have holes in the practice.&lt;/p&gt;
&lt;h3&gt;Wrapping it up&lt;/h3&gt;
&lt;p&gt;So, the TLDR version: we didn't always do TDD, and we had a lot of false starts along the way. I learned that it takes a lot of hands-on leadership to get it rolling, not just directive. If I had to do it over again, pairing practice would have been in place first, because it would have made it a TON easier. I also would have made sure that I was more in a place with my personal knowledge and experience of the practice before foisting it upon my team.&lt;/p&gt;
&lt;p&gt;The practice has evolved massively over the last 4 or 5 years, and it has not been easy. But it has been worth it. This is anecdotal. I have no real numbers for you. But I do know that the pulse of my team is that life is better with TDD than without, and in the case where someone goes off on their own and does something without it, they usually come back when they have to maintain or extend it and say "man, I wish I had done TDD here". To me, that's proof enough.&lt;/p&gt;
&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/how                   3e                   7o                  11t" rel="tag"&gt;how we do it&lt;/a&gt;, &lt;a href="http://technorati.com/tag/improvement" rel="tag"&gt;improvement&lt;/a&gt;, &lt;a href="http://technorati.com/tag/lean" rel="tag"&gt;lean&lt;/a&gt;, &lt;a href="http://technorati.com/tag/management" rel="tag"&gt;management&lt;/a&gt;, &lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://technorati.com/tag/team" rel="tag"&gt;team&lt;/a&gt;, &lt;a href="http://technorati.com/tag/planning" rel="tag"&gt;planning&lt;/a&gt;, &lt;a href="http://technorati.com/tag/tdd" rel="tag"&gt;tdd&lt;/a&gt;, &lt;a href="http://technorati.com/tag/bdd" rel="tag"&gt;bdd&lt;/a&gt;, &lt;a href="http://technorati.com/tag/testing" rel="tag"&gt;testing&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/610.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=jBY9QWr33iE:naH1UoPU22M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=jBY9QWr33iE:naH1UoPU22M:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=jBY9QWr33iE:naH1UoPU22M:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=jBY9QWr33iE:naH1UoPU22M:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=jBY9QWr33iE:naH1UoPU22M:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=jBY9QWr33iE:naH1UoPU22M:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=jBY9QWr33iE:naH1UoPU22M:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=jBY9QWr33iE:naH1UoPU22M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=jBY9QWr33iE:naH1UoPU22M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/jBY9QWr33iE" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/07/610.aspx</guid>
            <pubDate>Wed, 07 Oct 2009 15:17:05 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/07/610.aspx#feedback</comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/610.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/610.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/07/610.aspx</feedburner:origLink></item>
        <item>
            <title>How We Do Things - Planning Part 2</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/WEmpC2WoPrk/609.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;This content comes solely from my experience, study, and a lot of trial and error (mostly error). I make no claims stating that which works for me will work for you. As with all things, your mileage may vary, and you will need to apply all knowledge through the filter of your context in order to strain out the good parts for you. Also, feel free to call BS on anything I say. I write this as much for me to learn as for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is part 3 of the &lt;a href="http://scottcreynolds.com/archive/2009/10/04/605.aspx"&gt;How We Do Things&lt;/a&gt; series.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In the last post I talked about the various evolutions of planning the team has been through over the last few years. This post is about what we do now. Take a moment to read the last one to catch up on what the picture below is about.&lt;/p&gt;
&lt;h3&gt;The Planning Space-Time Continuum&lt;/h3&gt;
&lt;div style="text-align:center;"&gt;&lt;img src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scottcreynolds/planningtimeline.jpg" alt="planningtimeline.jpg" border="0" width="523" height="272" /&gt;&lt;/div&gt;
&lt;p&gt;The basic gist here is that as items move from right to left they become more well-known, more defined, and more likely to actually be worked on.&lt;/p&gt;
&lt;h3&gt;JIT Planning Next Work To Be Done&lt;/h3&gt;
&lt;p&gt;We've come to a point where we plan, basically, as much work as we need to plan to keep work in progress until the next time we want to plan. I'll try to make that a little less esoteric.&lt;/p&gt;
&lt;p&gt;We intend to plan a week's worth of work at a time, give or take. The acceptable threshold is typically anywhere between 3 days and 8. Usually this takes the form of planning just one or two minimal marketable features (MMFs - more on these in another post) depending on size. There's a lot of "feel" to this, and that feel stems from having established a pretty rhythmic workflow and from having same(ish)-sized stories (more on that in another post as well).&lt;/p&gt;
&lt;p&gt;Mechanically, the planning meeting looks like this: representative team members (usually myself, one or more BAs, the developers that will work on the MMFs, and a QA person) will get together and go through the stories that need to get worked on next. We'll do a story workshop of sorts where we flesh out details of acceptance criteria, surface any issues or further questions, actually plan out some tests, and determine if the stories are appropriately sized.&lt;/p&gt;
&lt;p&gt;If any questions or blocking issues come up at this time we will deal with them then and there by either talking them out, or if necessary tracking down the right people to answer the questions. If we can't get the answers right away we figure out if we can get started without them and trust that someone will have the answer by the time we get to that point. This will spin up a thread for a BA or myself to go track someone down in the lab or elsewhere in the organization, set up a meeting, and do that whole thing.&lt;/p&gt;
&lt;p&gt;This planning is unscheduled and happens as needed. If we are running low on work today, we'll schedule a planning meeting for tomorrow morning. They usually last no more than 30 minutes unless there's a lot of design discussion to be had.&lt;/p&gt;
&lt;h3&gt;Near-Term Planning - The Rolling Wave&lt;/h3&gt;
&lt;div style="text-align:center;"&gt;&lt;img src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scottcreynolds/rollingwave.jpg" alt="rollingwave.jpg" border="0" width="375" height="250" /&gt;&lt;/div&gt;
&lt;p&gt;The planning in the prior section is directly seeded by the planning done in this section. This is the next segment of the continuum to the right, and represents the picture of what we will probably be working on sometime in the next month.&lt;/p&gt;
&lt;p&gt;This stage of planning doesn't directly involve any developers or testers unless specific questions arise. At this point the BAs and I are sketching out the stories at a higher, not quite as detailed level, and stitching them together to form MMFs. We are figuring out what questions need to be asked and where these MMFs will fall in the slightly larger picture. Here is where we are evaluating priorities of features and roughly determining when they will be started. In short, we have about a month's worth of stories, give or take, in states somewhere between fine and coarse-grained detail, with priorities, and we're fairly confident that we will get to them in the next month. This is what a scrum team might call their product backlog.&lt;/p&gt;
&lt;p&gt;This planning happens on a schedule every Monday morning. We go through requests, evaluate them, evaluate work in progress, and determine which stories to add finer detail to and queue up for the next work planning session.&lt;/p&gt;
&lt;p&gt;This is a variation of &lt;a href="http://jrothman.com/blog/mpd/2004/05/rolling-wave-planning.html"&gt;Rolling Wave planning&lt;/a&gt; in that we don't necessarily keep the "wave" the same size at all times, and we don't make detailed work plans for the items in the wave. There's also no guarantee that items move linearly from the end of the wave toward the beginning as time passes, since we allow for priority shifts within this space. In some ways, it's more like a rolling cloud than a rolling wave, but I don't know if I'm qualified to make up a new project management term.&lt;/p&gt;
&lt;p&gt;Some weeks, like this week, we may not bring any new stories into the wave at all. We may sit down, go through the backlog, look at work in progress, evaluate current conditions, and determine that we don't need to spend any time adding more work to the wave. To me, this is perfectly acceptable in the spirit of eliminating waste. We aren't adding more inventory when we don't need it, and we aren't wasting motion defining things when there's no immediate requirement. Sometimes our wave can get as lean as to only have a week or two in it, and sometimes it can bloat up to 6 to 8 weeks. We use this wave as our buffer to adapt to changing conditions.&lt;/p&gt;
&lt;p&gt;There's a real chance that the work put into the wave last week will be superseded in priority by new work identified this week. We don't push that other work out just because the priority changed, we just insert the higher priority stuff where it belongs. This accounts for the occasional bloating of the wave, and we compensate by not adding to it next time.&lt;/p&gt;
&lt;p&gt;Sometimes there is no priority work to be brought into the wave, or no stories that we can get enough information on yet, so we just let it go for that week and let it shrink in size. If you'll pardon the metaphor, we let the size of this backlog ebb and flow fluidly.&lt;/p&gt;
&lt;p&gt;The picture of the wave at any given time allows us to make decisions about what work will be delayed if new priority work is identified, and we can share that easily with project stakeholders. Because we know that we're talking about a month or so of work, we are able to make statements about timelines of work that has been specified in enough detail and given enough priority to be in the wave. This makes external parties much happier.&lt;/p&gt;
&lt;h3&gt;The Roadmap&lt;/h3&gt;
&lt;div style="text-align:left;vertical-align:text-top;"&gt;&lt;img src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scottcreynolds/good_5F00_luck_5F00_sign.jpg" alt="good_luck_sign.jpg" border="0" width="180" height="250" style="float:left;padding: 3px;" /&gt;The sections farthest to the right are our next quarter/next year roadmap. This is where we would understand longer-running strategic initiatives or targets that we will ideally get to if, and only if, &lt;em&gt;current conditions remain the same.&lt;/em&gt; This includes items from both the corporate initiatives roadmap, and our internal project roadmap. This could be anything from "In Q4 we are likely going to introduce a new product line" to "we'd really like to replace our hand-rolled data access with NHibernate." We put this stuff on the roadmap to serve as the mile markers for where we (the organization, not just the developers) want to take our software.&lt;/div&gt;
&lt;p&gt;Some items on the roadmap will very likely get implemented, and we may know it well in advance, but their priority or maybe external dependencies aren't such that we could reliably be planning this work yet, so it goes out here to the right for the time being.&lt;/p&gt;
&lt;p&gt;Some of the items on the roadmap could very well never get implemented. These aren't just the "man it would be great if..." items, though those are on there. They are also the items that are totally valid, have strategic value, but somehow never seem to win the priority battle with other items. These are the items that usually end up becoming factors in the decision to increase staff or potentially purchase something.&lt;/p&gt;
&lt;p&gt;Or maybe they are items that get totally replaced by something better. As an example, we had a project out here in this space for almost two years. Everyone wanted to do it. The business was hyped on it. They kept asking when we could get to it, and kept insisting it was going to be a key part of our service offerings. However, it never could beat out other priorities. In two years it never once won a priority battle. Recently we uncovered a vendor that would provide us with a 90% solution that would take mere weeks to integrate, versus what was looking like a multi-month project. The original target came off the list, replaced by the new hotness.&lt;/p&gt;
&lt;p&gt;If we had spent any real time planning this project beyond a very basic understanding of its scope and keeping it as sort of an 'idea bucket' that work would have been completely wasted. As it stands, no harm no foul.&lt;/p&gt;
&lt;h3&gt;The Lie&lt;/h3&gt;
&lt;p&gt;The last part of the continuum I want to address is what we have affectionately dubbed "The Lie". This is the point past which any projections you make on time/cost/when/where/who/how something will get done may as well have come from a magic 8 ball. When asked for this type of long-long-range (usually this is somewhere in the neighborhood of 6 months from now for us) information, we play it straight up. We say "this is a lie. what we are about to say will not come true at all." For some reason we can get stakeholders to &lt;em&gt;accept and understand&lt;/em&gt; that it's a lie, but we cannot get them to &lt;em&gt;stop asking&lt;/em&gt; for the lie. It boggles the mind. But whatever. We're up front about it, and we refuse to be held to it. Part of effective planning is identifying the issues and constraints that will make the plan go astray, presenting those, and sticking to your guns when they happen.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;As a side note, I want to point out that these time thresholds we have come up with have been a moving target, and yours will differ based on the size of your team, how fast they work, the nature of your organization, and a ton of other factors. So just be prepared to experiment.&lt;/em&gt;&lt;/p&gt;
&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/how                   2e                   6o                   1t" rel="tag"&gt;how we do it&lt;/a&gt;, &lt;a href="http://technorati.com/tag/improvement" rel="tag"&gt;improvement&lt;/a&gt;, &lt;a href="http://technorati.com/tag/lean" rel="tag"&gt;lean&lt;/a&gt;, &lt;a href="http://technorati.com/tag/management" rel="tag"&gt;management&lt;/a&gt;, &lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://technorati.com/tag/team" rel="tag"&gt;team&lt;/a&gt;, &lt;a href="http://technorati.com/tag/planning" rel="tag"&gt;planning&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/609.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=WEmpC2WoPrk:Wy0dQNsciuk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=WEmpC2WoPrk:Wy0dQNsciuk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=WEmpC2WoPrk:Wy0dQNsciuk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=WEmpC2WoPrk:Wy0dQNsciuk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=WEmpC2WoPrk:Wy0dQNsciuk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=WEmpC2WoPrk:Wy0dQNsciuk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=WEmpC2WoPrk:Wy0dQNsciuk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=WEmpC2WoPrk:Wy0dQNsciuk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=WEmpC2WoPrk:Wy0dQNsciuk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/WEmpC2WoPrk" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/06/609.aspx</guid>
            <pubDate>Tue, 06 Oct 2009 05:11:28 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/06/609.aspx#feedback</comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/609.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/609.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/06/609.aspx</feedburner:origLink></item>
        <item>
            <title>Attribution and Analogy</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/xADxJctiTkc/608.aspx</link>
            <description>&lt;p&gt;Brief pause to correct and address a couple of things.&lt;/p&gt;
&lt;p&gt;In my post &lt;a href="http://www.lostechies.com/blogs/scottcreynolds/archive/2009/10/02/quit-living-in-the-past-practices-evolve.aspx"&gt;Quit Living in the Past - Practices Evolve&lt;/a&gt; I used an analogy about hand washing in hospitals. It was later brought to my attention that Uncle Bob used this analogy (though not in exactly the depth that I did) on both a Hanselminutes Podcast episode and in a blog post a few years ago. I can honestly say I hadn't listened to the podcast, and I may or may not have read the blog post, who knows? I did reply in my comments that it's quite possible that this analogy was floating around out there due to Uncle Bob or others, or I had seen it in passing on twitter, or picked it up in a blog somewhere, and that is why it occurred to me to use it. So, officially, my apologies to anyone who thinks I have stolen this analogy without attributing the source. It was unintentional at worst, and I hope you'll give me the benefit of the doubt on this one.&lt;/p&gt;
&lt;p&gt;In my post &lt;a href="http://www.lostechies.com/blogs/scottcreynolds/archive/2009/10/01/well-constructed-over-architected.aspx"&gt;Well-constructed != Over-architected&lt;/a&gt;, I opened with a story about a dog house. An anonymous commenter (since removed) accused me of stealing this one from Steve McConnell and pointed me to &lt;a href="http://www.codinghorror.com/blog/archives/000283.html"&gt;this&lt;/a&gt; CodingHorror post.&lt;/p&gt;
&lt;p&gt;1) I've never read the book Rapid Development. b) I don't read CodingHorror, and if I had this post is over 4 years old. iii) it isn't even the same analogy. Get over it.&lt;/p&gt;
&lt;p&gt;People wonder why sometimes I might treat some comments, particularly from those I don't know, as trolls. Frankly, it's because of crap like this. Analogies are analogies, and we shouldn't be expected to see if anyone has ever used a similar analogy &lt;em&gt;ever&lt;/em&gt; before putting one online. In the case of the handwashing one, I realize that it's awful similar and so like I said, my apologies for not attributing. It was an awareness thing. In the dog house case, well, give me a break. If you can't add to the conversation, don't post a comment on something so frivolous. And if you feel like you must point out something like this (and feel free, please, if it's valid, as is the handwashing analogy case) then don't be a dick about it, and even if you must be a jerk, at least have the courage to use your name.&lt;/p&gt;&lt;img src="http://scottcreynolds.com/aggbug/608.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=xADxJctiTkc:ZUoyS3msrfk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=xADxJctiTkc:ZUoyS3msrfk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=xADxJctiTkc:ZUoyS3msrfk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=xADxJctiTkc:ZUoyS3msrfk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=xADxJctiTkc:ZUoyS3msrfk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=xADxJctiTkc:ZUoyS3msrfk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=xADxJctiTkc:ZUoyS3msrfk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=xADxJctiTkc:ZUoyS3msrfk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=xADxJctiTkc:ZUoyS3msrfk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/xADxJctiTkc" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/05/608.aspx</guid>
            <pubDate>Mon, 05 Oct 2009 17:55:58 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/05/608.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/608.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/608.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/05/608.aspx</feedburner:origLink></item>
        <item>
            <title>How we do things - Evolving Our Planning Practice</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/d3b8c8iEf18/607.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;This content comes solely from my experience, study, and a lot of trial and error (mostly error). I make no claims stating that which works for me will work for you. As with all things, your mileage may vary, and you will need to apply all knowledge through the filter of your context in order to strain out the good parts for you. Also, feel free to call BS on anything I say. I write this as much for me to learn as for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is part 2 of the &lt;a href="http://scottcreynolds.com/archive/2009/10/04/605.aspx"&gt;How We Do Things&lt;/a&gt; series.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Planning is a key part of any software effort. It serves multiple purposes in an organization, from budgeting to work scheduling, and it's not always a science. We're going to talk about how we do planning on my team in two installments, starting with how our planning process has evolved over time, and moving into the mechanics of what we do in the next post.&lt;/p&gt;
&lt;h3&gt;How we used to plan&lt;/h3&gt;
&lt;p&gt;Stop me if you've heard this one before. At the start of our LIS project, we planned and defined the whole thing. We specified &lt;em&gt;everything&lt;/em&gt; to great detail, put it on a Gantt chart, and put it on the wall. Then we went to work and created something that didn't bear a lot of resemblance to the plan.&lt;/p&gt;
&lt;p&gt;When we finished we were almost 6 months off the Gantt chart's projected timeline. I didn't consider us late, because we weren't. Scope creep had set in, standard organizational delays, and over-optimistic and naïve estimates led to us creating a picture far in advance that didn't in any way represent reality.&lt;/p&gt;
&lt;p&gt;Planning in great detail far in advance of the work being done got us in trouble, and it allowed the perception that we were failing to set in. It created a morale problem on the team, put us under a ton of undue pressure, and made the project into a death-march of sorts.&lt;/p&gt;
&lt;p&gt;When all was said and done, we were hugely successful in delivering the project, and I would consider it a heroic effort given what we were up against. But while it was underway, having that detailed "plan" was a boat anchor attached to our necks.&lt;/p&gt;
&lt;p&gt;So we don't do that anymore.&lt;/p&gt;
&lt;h3&gt;Planning isn't all-or-nothing&lt;/h3&gt;
&lt;p&gt;Somewhere along the line someone decided that you had to plan an entire project, in detail, up front, for...some reason. I'm not sure what that reason is, to be honest, because after all this time we know that those plans usually end up falling down. If the reason is budgeting, you're going to be off. If the reason is resource allocation (hate that phrase) you're going to be off. If the reason is setting deadlines, you're likely going to be off. At the end of the day, if the project turns out to have mirrored the plan up front, well, you're either better at lying than I am, or you're a dark wizard and I wish to apprentice for you.&lt;/p&gt;
&lt;p&gt;When we continue to go through the motions of this huge up-front planning effort in the name of whatever gain we think comes from it, even though we know that at the end we will likely not have actually realized that gain, we are, simply, lying to ourselves and the organization. If we know that today's plan is next week's joke, why do we keep doing it this way? As the saying goes, the definition of insanity is repeating the same action expecting a different result.&lt;/p&gt;
&lt;h3&gt;The wastes of detailed advanced planning&lt;/h3&gt;
&lt;p&gt;We came to realize that there was a lot of waste associated with a lot of up-front detailed planning.&lt;/p&gt;
&lt;div style="text-align:center;"&gt;&lt;img src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scottcreynolds/inventory2.jpg" alt="inventory2.jpg" border="0" width="396" height="309" /&gt;&lt;/div&gt;
&lt;p&gt;The first waste is inventory. Carrying excess inventory is one of the &lt;a href="http://en.wikipedia.org/wiki/Muda_%28Japanese_term%29"&gt;seven primary wastes&lt;/a&gt; in lean manufacturing, and in our case, defined work that is not yet in progress is inventory.&lt;/p&gt;
&lt;p&gt;This inventory is wasteful because after this work has been done, any number of things can happen that will nullify that work. Changing requirements and changing priorities can have a big impact. When we change requirements or learn more about the needs of a pre-planned system, we end up throwing away a lot of that planned work and starting over. This happens all the time in our world, where certain things will simply not surface until well after we have identified a set of features, and trying too hard to get them all planned out beforehand leads to tossing those stories and starting over.&lt;/p&gt;
&lt;p&gt;Changing priorities leads to a different but equally wasteful problem in that we have planned the work, but priority shifts will ensure that the work continues to sit inert as inventory and that the organization is not realizing any value from the planning work done. In essence, we wasted our time putting a lot of detail on this work.&lt;/p&gt;
&lt;p&gt;Finally, there's the cognitive waste of having work planned and defined well in advance of development, and then losing scope of everything you had talked about by the time you actually get around to implementing. Basically, we were finding that anything we planned more than a month or so in advance of development led us to essentially repeat that planning work near the time of development in order to make sure we were still on the right page. This is an example of excessive motion, another waste identified by lean.&lt;/p&gt;
&lt;h3&gt;Baby Steps&lt;/h3&gt;
&lt;p&gt;As we migrated from a waterfall to a scrum approach, we started planning much smaller. We got to a point where we were doing detailed planning about a month in advance. Even this was too much, but it was a step in the right direction.&lt;/p&gt;
&lt;p&gt;We realized that we were never going to get to a point where the organization wouldn't throw new things at us on at any given moment, and we were never going to achieve the kind of workflow protection that scrum claims to offer (more about this when I get to the post about Kanban). Even planning in detail a month in advance was leading to the same wastes as before. Less of it, to be sure, but it was there. So, we made another change.&lt;/p&gt;
&lt;h3&gt;The other extreme&lt;/h3&gt;
&lt;p&gt;The next step in our evolution was to essentially throw planning out the door altogether.&lt;/p&gt;
&lt;p&gt;We decided if our plans were just going to go to waste anyway, that we would &lt;a href="http://en.wikipedia.org/wiki/Just-in-time_%28business%29"&gt;JIT&lt;/a&gt; every ounce of it. This meant no planning and no specs until it was time to work on them. We carried near-zero inventory of pre-planned work, and had no problem handling changing priorities.&lt;/p&gt;
&lt;p&gt;The problems with this approach became quickly evident though as we realized that we had basically no roadmap. We couldn't tell you what we were doing next week, let alone next month, with any confidence. As the organization started to do some long-term strategic planning, I was unable to provide any information about where these plans could fit into our workflow beyond "yeah we can work on that, but maybe some other stuff falls by the wayside, but I don't know what that stuff is." This is obviously an unacceptable situation.&lt;/p&gt;
&lt;p&gt;We needed a compromise that served our needs and the organization's.&lt;/p&gt;
&lt;h3&gt;The Space-Time Continuum of Project Planning&lt;/h3&gt;
&lt;p&gt;For us, planning is now broken up into three distinct parts: immediate, near-term, and long-term.&lt;/p&gt;&lt;div style="text-align:center;"&gt;&lt;img src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scottcreynolds/planningtimeline.jpg" alt="planningtimeline.jpg" border="0" width="523" height="272" /&gt;&lt;/div&gt;
&lt;p&gt;In the next part of this series I will talk about the mechanics of each segment, and how it fits together to form the whole.&lt;/p&gt;
&lt;p&gt;In general the idea is this: I can tell you with great detail and confidence what we are working on in the next few days. In the next month or so I have a pretty good idea of what's coming and the scope of the work, but it's not planned and specified in minute detail yet. In the upcoming quarter or so, I have a roadmap of things that we will get to &lt;strong&gt;&lt;em&gt;if current conditions and priorities remain the same.&lt;/em&gt;&lt;/strong&gt; Beyond that, we have a general idea of where the products should go and what initiatives may be on the horizon, but they are just a general idea, and we will not spend much time doing anything more than exploratory information gathering until we are past what we are doing now.&lt;/p&gt;
&lt;p&gt;On this continuum, the things to the right are very top-level and amorphous by design. There's a real chance that things far to the right will stay far to the right for the rest of time. Stuff closer to the left is viewed as "real work" and we will get to it soon, or may be working on it now. Maybe some things get inserted there along the way, but we have scope of what items they will move to the right.&lt;/p&gt;
&lt;p&gt;The stuff furthest to the right is not really affected by changes to the left because it's far enough away from the gravitational field of work in progress. It's like the stars at the edge of a galaxy, largely unaffected by the gravity of the black hole at the center, and held in place by the cumulative gravitational affect of millions of other stars.&lt;/p&gt;
&lt;p&gt;In this category we may have things like "we'd really like to put an iPhone app in play to interact with some service at some point". We keep track of the fact that that's a desire, but it's barely visible as a dull dot through a telescope. In our spare time we may dream about the form of these features, but no real work gets put into them. It's more of an idea bucket. At such time as the organization decides it's a strategic priority, however, it comes out of the cloud and moves into a place where we know we will be getting to it, and the planning process described in the next post begins.&lt;/p&gt;
&lt;p&gt;Next up we'll talk about how we do planning for each segment of the continuum. Stay tuned!&lt;/p&gt;


&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/how%20we%20do%20it" rel="tag"&gt;how we do it&lt;/a&gt;, &lt;a href="http://technorati.com/tag/improvement" rel="tag"&gt;improvement&lt;/a&gt;, &lt;a href="http://technorati.com/tag/lean" rel="tag"&gt;lean&lt;/a&gt;, &lt;a href="http://technorati.com/tag/management" rel="tag"&gt;management&lt;/a&gt;, &lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://technorati.com/tag/team" rel="tag"&gt;team&lt;/a&gt;, &lt;a href="http://technorati.com/tag/planning" rel="tag"&gt;planning&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/607.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=d3b8c8iEf18:7NU2P2Z8Yvw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=d3b8c8iEf18:7NU2P2Z8Yvw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=d3b8c8iEf18:7NU2P2Z8Yvw:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=d3b8c8iEf18:7NU2P2Z8Yvw:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=d3b8c8iEf18:7NU2P2Z8Yvw:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=d3b8c8iEf18:7NU2P2Z8Yvw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=d3b8c8iEf18:7NU2P2Z8Yvw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=d3b8c8iEf18:7NU2P2Z8Yvw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=d3b8c8iEf18:7NU2P2Z8Yvw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/d3b8c8iEf18" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/05/607.aspx</guid>
            <pubDate>Mon, 05 Oct 2009 14:33:54 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/05/607.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/607.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/607.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/05/607.aspx</feedburner:origLink></item>
        <item>
            <title>How We Do Things - Who we are, Where we were, Where we stand</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/Hu3obaBNk_o/606.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;This content comes solely from my experience, study, and a lot of trial and error (mostly error). I make no claims stating that which works for me will work for you. As with all things, your mileage may vary, and you will need to apply all knowledge through the filter of your context in order to strain out the good parts for you. Also, feel free to call BS on anything I say. I write this as much for me to learn as for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is part 1 of the &lt;a href="http://www.scottcreynolds.com/archive/2009/10/04/605.aspx"&gt;How We Do Things&lt;/a&gt; series.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Allow me to introduce our team. We are an IT development shop in a rapidly growing corporate laboratory. Our company functions as a lab (your doctor takes a biopsy, sends it to us for diagnosis) and as a laboratory services company. We are a sales-driven medical organization with priorities split between medical and patient care concerns and sales and corporate priorities (with the ever-annoying regulatory concerns mixed in for good measure). In my 5+ years here our volume in case load alone has grown over 2,000%, and we have steadily (or maybe exponentially) increased our number of product lines and service offerings to our client physicians. I don't take credit for all of this, but, our team has been an integral part in enabling this growth.&lt;/p&gt;
&lt;p&gt;When I started we had myself, our Director of IT, and a DBA/Report Specialist as the entire IT department. Now I have 8 developers, a DBA, a QA tester, and two Business Analysts in my department alone, and an equivalent number of network and support staff.&lt;/p&gt;
&lt;p&gt;My time here started with the goal of facilitating augmentation of our purchased Lab Information System (LIS). That turned into trying to buy a new one that would grow with us. An unsuccessful search there led to creating our own. The system we created has been called "the best in the industry" by our doctors and external parties. It has been in successful operation for almost 3 years, and is undergoing constant new development to facilitate new product lines and changing offerings, new and changing regulatory requirements, and the standard "wishlist enhancements" that come with any enterprise software. In addition to our LIS we provide data integrations with a large number of external systems, from state departments of health to commercial electronic medical records (EMR) packages. We also provide web-based tools for multiple levels of clients to interact with us. At present we are undergoing a massive effort to extend our software to support our growing services, but I can't go into much detail about that yet ;)&lt;/p&gt;
&lt;p&gt;Our LIS was designed in a waterfall-ish way, beginning in late 2004. We broke ground on code in late 2005. The entirety of the release version of the system was coded by myself and a junior programmer fresh out of high school. The suite of applications is composed of client applications for medical and lab personnel, sales support and client service users, IT users, billing users, and a slew of back-end services. In truth, lab management is probably only half of the picture, and it's a full-on enterprise application suite. Deployment consisted of the entire team being on-site at our lab facility 1500 miles from home for a month working 22 hour days on average. It was not fun times.&lt;/p&gt;
&lt;p&gt;To say I've learned a lot from the development of this system, and what has happened since, is an understatement. Since that time I've added a large number of staff, and found myself transitioning from developer to full-time manager. We have had to learn to accommodate rapidly changing priorities and capitalize on business opportunities in rapid-fire mode while maintaining a no-exceptions stance on quality and correctness. After all, we're dealing with people's lives.&lt;/p&gt;
&lt;p&gt;The LIS system was not built with TDD (and we pay for that every friggin day), and has a lot of technical debt that we deal with. We rolled our own data access for God's sake, and it's still there. We were not agile when we started. We worked hard, very hard, to earn every ounce of trust that the business has gained in our ability to deliver, and we've traded on that trust to implement the changes and improvements we've made along the way. Sometimes the path to improvement has been easy and obvious, and sometimes we've just had to say "trust us". Without establishing that trust first, without establishing that we are a team that can deliver value and is in tune with the organization as a whole, we wouldn't have been able to make the improvements we've made.&lt;/p&gt; 
&lt;p&gt;I can't stress this enough. An organization has no reason to trust you unless you earn that trust. And let's be honest, a lot of the practices I'm going to talk about, such as Pair Programming, non-traditional project management, and TDD, aren't sold on the numbers. They're sold on trust and post-practice verification.&lt;/p&gt;
&lt;p&gt;The team today is very different in form and function than it was five years ago. Apart from being larger, we operate as a lean software team utilizing kanban for workflow and just-in-time planning and design. We hold many XP practices dear that we've adopted along the way, including pair programming and TDD. We deliver continuously and we do so at extremely high quality. The story of how we got from there to here is the focus of this series. Come along for the ride.&lt;/p&gt;&lt;img src="http://scottcreynolds.com/aggbug/606.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=Hu3obaBNk_o:uy3eI1CGSLw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=Hu3obaBNk_o:uy3eI1CGSLw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=Hu3obaBNk_o:uy3eI1CGSLw:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=Hu3obaBNk_o:uy3eI1CGSLw:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=Hu3obaBNk_o:uy3eI1CGSLw:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=Hu3obaBNk_o:uy3eI1CGSLw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=Hu3obaBNk_o:uy3eI1CGSLw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=Hu3obaBNk_o:uy3eI1CGSLw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=Hu3obaBNk_o:uy3eI1CGSLw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/Hu3obaBNk_o" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/04/606.aspx</guid>
            <pubDate>Mon, 05 Oct 2009 03:16:23 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/04/606.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/606.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/606.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/04/606.aspx</feedburner:origLink></item>
        <item>
            <title>How We Do Things - Preamble and Contents</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/2yCrD5B_BLk/605.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;This content comes solely from my experience, study, and a lot of trial and error (mostly error). I make no claims stating that which works for me will work for you. As with all things, your mileage may vary, and you will need to apply all knowledge through the filter of your context in order to strain out the good parts for you. Also, feel free to call BS on anything I say. I write this as much for me to learn as for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So a bit ago I asked you, after getting a lot of questions at talks I give, if you thought there would be value in me laying out how our team gets things done.&lt;/p&gt;
&lt;p&gt;After hearing a lot of positive feedback on the idea, it's time to start getting the content out there.&lt;/p&gt;
&lt;p&gt;I intend to "open the kimono" on how my team operates, from planning to production, and talk about how we got to where we are, lessons we've learned, mistakes we've made, and improvements we are pursuing.&lt;/p&gt;
&lt;p&gt;I hope this series will provide two outcomes. The first is to illustrate ways to improve a team over time, and the second, and maybe more important, is to spawn conversations where you guys will us to improve even more.&lt;/p&gt;
&lt;p&gt;I'll be attaching the disclaimer above to every post. I want to make perfectly clear that this is all anecdotal, and is illustrative, not prescriptive. It is not my way or the highway, and at no point will my intent to be to tell anyone to do things exactly as I have done, so please don't act like that's the case.&lt;/p&gt;
&lt;p&gt;I would absolutely love constructive debate on any of the items, because it will only help me solidify and hopefully improve the way I do things. I would love to hear how you guys do things too, because I think the cumulative content will be very helpful to the community.&lt;/p&gt;
&lt;p&gt;I'd also like to take this opportunity to call on my fellow bloggers (both at Los Techies and elsewhere) to share what they can in the same vein. It's great to spout off on this ideal or that, but I think we lack a lot of good information out there about what we are doing in the real world. Maybe I'm just being idealistic, but I think this sort of thing can add a lot of context to discussions about how to craft software.&lt;/p&gt;
&lt;p&gt;I'm going to be calling on a couple of my teammates to do some guest posting here, and I can't promise a new post every day, but I will complete the series.&lt;/p&gt;
&lt;p&gt;Topics to be covered: (will serve as a table of contents)
&lt;/p&gt;&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.scottcreynolds.com/archive/2009/10/04/606.aspx"&gt;Introduction to our team, and where we came from.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://scottcreynolds.com/archive/2009/10/05/607.aspx"&gt;Evolving our Planning Practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.scottcreynolds.com/archive/2009/10/06/609.aspx"&gt;How we do planning today&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.scottcreynolds.com/archive/2009/10/07/610.aspx"&gt;Evolving our TDD/BDD Practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://scottcreynolds.com/archive/2009/10/11/611.aspx"&gt;Testing Part 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Specification&lt;/li&gt;
&lt;li&gt;Team Room&lt;/li&gt;
&lt;li&gt;Pair Programming&lt;/li&gt;
&lt;li&gt;Communication, Retrospectives, and Solving Problems&lt;/li&gt;
&lt;li&gt;Deciding what technology to use&lt;/li&gt;
&lt;li&gt;Building Quality In&lt;/li&gt;
&lt;li&gt;Kanban&lt;/li&gt;
&lt;li&gt;Roles, Responsibilities, and our "One Team" Philosophy&lt;/li&gt;
&lt;li&gt;Continued Learning and Personal Improvement&lt;/li&gt;
&lt;li&gt;Team Mentoring&lt;/li&gt;
&lt;li&gt;Demos&lt;/li&gt;
&lt;li&gt;Reducing Technical Debt and Cleaning up Messes&lt;/li&gt;
&lt;li&gt;How we define "done"&lt;/li&gt;
&lt;li&gt;My role on the team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each section will talk about where we started, where we are, and the steps we took to get there. In addition, I will be providing information where I can about how we "sold" certain practices to management, and how we reconcile our practices with the sometimes opposing views of executive staff.&lt;/p&gt;
&lt;p&gt;If you have any specific questions on any of the topics, or would like to propose others, please leave comments and I'll see if I can work them in.&lt;/p&gt;
&lt;p&gt;Hope you enjoy!&lt;/p&gt;

&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/improvement" rel="tag"&gt;improvement&lt;/a&gt;, &lt;a href="http://technorati.com/tag/management" rel="tag"&gt;management&lt;/a&gt;, &lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/team" rel="tag"&gt;team&lt;/a&gt;, &lt;a href="http://technorati.com/tag/how%20we%20do%20it" rel="tag"&gt;how we do it&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/605.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=2yCrD5B_BLk:Q6P5DUssd48:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=2yCrD5B_BLk:Q6P5DUssd48:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=2yCrD5B_BLk:Q6P5DUssd48:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=2yCrD5B_BLk:Q6P5DUssd48:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=2yCrD5B_BLk:Q6P5DUssd48:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=2yCrD5B_BLk:Q6P5DUssd48:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=2yCrD5B_BLk:Q6P5DUssd48:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=2yCrD5B_BLk:Q6P5DUssd48:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=2yCrD5B_BLk:Q6P5DUssd48:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/2yCrD5B_BLk" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/04/605.aspx</guid>
            <pubDate>Mon, 05 Oct 2009 02:42:56 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/04/605.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/605.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/605.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/04/605.aspx</feedburner:origLink></item>
        <item>
            <title>Quit Living In The Past - Practices Evolve</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/ZynACVYXkMI/604.aspx</link>
            <description>&lt;p&gt;In 1846 it wasn't a required practice for medical professionals to wash their hands or equipment when treating a patient. In 1847, &lt;a href="http://en.wikipedia.org/wiki/Ignaz_Semmelweis"&gt;Ignaz Semmelweis&lt;/a&gt; experimented and discovered that incidences of maternal death from Puerperal fever at Vienna General Hospital were drastically reduced simply by requiring midwife ward staff to wash their hands.&lt;/p&gt;
&lt;p&gt;Despite showing data that mortality rates under his watch at his hospital rapidly fell off after instituting this new practice, his theories were not widely accepted until well after his death when Louis Pasteur confirmed the &lt;a href="http://en.wikipedia.org/wiki/Germ_theory_of_disease"&gt;germ theory of disease.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What does this have to do with software? Well, I have to wonder why we are so filled with hubris as to think that we are not subject, as a profession, to the same evolutionary improvement steps of &lt;em&gt;every other profession in existence.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In a &lt;a href="http://www.lostechies.com/blogs/scottcreynolds/archive/2009/09/29/smart-and-gets-things-done-right.aspx"&gt;previous post&lt;/a&gt;, a commenter said: &lt;/p&gt;&lt;blockquote&gt;There is bucketloads of software out there designed by good coders who didn't follow every tenent [sic] of the Alt.NET manifesto, yet their code works just fine.&lt;/blockquote&gt;On the same post, another commenter says: &lt;blockquote&gt;Some people without a lot of credibility to back them up like to talk about quality and maintainability and simply ignore the history of software development.&lt;/blockquote&gt;Another "gem": &lt;blockquote&gt;Although the numbers are changing, the VAST majority of successful, well-written software wasn't developed using TDD.&lt;/blockquote&gt;
&lt;p&gt;These comments pretty fairly represent things I hear an awful lot out of some community segments, and it boils down to "I don't need to learn or apply [x] because we've been getting things done without it."&lt;/p&gt;
&lt;p&gt;&lt;em&gt;...well written software wasn't developed using TDD&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;How well-written was it? What is your definition of well-written? Is it maintainable? Did it handle load and scale? After 3 years of production did it cost more to make a change than that change would realize in revenue? Did it result in the dreaded ground-up rewrite because the developers who came later threw up their hands in despair? I'm sorry, but unless you are privy to the codebase you really can't claim that it was well written. So stop saying it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;...yet their code works just fine.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Does it? Is that good enough? Is the bar so low that "works just fine" is what we're aiming for here? And what is "works just fine" anyway? What is the metric by which you understand this statement? &lt;strong&gt;Is correct program execution the ultimate measure of success of a piece of software, or is it the bare minimum we are willing to accept?&lt;/strong&gt; This is a key question, and your answer to it will go a long way in revealing your philosophy about software construction.&lt;/p&gt;
&lt;p&gt;Prior to 1847, babies were being born without the handwashing. Yeah, sometimes the mothers died, but the babies were getting born. Isn't that the desired outcome of childbirth? If it were a software program, would we say that it "works just fine"?&lt;/p&gt;
&lt;p&gt;Just because we have done things one way and had some success does not mean that new and improved techniques have no value. And just because we can't mathematically prove that a practice or methodology will work at all times for all projects doesn't mean that the evidence present from our own experimentation has no merit.&lt;/p&gt;
&lt;p&gt;In my &lt;a href="http://www.lostechies.com/blogs/scottcreynolds/archive/2009/10/01/well-constructed-over-architected.aspx"&gt;previous post&lt;/a&gt;, I said that I believe that certain practices have a lot of value and can lead to major improvements in the way I construct software. I believe this because I have taken the time and made the genuine effort to experiment and measure results. If you have not done so, then your opinion on the matter is irrelevant.&lt;/p&gt;
&lt;p&gt;I also said that I don't use every tool or practice in the toolbelt on every project because the payoff isn't always worth the effort. I don't know anyone out there who is saying in such black and white terms that every practice touted by "alt.net" (and ps, people claiming that all of the things talked about in alt.net originated with alt.net are betraying their very narrow scope of understanding of what's happening in the programming world at large) need be applied in every situation.&lt;/p&gt;
&lt;p&gt;But since my credibility on these matters has been called into question, let's talk about some highly credible people in the community. Have you ever heard &lt;a href="http://www.udidahan.com/"&gt;Udi&lt;/a&gt;, or &lt;a href="http://www.lostechies.com/blogs/chris_patterson/default.aspx"&gt;Chris Patterson&lt;/a&gt;, or &lt;a href="http://codebetter.com/blogs/dru.sellers/default.aspx"&gt;Dru Sellers&lt;/a&gt; say that every application must be SOA and have a message bus? No, but they can still talk about the benefits these architectures bring. Have you ever heard &lt;a href="http://ayende.com/"&gt;Oren&lt;/a&gt; say that every application must use NHibernate? Have you ever heard &lt;a href="http://codebetter.com/blogs/gregyoung/default.aspx"&gt;Greg&lt;/a&gt; or &lt;a href="http://codebetter.com/blogs/david_laribee/default.aspx"&gt;Dave&lt;/a&gt; say that every problem must be solved with a strict interpretation of the DDD bible? No. Everyone who practices these things and uses these tools and credibly talks about their benefits understands that there is context in play on every project.&lt;/p&gt;
&lt;p&gt;If you insist on dismissing anything someone recommends because they don't have the data to prove beyond a shadow of a doubt that a given practice is globally applicable and will result in improved outcomes in all cases, then I will insist on dismissing you unless you have the data to prove the opposite. And I'm sorry kids, but "plenty of software was built without [some practice]" just doesn't cut it as proof, so kindly take that argument elsewhere.&lt;/p&gt;
&lt;p&gt;I'll come right out and say it, if you have no interest in improving what you do, and are fully content to maintain the status quo and shoot down every idea that can't be mathematically proven to be globally applicable, you are lazy, unprofessional, and have no place in this business.&lt;/p&gt;
&lt;p&gt;Nobody is ignoring the history of software. In fact, when we strive to achieve better practices and methodologies, we are doing so with that historical context in mind and trying to &lt;em&gt;improve&lt;/em&gt; over past outcomes. Just like hand washing in the delivery room, some of us are out there saying "we can do this better, and because we're ostensibly professionals, we intend to try."&lt;/p&gt;
&lt;p&gt;&lt;em&gt;n.b. any comment that clearly indicates someone hasn't taken the time to read or understand the post will be removed. Troll elsewhere.&lt;/em&gt;&lt;/p&gt;


&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/community" rel="tag"&gt;community&lt;/a&gt;, &lt;a href="http://technorati.com/tag/craftsmanship" rel="tag"&gt;craftsmanship&lt;/a&gt;, &lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/rant" rel="tag"&gt;rant&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software%20writing" rel="tag"&gt;software writing&lt;/a&gt;, &lt;a href="http://technorati.com/tag/improvement" rel="tag"&gt;improvement&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/604.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=ZynACVYXkMI:zMXRd5XaDz8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=ZynACVYXkMI:zMXRd5XaDz8:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=ZynACVYXkMI:zMXRd5XaDz8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=ZynACVYXkMI:zMXRd5XaDz8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=ZynACVYXkMI:zMXRd5XaDz8:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=ZynACVYXkMI:zMXRd5XaDz8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=ZynACVYXkMI:zMXRd5XaDz8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=ZynACVYXkMI:zMXRd5XaDz8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=ZynACVYXkMI:zMXRd5XaDz8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/ZynACVYXkMI" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/02/604.aspx</guid>
            <pubDate>Fri, 02 Oct 2009 14:12:23 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/02/604.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/604.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/604.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/02/604.aspx</feedburner:origLink></item>
        <item>
            <title>Well-constructed != Over-architected</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/LPamoDjJawg/603.aspx</link>
            <description>&lt;p&gt;Let's imagine for a moment that we're building a dog house for our beloved family pet. We want it to protect Rover from the elements, be a comfortable place for him to escape the sun and relax, and in general, have the structure hold up for quite some time.&lt;/p&gt;
&lt;p&gt;We are probably going to select decent wood, rather than scraps. We'll probably frame it out, make sure it's sturdy, make sure the joints are secure, that it has a solid base, and that the roof is well put together. We're probably going to plan it out, draw it up, and do the measurements to make sure Rover fits inside. If we aren't that good at carpentry, we may grab a book or two and follow the recommendations of people more practiced than us. Sure, we can hammer nails, but we don't necessarily know whether a miter joint is more appropriate than a dovetail joint in this case. We're not just going to slap it together with glue and tacks, leaving gaps between boards, and not being too concerned if it skews in a strong wind. In short, we're going to build a shelter that we're happy to put a loved one in.&lt;/p&gt;
&lt;p&gt;We aren't going to support the walls with flying buttresses to future-proof the structure. We aren't going to build it with steel girders. We aren't going to turn it into the &lt;a href="http://www.winchestermysteryhouse.com/"&gt;Winchester House&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There's a difference between well-constructed and over-architected.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There's an epidemic of misinformed opinion going around that adhering to commonly accepted good coding practices is synonymous with being an "architecture astronaut". That somehow someone who insists on applying SOLID and other principles to their code is more likely to inappropriately "solve" simple problems with too much complexity. This is simply not the case, and in my experience, the opposite is usually true.&lt;/p&gt;
&lt;p&gt;If I have a simple one-off forms over data application to deliver in a short time it's very unlikely that I'm going to spend a lot of time applying everything I ever read about DDD to the problem, and put a message bus behind it, put NHibernate under it, and implement some extensibility framework ahead of time just in case.&lt;/p&gt;
&lt;p&gt;I will, however, write the code to adhere to the Single Responsibility Principle, and I will employ Dependency Inversion, and I probably won't have many Law of Demeter violations. And I'll probably, but maybe not always, design it with TDD. Why? Because my experience leads me to understand that these are good things. They help ensure that this simple app is going to be understandable and readable in 6 months when I have to add a feature or fix a bug. And they're internalized. It's the way I code now. It's no faster or slower than not employing SOLID principles because that's a useless comparison at this point. I'm unlikely to &lt;em&gt;not&lt;/em&gt; employ these techniques because it's how I write code.&lt;/p&gt;
&lt;p&gt;I believe that IoC containers are powerful tools. Every application I've written in the last couple of years does not, however, employ an IoC tool. Each of them does, however, make use of dependency inversion internally because that's a good way to construct your classes.&lt;/p&gt;
&lt;p&gt;I believe ORMs are powerful and useful tools. I do not, however, have a single application in production today that uses NHibernate (ok, it's out, I'm the only alt.net guy not using NHibernate in production). I do, however, typically abstract data access away from the rest of the application as a natural result of applying SRP.&lt;/p&gt;
&lt;p&gt;I believe that DDD is a very powerful design philosophy, and that DDD as a concept is composed of many useful parts, not just the patterns. Every application I have in production does not, however, have a complex domain model, and a layer of application and domain services, and a slew of repositories, and explicit aggregates with roots and so on. &lt;/p&gt;
&lt;p&gt;I do, however, always think about my domain even if it's an ActiveRecord type implementation, because it helps make sure I'm modeling the appropriate concepts. And I do always think about and build a lexicon for ubiquitous language for a project because it enhances communication and clarity. And I do think about what my bounded contexts are because it helps me understand the nature of the system.&lt;/p&gt;
&lt;p&gt;Irrespective of the complexity of code to be written or the time allotted to write it, I always strive to make sure my code is readable, and that my APIs are intention-revealing. This isn't about geeking out on code structure, this is about putting something together that someone else on your team can understand. There's no time tradeoff to be made here, nor is there a complexity one. It's just part of constructing your software well.&lt;/p&gt;
&lt;p&gt;Nobody ever said that building software well meant employing every tool and technique in the alt.net toolbelt every time, so I don't know why people insist on acting like that's being said. These arguments about not having enough time to "do it right" or not wanting to overcomplicate "simple" solutions usually come from a position of either ignorance or fear.&lt;/p&gt;
&lt;p&gt;Constructing something well means simply constructing something well. Have the professionalism to do so.&lt;/p&gt;


&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software%20writing" rel="tag"&gt;software writing&lt;/a&gt;, &lt;a href="http://technorati.com/tag/craftsmanship" rel="tag"&gt;craftsmanship&lt;/a&gt;, &lt;a href="http://technorati.com/tag/SOLID" rel="tag"&gt;SOLID&lt;/a&gt;, &lt;a href="http://technorati.com/tag/DDD" rel="tag"&gt;DDD&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/603.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=LPamoDjJawg:866Xwwrge_I:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=LPamoDjJawg:866Xwwrge_I:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=LPamoDjJawg:866Xwwrge_I:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=LPamoDjJawg:866Xwwrge_I:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=LPamoDjJawg:866Xwwrge_I:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=LPamoDjJawg:866Xwwrge_I:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=LPamoDjJawg:866Xwwrge_I:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=LPamoDjJawg:866Xwwrge_I:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=LPamoDjJawg:866Xwwrge_I:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/LPamoDjJawg" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/10/01/603.aspx</guid>
            <pubDate>Thu, 01 Oct 2009 06:29:08 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/10/01/603.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/603.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/603.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/10/01/603.aspx</feedburner:origLink></item>
        <item>
            <title>Choose My Adventure</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/BXclGaSaOCo/602.aspx</link>
            <description>&lt;p&gt;Earlier tonight I had a &lt;a href="http://twitter.com/scottcreynolds/status/4484869402"&gt;fleeting thought&lt;/a&gt; about crowdsourcing my decision-making via twitter. Several people chimed in pretty quickly, and before I knew it, a concrete idea was formed.&lt;/p&gt;
&lt;p&gt;An experiment was born. One in which I would post my life's control-flow logic on twitter and let people make my decisions. &lt;a href="http://twitter.com/decideforscott/status/4486477991"&gt;The trial run&lt;/a&gt; resulted in a very tasty bacon, egg, and cheese sandwich. Shortly after it was decided I would make a blog post rather than play video games. Simple stuff, but, it was fun and interesting to do.&lt;/p&gt;
&lt;p&gt;Almost right away I discovered the ways in which people will branch the decision further, and that the answers aren't binary. The bacon suggestion came from what was essentially intended to be a yes/no question. On the blog/video game question, people not only chose blogging, but they suggested topics. I had to do quick math to determine if any topic got a majority before I followed through on the decision made for me.&lt;/p&gt;
&lt;p&gt;Like I said, it was fun.&lt;/p&gt;
&lt;p&gt;I've decided I'm going to keep the experiment up for a little while. I created &lt;a href="http://twitter.com/decideforscott/"&gt;a new twitter account (@decideforscott)&lt;/a&gt; that you can follow if you want to join in and choose my adventure for me.&lt;/p&gt;
&lt;p&gt;The rules are simple:
&lt;/p&gt;&lt;ul&gt;
	&lt;li&gt;I pose a question, you answer it with an @reply&lt;/li&gt;
&lt;li&gt;After a reasonable time has passed (variant on the urgency of the decision) I will take the most popular response and act on it. This means that maybe after 10 minutes I'm adding up votes, or, maybe the first response is the one I go with in the interest of time.&lt;/li&gt;
&lt;li&gt;I will post the results of both the poll, and my subsequent action.&lt;/li&gt;
&lt;/ul&gt;
And that's basically it. Some decisions will be boring. Some will be fun. Some will be major. Some will be very minor. Participate or don't at your leisure, the law of two feet applies for sure.

&lt;p&gt;Why am I doing this? I dunno. It's a lark mostly. A bit of an experiment. Maybe a little bit of narcissism, and probably at least a touch of trying to open my mind as I prepare to make some major changes in my life (more on that soon). But mostly, it was a wacky idea that I decided to follow for a little while.  Thanks for playing along.	 &lt;/p&gt;

&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/random" rel="tag"&gt;random&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/602.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=BXclGaSaOCo:6N1LNrRfPX4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=BXclGaSaOCo:6N1LNrRfPX4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=BXclGaSaOCo:6N1LNrRfPX4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=BXclGaSaOCo:6N1LNrRfPX4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=BXclGaSaOCo:6N1LNrRfPX4:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=BXclGaSaOCo:6N1LNrRfPX4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=BXclGaSaOCo:6N1LNrRfPX4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=BXclGaSaOCo:6N1LNrRfPX4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=BXclGaSaOCo:6N1LNrRfPX4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/BXclGaSaOCo" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/09/30/602.aspx</guid>
            <pubDate>Wed, 30 Sep 2009 05:32:26 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/09/30/602.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/602.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/602.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/09/30/602.aspx</feedburner:origLink></item>
        <item>
            <title>Smart and gets things done *right*</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/V43yIiFIkc8/601.aspx</link>
            <description>&lt;p&gt;I suppose it's time for the obligatory weigh-in on the latest bit o' reckless software advice from Joel Spolsky on the merits of the "Duct Tape Programmer".
&lt;/p&gt;
&lt;p&gt;
I think being a duct tape programmer is a bit like being an alcoholic. Once you become one, you are one, and when you want to stop, you have to constantly be vigilant against backsliding. Oh, and the first step is admitting you have a problem.
&lt;/p&gt;
&lt;p&gt;
Hi, I'm Scott, and I'm a recovering duct tape programmer.
&lt;/p&gt;
&lt;p&gt;I don't want to get too deep in the weeds on Joel's article, because the simple fact is that it doesn't warrant as much discussion as it's getting. On further review, he doesn't say much more than "be like this and get things done, but, you're probably not smart enough to be like this, so...". I will be pulling out a few key parts of his article to make my points however.&lt;/p&gt;
&lt;p&gt;What I do want to talk about is this notion that somehow being a craftsman and striving for appropriate, maintainable, and dare I say elegant solutions is in opposition of getting things done.&lt;/p&gt;
&lt;p&gt;There's a major problem in this industry (and the sub-industry of blogging/speaking/writing about this industry) of trying to remove contextual analysis from what we say. When we do that we get ourselves in trouble. Every product is different, every organization is different, and the needs of each varies wildly. Therefore it's impossible to prescribe one action over another free of context. The second side of that same coin is that the vast majority of people taking this sort of context free advice don't recognize this lack of context and run with it because some hero they worship said it. Then you get people that say things like "I don't want to write tests because Jeff Atwood and Joel Spolsky don't" or "I just want to code all night in a cave and 'get shit done' because that's what Joel said is valuable to business". This is a major problem.&lt;/p&gt;
&lt;p&gt;There's also this problem of the definition of "quality" in software. Some people tend to take a narrow view that the software quality issue is about patterns and clean code. This is part of it to be sure, but it's not the whole thing. Quality is part of solving the problem. Solving the right problem, with the right solution, that works for the business, in an amount of time that ensures value was provided, that's part of quality. Ensuring that the code is at the very least *correct* is also part of quality. Ensuring that code is maintainable can also be part of quality. Each of these parts of quality has a cost associated with it, and business decisions have to be made about the ROI tradeoffs associated. The problem is the business rarely makes the decisions, because the developers either don't care to raise the issue and educate, or don't want to.&lt;/p&gt;
&lt;p&gt;Joel's hero of the day was Jamie Zawinski, one of the original developers at Netscape. He stands him up as a bastion of getting things done, and I won't begin to deny Jamie's talent. But I do want to break down the straw men set up by Joel and add some context.&lt;/p&gt;
&lt;h3&gt;Just what is "important code"?&lt;/h3&gt;
&lt;blockquote&gt;Remember, before you freak out, that Zawinski was at Netscape when they were changing the world. They thought that they only had a few months before someone else came along and ate their lunch. A lot of important code is like that.&lt;/blockquote&gt;
&lt;p&gt;Yes, that was back in the glory wild west days of the internet and in the formative years of what the software industry has become. And yes, a lot of people are under the gun to get something to market before their funding runs out or someone bypasses them. But let's be real. The vast majority of software development out there is on the more "mundane" systems...you know...the ones that run the world, rather than the fancy Web 2.0 products. Do you want a duct tape programmer writing the software that controls your bank, or the lab equipment processing your mother's biopsy, or your insurance company's claims system or the air traffic control systems? I don't know the numbers, but I'm willing to bet that more people working in corporate IT on systems that have real impact on lives read Joel's blog than do people like Jamie. Just a guess.&lt;/p&gt;
&lt;p&gt;For me, the code running my bank is more important code than web browser code. Calling it "important code" is a huge red flag for me of the developer/geek bias in Joel's opinions. Important in this case means approximately "cool and new". My definition of important code makes me afraid that the people who write such code will follow Joel's advice.&lt;/p&gt;
&lt;h3&gt;Ship It!&lt;/h3&gt;
&lt;blockquote&gt;“Yeah,” he says, “At the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point—you’re not here to write code; you’re here to ship products.”&lt;/blockquote&gt;
&lt;p&gt;Yes, you're here to ship. I don't think that's a question in anyone's mind. But let's talk about the meat of this quote. The assumption here is that the developers of the non-duct-tape variety are focused on "pretty" code. Coupled with other sentiments in the article, it would seem that Joel (and Jamie) is saying that a testing practice and the idea of putting together a readable, maintainable codebase is the enemy of getting things done. This isn't a binary issue. Being for a maintainable codebase doesn't mean being against shipping. Being for code quality doesn't mean being for cleverness or complexity for the sake of cool (quite often it means the opposite).&lt;/p&gt;
&lt;p&gt; Again, this statement lacks the analysis of the context of different project and organization needs. If you're trying to produce the world's first web browser then yeah, get it out there and get it done. If you're trying to produce a long-lasting insurance claims application that will be the backbone of a corporation's business, then maintainability should probably be on your radar. Again, include the business in the decision making process. You shouldn't go off on your own in either direction, sacrificing quality for speed or vice-versa.&lt;/p&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;blockquote&gt;Zawinski didn’t do many unit tests. They “sound great in principle. Given a leisurely development pace, that’s certainly the way to go.&lt;/blockquote&gt;
&lt;p&gt;Now this is just crap, and it assumes and perpetuates the flawed idea that a mature testing practice costs you time. Yes, I said mature. Getting started on TDD &lt;em&gt;will&lt;/em&gt; be slow at first, but the payoff is huge. And let's not forget that time to market is total time to market, not just time to code features. Those features have to be implemented and tested before release (hopefully), and a practice that eschews testing for the sake of speed is often going to result in costly rework that will cost time ultimately. Again, context being what it is, I'm not saying that you can't do quality work and avoid rework with no testing, but what I am saying is that you also can't say that testing is only for those with "a leisurely development pace". My team cranks out features at an alarming rate sometimes, and manages to do so while practicing TDD and testing all the way up and down the stack.&lt;/p&gt;
&lt;p&gt;The point I'm getting at here is that we need to evaluate each project on its own merits and decide the practices that are appropriate to produce the value needed in the time required, and that we absolutely have to be careful about tossing around potentially harmful advice to our large audiences that will likely lead to some really crappy software being produced. Matt Hinze said it best when &lt;a href="http://twitter.com/mhinze/status/4341230362"&gt;he said&lt;/a&gt; "...never take software advice from a bug tracking system salesman".&lt;/p&gt;
&lt;p&gt;Oh and let's not forget how bad Netscape's browser ultimately became, and what a bloated piece of garbage it was by the time it died. Guess all that duct tape caught up with them.&lt;/p&gt;

&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://technorati.com/tag/tdd" rel="tag"&gt;tdd&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software%20writing" rel="tag"&gt;software writing&lt;/a&gt;, &lt;a href="http://technorati.com/tag/rant" rel="tag"&gt;rant&lt;/a&gt;, &lt;a href="http://technorati.com/tag/quality" rel="tag"&gt;quality&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/601.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=V43yIiFIkc8:phnj_7opzM4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=V43yIiFIkc8:phnj_7opzM4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=V43yIiFIkc8:phnj_7opzM4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=V43yIiFIkc8:phnj_7opzM4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=V43yIiFIkc8:phnj_7opzM4:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=V43yIiFIkc8:phnj_7opzM4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=V43yIiFIkc8:phnj_7opzM4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=V43yIiFIkc8:phnj_7opzM4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=V43yIiFIkc8:phnj_7opzM4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/V43yIiFIkc8" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/09/29/601.aspx</guid>
            <pubDate>Wed, 30 Sep 2009 02:56:40 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/09/29/601.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/601.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/601.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/09/29/601.aspx</feedburner:origLink></item>
        <item>
            <title>Would you like to know how I do things?</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/4MtY3oewRRs/600.aspx</link>
            <description>&lt;p&gt;Over the years, as I speak to other developers, or give presentations at events, I always end up with a lot of questions about "How do you...[x]?"&lt;/p&gt;
&lt;p&gt;It occurs to me that there's an awful lot of information out there about the ideal ways to do things, or about how things should be done, or even personal stories about how things are done, but there's not a ton of people out there saying "This is how all this stuff works on my team, end to end, top to bottom"&lt;/p&gt;
&lt;p&gt;Further, there always seems to be a focus on what we're doing *now* with a lack of the context of how we got here and how we plan to go forward. This is how I do planning today. This is how I do testing today. This is how we do pairing today. The big questions from those that want to look at implementing these things are always in the form of "Ok, but how did you get there? How did you sell it to management? How did you get your team to buy in?"&lt;/p&gt;
&lt;p&gt;Last year at KaizenConf the Dovetail team led by &lt;a href="http://www.lostechies.com/blogs/chad_myers/default.aspx"&gt;Chad&lt;/a&gt; and &lt;a href="http://codebetter.com/blogs/jeremy.miller/default.aspx"&gt;Jeremy&lt;/a&gt; did a workshop that they called, tongue-in-cheek, "Opening the Kimono", in which they talked about how they are doing things with MVC at Dovetail, how they came to the decisions they came to, and how they have evolved what they are doing. They opened Visual Studio and showed their actual code. They walked through their process. It was, in its own way, beautiful, and it was a wildly popular session.&lt;/p&gt;
&lt;p&gt;So I've gotten enough questions from enough people about how my team works, and how it got to where it is, that I think maybe it's time that I open the kimono a bit and share.&lt;/p&gt;
&lt;p&gt;The question to you, dear reader, is would this interest you? Would you like to know things like how we handle quality, how we implemented pairing, how we plan work, in short, how we run the team and build software?&lt;/p&gt;
&lt;p&gt;Now the caveat here is that I'm just one guy, doing things on one team, in one company. My way is not going to be the way that works for everyone, and I'm willing to accept that I do a lot of stuff *wrong*. Hell, I know I do, because I have ample areas in which I can improve. But if real descriptions of how I do things and the journey to get there will be helpful to the community, then I'm willing to lay it bare.&lt;/p&gt;
&lt;p&gt;So, if this interests you, leave a comment, or send an email, or hit me on &lt;a href="http://twitter.com/scottcreynolds"&gt;Twitter&lt;/a&gt;, and let me know. If you have specific things you'd like to see me address, include them. If you think this would have no value, then let me know that too. I'd hate to engage in so much navel gazing if nobody will get anything from it.&lt;/p&gt;

&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/community" rel="tag"&gt;community&lt;/a&gt;, &lt;a href="http://technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://technorati.com/tag/team" rel="tag"&gt;team&lt;/a&gt;, &lt;a href="http://technorati.com/tag/management" rel="tag"&gt;management&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/600.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=4MtY3oewRRs:cj9XLxCd-vc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=4MtY3oewRRs:cj9XLxCd-vc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=4MtY3oewRRs:cj9XLxCd-vc:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=4MtY3oewRRs:cj9XLxCd-vc:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=4MtY3oewRRs:cj9XLxCd-vc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=4MtY3oewRRs:cj9XLxCd-vc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=4MtY3oewRRs:cj9XLxCd-vc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=4MtY3oewRRs:cj9XLxCd-vc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=4MtY3oewRRs:cj9XLxCd-vc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/4MtY3oewRRs" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/09/17/600.aspx</guid>
            <pubDate>Thu, 17 Sep 2009 20:26:26 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/09/17/600.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/600.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/600.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/09/17/600.aspx</feedburner:origLink></item>
        <item>
            <title>Mac OS X Tip - Run Two Instances (or versions) of an App</title>
            <link>http://feedproxy.google.com/~r/scottcreynolds/~3/hvtGvMPiIdo/599.aspx</link>
            <description>&lt;p&gt;For my recently former Windows brothers out there who may not be clued into this - you can't run two instances of an app on OS X (at least not from the normal UI) nor can you install say, two versions of Firefox, side by side in the normal fashion.&lt;/p&gt;
&lt;p&gt;This is obviously foreign to Windows users who are used to being able to do both of these things with ease, but especially for those of you who may be using Selenium (which doesn't work with Firefox 3.5 yet), here's a tip to get you started.&lt;/p&gt;
&lt;p&gt;To install two versions of the same app side by side (in the applications folder) simply rename one. So, my firefox 3.5 install is named Firefox35.app and my Firefox 3 install is just Firefox.app. Now they can coexist.&lt;/p&gt;
&lt;p&gt;To run two instances of the same app side-by-side (looking at you, World of Warcraft multi-boxers), just make a copy of the app and rename one. Since everything most apps need to run is self-contained in the .app structure, and there's not a registry to deal with, that makes it easy.&lt;/p&gt;

&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/mac" rel="tag"&gt;mac&lt;/a&gt;, &lt;a href="http://technorati.com/tag/os%20x" rel="tag"&gt;os x&lt;/a&gt;
&lt;/p&gt;
&lt;!-- Technorati Tags End --&gt;&lt;img src="http://scottcreynolds.com/aggbug/599.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=hvtGvMPiIdo:4BR6qfr0hoc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=hvtGvMPiIdo:4BR6qfr0hoc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=hvtGvMPiIdo:4BR6qfr0hoc:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=hvtGvMPiIdo:4BR6qfr0hoc:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=hvtGvMPiIdo:4BR6qfr0hoc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=hvtGvMPiIdo:4BR6qfr0hoc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=hvtGvMPiIdo:4BR6qfr0hoc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/scottcreynolds?a=hvtGvMPiIdo:4BR6qfr0hoc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/scottcreynolds?i=hvtGvMPiIdo:4BR6qfr0hoc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/scottcreynolds/~4/hvtGvMPiIdo" height="1" width="1"/&gt;</description>
            <dc:creator>Scott C. Reynolds</dc:creator>
            <guid isPermaLink="false">http://scottcreynolds.com/archive/2009/08/12/599.aspx</guid>
            <pubDate>Wed, 12 Aug 2009 13:16:06 GMT</pubDate>
            <comments>http://scottcreynolds.com/archive/2009/08/12/599.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://scottcreynolds.com/comments/commentRss/599.aspx</wfw:commentRss>
            <trackback:ping>http://scottcreynolds.com/services/trackbacks/599.aspx</trackback:ping>
        <feedburner:origLink>http://scottcreynolds.com/archive/2009/08/12/599.aspx</feedburner:origLink></item>
    </channel>
</rss>
