<?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.stevenharman.net/~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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>StevenHarman.net</title>
        <link>http://stevenharman.net/blog/Default.aspx</link>
        <description>Living. Learning. Improving.</description>
        <language>en-US</language>
        <copyright>Steven Harman</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <image><link>http://creativecommons.org/licenses/by/2.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image>
        <creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.stevenharman.net/stevenharman" type="application/rss+xml" /><feedburner:emailServiceId>stevenharman</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.stevenharman.net/stevenharman" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://my.feedlounge.com/external/subscribe?url=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://static.feedlounge.com/buttons/subscribe_0.gif">Subscribe with FeedLounge</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.stevenharman.net%2Fstevenharman" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
            <title>Being Lazy with Rake</title>
            <category>Tips &amp;amp; Tricks.</category>
            <category>How-To-[Tech].</category>
            <link>http://stevenharman.net/blog/archive/2009/05/29/being-lazy-with-rake.aspx</link>
            <description>&lt;p&gt;I’ve noticed &lt;a title="Rake: RTFM!" href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt; has been &lt;a title="OMG Rake!" href="http://codebetter.com/blogs/david_laribee/archive/2008/08/25/omg-rake.aspx"&gt;gaining some traction&lt;/a&gt; within the .net community as of late, or at least within a certain segment of that community. &lt;/p&gt;  &lt;p&gt;We’re currently using Rake to automate the great bulk of an entire deployment pipeline here at VersionOne, and I know of a few teams at Quick Solutions that are doing similar things.&lt;/p&gt;  &lt;p&gt;I believe Rake is a great tool for automating intensive processes and/or tasks and also find it to be great for handling some of the more mundane tasks we do on a daily basis. I spend a fair amount of each working day in a terminal window – running various &lt;abbr title="Source Control Management"&gt;SCM&lt;/abbr&gt; commands, compiling code, running specs, etc.&lt;/p&gt;  &lt;p&gt;More of those trivial tasks are being replaced by simple Rake tasks. For example, I’ve started adding a Rake task something like the following to nearly every code base I work on&lt;/p&gt;  &lt;p /&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;desc &lt;span class="str"&gt;"Launch the solution in Visual Studio"&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;task &lt;span class="preproc"&gt;:sln &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  Thread.&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    system &lt;span class="str"&gt;'devenv #{&lt;/span&gt;@props[&lt;span class="preproc"&gt;:solution_path&lt;/span&gt;]&lt;span class="str"&gt;}'&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is a pretty simple task:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;spins up a new thread within a block &lt;/li&gt;

  &lt;li&gt;then opens a new subshell via the &lt;code&gt;system&lt;/code&gt; command &lt;/li&gt;

  &lt;li&gt;launches Visual Studio (via &lt;code&gt;devenv&lt;/code&gt;) passing the path to the solution file. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As long as I have Ruby and the Rake gem installed I can execute the task from anywhere within my project structure and have Visual Studio open the solution.&lt;/p&gt;

&lt;p&gt;&lt;a title="&amp;gt; rake sln" href="http://stevenharman.net/images/stevenharman_net/blog/WindowsLiveWriter/BeingLazywithRake_C623/rake-sln_4.png" rel="lightbox"&gt;&lt;img class="left" title="&amp;gt; rake sln" alt="&amp;gt; rake sln" src="http://stevenharman.net/images/stevenharman_net/blog/WindowsLiveWriter/BeingLazywithRake_C623/rake-sln_thumb_1.png" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It may seem incredibly lazy, but it comes in very hand if you like to keep your fingers on the home row. Not to mention the time saver it is on &lt;em&gt;No Mouse Thursdays&lt;/em&gt;!&lt;/p&gt;

&lt;p class="clear"&gt;&lt;strong&gt;Full Disclosure&lt;/strong&gt;: I didn’t come up with this little time saver on my own. I was inspired &amp;amp; then stole it from &lt;a title="Aaron Jensen" href="http://codebetter.com/blogs/aaron.jensen/" rel="met friend"&gt;Aaron Jensen&lt;/a&gt;, though I’m sure he was motivated by a similar level of laziness. :)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f05%2f29%2fbeing-lazy-with-rake.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f05%2f29%2fbeing-lazy-with-rake.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cbe1898b-8ae0-4862-a27a-c0fd6669e445" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/ruby" rel="tag"&gt;ruby&lt;/a&gt;,&lt;a href="http://technorati.com/tags/rake" rel="tag"&gt;rake&lt;/a&gt;,&lt;a href="http://technorati.com/tags/productivity" rel="tag"&gt;productivity&lt;/a&gt;&lt;/div&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12819.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=Jn1m4gjhRL8:XdzA_doiqxc:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=Jn1m4gjhRL8:XdzA_doiqxc:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=Jn1m4gjhRL8:XdzA_doiqxc:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=Jn1m4gjhRL8:XdzA_doiqxc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=Jn1m4gjhRL8:XdzA_doiqxc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=Jn1m4gjhRL8:XdzA_doiqxc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=Jn1m4gjhRL8:XdzA_doiqxc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=Jn1m4gjhRL8:XdzA_doiqxc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/Jn1m4gjhRL8" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2009/05/29/being-lazy-with-rake.aspx</guid>
            <pubDate>Fri, 29 May 2009 21:08:37 GMT</pubDate>
            <wfw:comment>http://stevenharman.net/blog/comments/12819.aspx</wfw:comment>
            <comments>http://stevenharman.net/blog/archive/2009/05/29/being-lazy-with-rake.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12819.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Toward a Better Use of Context/Specification</title>
            <category>Code &amp;amp; Stuff...</category>
            <link>http://stevenharman.net/blog/archive/2009/05/27/toward-a-better-use-of-context-specification.aspx</link>
            <description>&lt;p&gt;If you’ve hand-rolled your own &lt;strong&gt;Context/Specification&lt;/strong&gt; apparatus to support your &lt;strike&gt;test&lt;/strike&gt; spec-first lifestyle, you’ve likely got a base class that looks something like the following:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; concerns&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  [SetUp]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; setup_context()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    context();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;  &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; context() {}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;  &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; decontext() {}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;  [TearDown]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; cleanup_context()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;  {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    decontext();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The above is basically co-opting an existing unit testing tool into something more language-oriented and behavior focused. In this case we’ve built upon &lt;a title="generative unit test framework" href="http://mbunit.com/"&gt;MbUnit&lt;/a&gt;, adding a couple of hook methods that are responsible for&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;setting up the context before an individual specification - &lt;code&gt;context&lt;/code&gt; &lt;/li&gt;

  &lt;li&gt;optionally doing any necessary teardown after each specification – &lt;code&gt;decontext&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;An example&lt;/h3&gt;

&lt;p&gt;Using this base class, we’ll end up with specs that might looks something like&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Skynet.Core&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; when_initializing_core_module : concerns&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  SkynetCoreModule _core;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;  &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; context()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;  {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    &lt;span class="rem"&gt;//we'll stub it...you know...just in case&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    var skynetController = stub&amp;lt;ISkynetMasterController&amp;gt;();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    _core = &lt;span class="kwrd"&gt;new&lt;/span&gt; SkynetCoreModule(skynetController);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    _core.Initialize();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;  &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;  [Specification]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; it_should_not_become_self_aware()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;  {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    _core.should_not_have_received_the_call(x =&amp;gt; x.InitializeAutonomousExecutionMode());&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;  &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;  [Specification]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; it_should_default_to_human_friendly_mode()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;  {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    _core.AssessHumans().should_equal(RelationshipTypes.Friendly);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;  &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;  &lt;span class="rem"&gt;// more specifications under this same context&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;  &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Here we’ve set up a common context that holds true for each of specifications that follow it. This is also a common pattern used in &lt;em&gt;classic unit testing&lt;/em&gt; and in fixture-per-class style Test-Driven Development. In fact, the only real between the above and what I’d have done in fixture-per-class style &lt;abbr title="Test-Driven Development"&gt;TDD&lt;/abbr&gt; is the_use_of_underscores, intention revealing names, and the context hook method.&lt;/p&gt;

&lt;h3&gt;Is that really any different?&lt;/h3&gt;

&lt;p&gt;These modest cosmetics are not what differentiate Context/Specification from other styles of test-first development. For me, the core differentiator is the realization that there are often many contexts under which a particular behavior my be exercised, each producing an observable and possibly different set of results.&lt;/p&gt;

&lt;p&gt;More directly, with Context/Specification we’ll often have &lt;strong&gt;many fixtures per class/feature/functional area&lt;/strong&gt; of the code base. Doing this allows us to keep the context as simple as possible and focused on the behavior being specified. I’ve found that I tend toward having a single file-per-class/functional area, with any number of contexts (fixtures) in each file.&lt;/p&gt;

&lt;p&gt;Another big change is that specifications should be side effect free. To be more exact, the specification is actually an observation about the interactions that occurred while or the state of the system after some behavior has been exercised.&lt;/p&gt;

&lt;h3&gt;Make it explicit!&lt;/h3&gt;

&lt;p&gt;We want small, focused contexts, yes? And we want side effect free specifications too, yeah? So why not leverage our tools to help guide us in that direction? &lt;strong&gt;YES!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider the following tweak to the &lt;code&gt;concerns&lt;/code&gt; base class&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; concerns&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  &lt;strong&gt;[FixtureSetUp]&lt;/strong&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; setup_context()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    context();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;  &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; context() {}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;  &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; decontext() {}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;  &lt;strong&gt;[FixtureTearDown]&lt;/strong&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; cleanup_context()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;  {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    decontext();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Such a base class will only set up each context once, no matter how many specifications are made against the context. This does a couple of things for us&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;requires side effect free specifications &lt;/li&gt;

  &lt;li&gt;guides us toward smaller, more focused contexts &lt;/li&gt;

  &lt;li&gt;might actually make our specs run faster! &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for the &lt;em&gt;running faster&lt;/em&gt; bit, that is not guaranteed as it really depends on how you were writing your specs before making this change.&lt;/p&gt;

&lt;h3&gt;Some things to watch for&lt;/h3&gt;

&lt;p&gt;If, however, you were following more of a fixture-per-class style, you might find a drastic reduction in how long it takes your spec suite to run. The corollary is, of course, that you likely don’t have small contexts. That is trouble and is often an indicator that the one, large context is itching to be split out into two or more discrete contexts.&lt;/p&gt;

&lt;p&gt;Upon switching your base class over to this more rigid Context/Specification pattern, you might also find that you have some – or many – broken specs. This is an indicator that those broken specs were not side effect free. Well, actually its suggesting that some of the sibling specs weren’t side effect free and they are now causing other specs to break.&lt;/p&gt;

&lt;h3&gt;Notes:&lt;/h3&gt;

&lt;p&gt;The portions of this article relating to changing from a standard context set up to a once-per-fixture style apply to &lt;em&gt;most&lt;/em&gt; of the hand-rolled Context/Specification base classes I’ve seen in the wild.&lt;/p&gt;

&lt;p&gt;If, however, you are using a tool like &lt;a href="http://github.com/machine/machine.specifications"&gt;MSpec&lt;/a&gt;, then you’re in good shape as &lt;a href="http://codebetter.com/blogs/aaron.jensen/" rel="friend met"&gt;Aaron&lt;/a&gt; applied this same philosophy out of the gate. And if you’re not using MSpec, I’d encourage you to take a look at it for inspiration, if nothing else.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f05%2f27%2ftoward-a-better-use-of-context-specification.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f05%2f27%2ftoward-a-better-use-of-context-specification.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:10678bc3-2e8c-4e64-94d7-6dabdc258033" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/contextspecification" rel="tag"&gt;contextspecification&lt;/a&gt;,&lt;a href="http://technorati.com/tags/bdd" rel="tag"&gt;bdd&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tdd" rel="tag"&gt;tdd&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mspec" rel="tag"&gt;mspec&lt;/a&gt;&lt;/div&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12818.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=jvjOz7lyjoE:WpC2d0tWvgs:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=jvjOz7lyjoE:WpC2d0tWvgs:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=jvjOz7lyjoE:WpC2d0tWvgs:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=jvjOz7lyjoE:WpC2d0tWvgs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=jvjOz7lyjoE:WpC2d0tWvgs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=jvjOz7lyjoE:WpC2d0tWvgs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~ff/stevenharman?a=jvjOz7lyjoE:WpC2d0tWvgs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=jvjOz7lyjoE:WpC2d0tWvgs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/jvjOz7lyjoE" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2009/05/27/toward-a-better-use-of-context-specification.aspx</guid>
            <pubDate>Wed, 27 May 2009 17:19:53 GMT</pubDate>
            <wfw:comment>http://stevenharman.net/blog/comments/12818.aspx</wfw:comment>
            <comments>http://stevenharman.net/blog/archive/2009/05/27/toward-a-better-use-of-context-specification.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12818.aspx</wfw:commentRss>
        </item>
        <item>
            <title>So Long Columbus, and Thanks for All the Fish!</title>
            <category>Updates &amp;amp; News.</category>
            <link>http://stevenharman.net/blog/archive/2009/02/06/so-long-columbus-and-thanks-for-all-the-fish.aspx</link>
            <description>&lt;p&gt;Yes, that’s right Columbus… after nearly a decade here, it’s time for me to move on. But don’t worry Columbus, you’ll always be a special place in my heart – and likely irreversible damage to both my psyche and liver for me to remember you by.&lt;/p&gt;  &lt;p&gt;Leaving Columbus is a bittersweet thing for me. I’ve got a great group of friends, a metric crap-load memories, experiences I’ll never forget, and a network of some of the greatest colleagues and co-workers in the biz.&lt;/p&gt;  &lt;p&gt;Speaking of &lt;em&gt;the biz&lt;/em&gt;, the decision to leave &lt;a title="Quick Solutions, Inc." href="http://quicksolutions.com/" rel="external"&gt;Quick Solutions&lt;/a&gt; was not an easy one. &lt;abbr title="Quick Solutions, Inc."&gt;QSI&lt;/abbr&gt; is chock full of some of the smartest, most passionate, and dedicated folks I’ve ever had the pleasure of working with. I’m really going to miss the team I worked with every day, and I’m especially sad I won’t be around to see the team continue to push the boundaries and reap the rewards of some of the seeds of change we’ve planted together.&lt;/p&gt;  &lt;p&gt;So what’s next for me? &lt;/p&gt;  &lt;h3&gt;I’m headed to The ATL&lt;/h3&gt;  &lt;p&gt;That’s right, on February 14th I’ll be packing up my car and heading down to Atlanta. I’ll be spending Valentine’s day cruising down I-75, followed by an evening tearing up Atlanta with some crazy cats I know down there.&lt;/p&gt;  &lt;p&gt;And then on the 16th, I’ll be starting my new gig as member of the rockin’ &lt;a title="VersionOne - Simplifying Software Delivery" href="http://versionone.com/" rel="external"&gt;VersionOne&lt;/a&gt; development team. I spent a full, as in 13-hour-long, day visiting/interviewing with the VersionOne crew a short while back and I’m really excited about being part of what has the potential to be a truly legendary team.&lt;/p&gt;  &lt;p&gt;I’m really looking forward to getting back into the product business and focusing on a domain that I’m passionate about – helping drive continuous improvement in an Agile team, building products for Agile teams. &lt;em&gt;Sweet, right!&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I’m pumped to see just how far this team can Agile and Lean, and I’m really looking forward to sharing those experiences with you, as we go.&lt;/p&gt;  &lt;p&gt;So long, and thanks for all the fish!&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:785a769d-879a-425a-8076-9d3768300a4e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/career" rel="tag"&gt;career&lt;/a&gt;, &lt;a href="http://technorati.com/tags/life" rel="tag"&gt;life&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Quick+Solutions" rel="tag"&gt;Quick Solutions&lt;/a&gt;, &lt;a href="http://technorati.com/tags/VersionOne" rel="tag"&gt;VersionOne&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Columbus" rel="tag"&gt;Columbus&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Atlanta" rel="tag"&gt;Atlanta&lt;/a&gt;&lt;/div&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12817.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=zSLPeg58"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=zSLPeg58" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=DS2PWJG3"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=XPTQQRG5"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=XPTQQRG5" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=Zx8SxpzX"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=Zx8SxpzX" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/oMnCAPhVOM0" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2009/02/06/so-long-columbus-and-thanks-for-all-the-fish.aspx</guid>
            <pubDate>Fri, 06 Feb 2009 05:22:42 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2009/02/06/so-long-columbus-and-thanks-for-all-the-fish.aspx#feedback</comments>
            <slash:comments>14</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12817.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A Little More Sugar for Testing Routes in asp.net MVC</title>
            <category>Code &amp;amp; Stuff...</category>
            <link>http://stevenharman.net/blog/archive/2009/02/05/a-little-more-sugar-for-testing-routes-in-asp.net-mvc.aspx</link>
            <description>&lt;p&gt;The other day I was spec’ing out some new routes for my application and I wanted to make sure certain routes were ignored. Not happy with the disgustingly-verbose way of testing routes &lt;abbr title="Out of the Box"&gt;OOTB&lt;/abbr&gt; with asp.net &lt;abbr title="Model View Controller"&gt;MVC&lt;/abbr&gt;, I decided to lean on the great work Ben Schierman did in his &lt;a title="Fluent Route Testing in ASP.NET MVC" href="http://flux88.com/blog/fluent-route-testing-in-asp-net-mvc/" rel="external"&gt;fluent route testing&lt;/a&gt; extensions.&lt;/p&gt;  &lt;p&gt;I whipped together a quick extension method that allows me to do the following:&lt;/p&gt;  &lt;div class="dropshadow"&gt;   &lt;div class="innerbox"&gt;     &lt;div class="csharpcode"&gt;       &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; when_requesting_a_gif_file : with_routes_configured&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    [Test]&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; should_ignore_the_route()&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="str"&gt;"~/my_file.gif"&lt;/span&gt;.ShouldBeIgnored();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    }&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;}&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Building the extension was a snap – I leveraged the work already in place for the other fluent route testing extensions, and just made sure the &lt;code&gt;RouteHandler&lt;/code&gt; responsible for the given route pattern was a &lt;code&gt;StopRoutingHandler&lt;/code&gt;. It looks something like this:&lt;/p&gt;

&lt;div class="dropshadow"&gt;
  &lt;div class="innerbox"&gt;
    &lt;div class="csharpcode"&gt;
      &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; RouteTestingExtensions&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; RouteData ShouldBeIgnored(&lt;span class="kwrd"&gt;this&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; relativeUrl)&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        RouteData routeData = relativeUrl.Route();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        routeData.RouteHandler.ShouldBeOfType&amp;lt;StopRoutingHandler&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; routeData;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    }&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;}&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;And that's all there is to it!&lt;/p&gt;

&lt;p&gt;&lt;strike&gt;I’ll be submitting&lt;/strike&gt; I &lt;a title="See the patch!" href="http://code.google.com/p/mvccontrib/source/detail?r=769" rel="external"&gt;have submitted this as a patch&lt;/a&gt; to MVC Contrib project within the next few minutes. Hopefully I can coax one of the committers into applying it. But until then, just steal my code and roll it into your code base!&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7b89e818-1357-449a-8ae4-9d2f5a26db5d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/aspnetmvc" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://technorati.com/tags/fluent" rel="tag"&gt;fluent&lt;/a&gt;, &lt;a href="http://technorati.com/tags/bdd" rel="tag"&gt;bdd&lt;/a&gt;, &lt;a href="http://technorati.com/tags/asp.net" rel="tag"&gt;asp.net&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f02%2f05%2fa-little-more-sugar-for-testing-routes-in-asp.net-mvc.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f02%2f05%2fa-little-more-sugar-for-testing-routes-in-asp.net-mvc.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12816.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=L9qxUQAp"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=L9qxUQAp" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=UsA7eZuL"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=yndRcxkQ"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=yndRcxkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=e3bj50HT"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=e3bj50HT" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/5PMHvzsrB7c" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2009/02/05/a-little-more-sugar-for-testing-routes-in-asp.net-mvc.aspx</guid>
            <pubDate>Fri, 06 Feb 2009 04:44:11 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2009/02/05/a-little-more-sugar-for-testing-routes-in-asp.net-mvc.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12816.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A Sketch of our Ideation Pipeline</title>
            <category>Me, On Software.</category>
            <link>http://stevenharman.net/blog/archive/2009/01/20/a-sketch-ideation-pipeline.aspx</link>
            <description>&lt;p&gt;&lt;a title="Initial sketch of our Ideation Pipeline" href="http://stevenharman.net/images/stevenharman_net/blog/WindowsLiveWriter/ASketchIdeationPipeline_9F4E/ideation-pipeline_6.png" rel="lightbox"&gt;&lt;img class="right" title="Initial sketch of our Ideation Pipeline" alt="Initial sketch of our Ideation Pipeline" src="http://stevenharman.net/images/stevenharman_net/blog/WindowsLiveWriter/ASketchIdeationPipeline_9F4E/ideation-pipeline_thumb_2.png" /&gt;&lt;/a&gt; This is an initial sketch of an &lt;em&gt;Ideation Pipeline&lt;/em&gt; my team will be using to help drive the direction of a product we’re working on. The sketch is based on a discussion we had about how we currently get from an idea to delivering on that idea, and how we’d like to do that going forward.&lt;/p&gt;  &lt;p&gt;While we probably should have done a full on &lt;a title="Value Stream Mapping" href="http://en.wikipedia.org/wiki/Value_Stream_Mapping"&gt;Value Stream Map&lt;/a&gt;, we didn’t. And the only excuse I have is that we’re kicking this product off so there isn’t really a set way we do things… not yet anyhow.&lt;/p&gt;  &lt;p&gt;At any rate, later today I’ll be turning this loose sketch into a physical &lt;a title="Kanban" href="http://en.wikipedia.org/wiki/Kanban"&gt;Kanban&lt;/a&gt; board that we’ll used to track and pull ideas through our ideation process, and feed the resulting features into our development process.&lt;/p&gt;  &lt;p&gt;But first, I want to explain how the whole thing will work, or at least how we’re going to start – I’m sure we’ll tweak and straight-up change out whole parts of this process as we go along. Let’s get started!&lt;/p&gt;  &lt;h3&gt;Starting with an Idea&lt;/h3&gt;  &lt;p&gt;Our process starts with an idea. An idea can be nearly anything that someone &lt;em&gt;thinks&lt;/em&gt; will add value to the system. An idea might be laser-focused, or it might be a bit more nebulous. At this stage we don’t really care, its only important that we realize we have a potential value-adding idea and that we act upon it.&lt;/p&gt;  &lt;p&gt;The Standardized Work (designated by the blue text in the lower box of each stage) in this stage is pretty basic, though not necessarily easy. In essence, an idea needs to be evaluated to determine it will deliver value. &lt;/p&gt;  &lt;p&gt;And what does &lt;em&gt;deliver value&lt;/em&gt; mean?&lt;/p&gt;  &lt;blockquote cite="http://www.poppendieck.com/pdfs/Waste-Value.pdf"&gt;   &lt;p&gt;&lt;strong&gt;Value is…&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Seen though the eyes of those who pay for, use, and derive value from the systems we create.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There are many factors that go into determining if something is or is not valuable. In our case it’s things like market demand, product vision and roadmap, feature parity with competitors, availability of resources, effort, etc… Also, value is a temporal thing. So while an idea might not hold much promise for delivering value now, that doesn’t mean that it won’t at some point in the future.&lt;/p&gt;  &lt;p&gt;If it’s determined that an idea will deliver value now, the idea card is moved into the Ready for Decomposition state. However, if the idea won’t deliver value now (or at least within the very short, foreseeable future), it’s moved to a &lt;em&gt;Never&lt;/em&gt; state. In the physical world that means the Idea Kanban is taken off the board.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;But wait… if the idea has potential to provide value in the future, and you’ve moved it to Never, won’t we lose track of it?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;YES, exactly!&lt;/strong&gt; And you know what? We don’t care! If the idea truly has potential for some future value, it will come back into our pipeline on its own. Why waste time, effort, and money keeping track of a huge backlog of stuff that might not ever happen? &lt;a title="DMZing the Backlog" href="http://arcware.net/dmzing-the-backlog/"&gt;DMZ that stuff&lt;/a&gt;!&lt;/p&gt;  &lt;h3&gt;Ready for Decomposition&lt;/h3&gt;  &lt;p&gt;Right now we have no queue limits on our Ready for Decomposition queue because we’re&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;thinking our throughput will be high enough to keep the queue short anyhow &lt;/li&gt;    &lt;li&gt;going to help our customers be honest with themselves and diligent in determining which ideas really will provide value &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;However, if we find this queue to be a bottleneck, or a source of thrashing, we’ll likely put a limit on it.&lt;/p&gt;  &lt;p&gt;The first thing that needs to happen when any idea enters the Ready for Decomposition state is to re-prioritize the queue. This needs to happen so the team knows which ideas are most important and should be decomposed first.&lt;/p&gt;  &lt;p&gt;Decomposing an idea means doing necessary analysis activities to understand and flesh-out the idea, break the idea down into one or more Minimum Marketable Feature (&lt;abbr title="Minimum Marketable Feature"&gt;MMF&lt;/abbr&gt;), and defining acceptance criteria (in a loose Context/Specification style) for each feature. During the decomposition the MMFs are transitioned to physical Kanbans that will feed into and flow through our development pipeline. These are also known as Feature Cards within our organization.&lt;/p&gt;  &lt;h3&gt;When to decompose?&lt;/h3&gt;  &lt;p&gt;Idea decomposition is not a regularly scheduled activity, but is triggered by a downstream need for Feature Cards. That is, ideas are &lt;em&gt;pulled&lt;/em&gt; through the Ideation Pipeline by some downstream activity that will move the idea closer to providing value. We’re pulling from &lt;a title="Implementing Lean Software Development: From Concept to Cash" href="http://www.amazon.com/Implementing-Lean-Software-Development-Addison-Wesley/dp/0321437381"&gt;Concept to Cash&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;It should also be noted that we only decompose as many ideas as are needed to satisfy the source of the pull. In this case, that would be our development pipeline’s backlog queue. If the backlog has two spots open, and we decompose an idea into two MMFs, then we’re done decomposing for now. If we only decompose it into one MMF, then we’ll need to decompose another idea.&lt;/p&gt;  &lt;p&gt;And what if that second idea decomposes into two or more MMFs? Now we’ve got more MMFs than we can fit in our backlog… oh no!&lt;/p&gt;  &lt;p&gt;Actually, that’s just fine! Our development backlog is itself a prioritized queue. So we just need to prioritize all of the MMFs, fill the backlog with the most important ones, and let the rest sit in the Decomposed state until the backlog pulls another one in!&lt;/p&gt;  &lt;h3&gt;On to the development pipeline!&lt;/h3&gt;  &lt;p&gt;Well… that’s what those MMF Kanbans would do anyhow! But you, dear reader, will have to wait until later – like until I write a post that covers our development pipeline!&lt;/p&gt;  &lt;h3&gt;Other Resources&lt;/h3&gt;  &lt;p&gt;If you’re looking for more information on some of the terms or concepts I’ve mentioned here, be sure to check out Karl Scotland’s excellent round-up of links/references to materials on &lt;a title="Useful links or references to material on Kanban Software Development." href="http://availagility.wordpress.com/kanban/"&gt;Kanban Software Development&lt;/a&gt;.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4218f160-c710-4df9-ab12-d54be8e946bb" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/lean" rel="tag"&gt;lean&lt;/a&gt;,&lt;a href="http://technorati.com/tags/kanban" rel="tag"&gt;kanban&lt;/a&gt;,&lt;a href="http://technorati.com/tags/software" rel="tag"&gt;software&lt;/a&gt;,&lt;a href="http://technorati.com/tags/process" rel="tag"&gt;process&lt;/a&gt;&lt;/div&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12808.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=o8CBLcMp"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=o8CBLcMp" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=LdWiWJr5"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=5UHkojaa"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=5UHkojaa" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=QwmhnWWY"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=QwmhnWWY" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/ZXYg9h7pDQw" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2009/01/20/a-sketch-ideation-pipeline.aspx</guid>
            <pubDate>Tue, 20 Jan 2009 20:49:34 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2009/01/20/a-sketch-ideation-pipeline.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12808.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Saving the World via&amp;hellip; TDD?</title>
            <category>Code &amp;amp; Stuff...</category>
            <link>http://stevenharman.net/blog/archive/2009/01/14/saving-the-world-via-tdd.aspx</link>
            <description>&lt;p&gt;Hot on the heels of my wildly (in)famous “&lt;a title="All the Fcuking time!" href="http://stevenharman.net/blog/archive/2008/12/17/when-should-i-write-tests.aspx"&gt;When Should I Write Tests?&lt;/a&gt;” post, I have another fun tidbit about testing to share with you. Though, to be honest, I found this gem via my buddy &lt;a title="Scott C Reynolds... this is his blog." href="http://www.lostechies.com/blogs/scottcreynolds/" rel="friend met"&gt;Scott C Reynolds&lt;/a&gt;, so I can’t take all – actually, I can’t take any – of the credit.&lt;/p&gt;  &lt;p&gt;Anyhow, Scott posted a great little snippet of code that does a couple of things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Shows &lt;em&gt;the gist&lt;/em&gt; of Context/Specification style specs in use. &lt;/li&gt;    &lt;li&gt;Ensures we won’t need John Connor’s help after all. &lt;/li&gt; &lt;/ol&gt;  &lt;div class="dropshadow"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Skynet.Core

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; when_initializing_core_module
{
    ISkynetMasterController _skynet;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; establish_context()
    {
        &lt;span class="rem"&gt;//we'll stub it...you know...just in case&lt;/span&gt;
        _skynet = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockRepository.GenerateStub&amp;lt;ISkynetMasterController&amp;gt;();
        _skynet.Initialize();
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; it_should_not_become_self_aware()
    {
        _skynet.AssertWasNotCalled(x =&amp;gt; x.InitializeAutonomousExecutionMode());
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; it_should_default_to_human_friendly_mode()
    {
        _skynet.AssessHumans().ShouldEqual(RelationshipTypes.Friendly);
    }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; when_attempting_to_wage_war_on_humans
{
    ISkynetMasterController _skynet;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; establish_context()
    {
        _skynet = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockRepository.GenerateStub&amp;lt;ISkynetMasterController&amp;gt;();
        _skynet.Stub(x =&amp;gt; 
            x.DeployRobotArmy(TargetTypes.Humans)).Throws&amp;lt;OperationInvalidException&amp;gt;();
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; because()
    {
        _skynet.DeployRobotArmy(TargetTypes.Humans);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; it_should_not_allow_the_operation_to_succeed()
    {
        _skynet.AssertWasThrown&amp;lt;OperationInvalidException&amp;gt;();
    }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Originally I wasn’t going to repost the code here because I didn’t want to take credit for it. But after a quick chat with Scott I decided maybe I should, just in case Pastie decides to take a dump! Plus, this is like a little time capsule of our current thoughts on Context/Specification, pop culture, and the ceremony of many of the languages we currently use.&lt;/p&gt;

&lt;p&gt;But as a matter of full disclosure, here is a &lt;a title="Pastie: Saving the World with TDD" href="http://pastie.org/360261" rel="external"&gt;link to the original code on pastie.org&lt;/a&gt;.&lt;/p&gt;

&lt;p /&gt;

&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:67545d2e-b63f-482e-bb0f-8a3b69c099be" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/tdd" rel="tag"&gt;tdd&lt;/a&gt;,&lt;a href="http://technorati.com/tags/bdd" rel="tag"&gt;bdd&lt;/a&gt;,&lt;a href="http://technorati.com/tags/contextspecification" rel="tag"&gt;contextspecification&lt;/a&gt;,&lt;a href="http://technorati.com/tags/terminator" rel="tag"&gt;terminator&lt;/a&gt;&lt;/div&gt;

&lt;p /&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f01%2f14%2f12807.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2009%2f01%2f14%2f12807.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12807.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=XWUzEbO8"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=XWUzEbO8" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=hKb4ZTZt"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=UIKFxujG"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=UIKFxujG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=apjHvTcY"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=apjHvTcY" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/GE64Nekjid8" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2009/01/14/saving-the-world-via-tdd.aspx</guid>
            <pubDate>Wed, 14 Jan 2009 05:55:56 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2009/01/14/saving-the-world-via-tdd.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12807.aspx</wfw:commentRss>
        </item>
        <item>
            <title>When Should I Write Tests?</title>
            <category>Code &amp;amp; Stuff...</category>
            <link>http://stevenharman.net/blog/archive/2008/12/17/when-should-i-write-tests.aspx</link>
            <description>&lt;p&gt;That is a question I get quite a bit, albeit in a variety of different flavors, but the heart of the question is always the same.&lt;/p&gt;  &lt;p&gt;So, inspired a conversation with my friend &lt;a title="Corey's Ramblings" href="http://coreyhaines.com" rel="friend met"&gt;Corey&lt;/a&gt;, and a certain talk from a recent Ruby Hoedown that he told me about, I decided to clear up the issue once and for all. And to make it perfectly clear, I decided to register some new URLs that are easy to remember:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="When Should I Test?" href="http://whenshoulditest.com"&gt;http://whenshoulditest.com&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="How Often Should I Test?" href="http://howoftenshoulditest.com"&gt;http://howoftenshoulditest.com&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Go give them a read, I think you’ll get the gist pretty quickly.&lt;/p&gt;  &lt;p&gt;(Thanks also to &lt;a title="diary of a mad hacker..." href="http://smartic.us" rel="external"&gt;Brian Liles&lt;/a&gt; for the inspiration)&lt;/p&gt;  &lt;p /&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:35c7a71f-9ad1-4c60-86cf-d16d0c6f0945" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/tdd" rel="tag"&gt;tdd&lt;/a&gt;, &lt;a href="http://technorati.com/tags/bdd" rel="tag"&gt;bdd&lt;/a&gt;, &lt;a href="http://technorati.com/tags/agile" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;&lt;/div&gt;  &lt;p /&gt;  &lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2008%2f12%2f17%2fwhen-should-i-write-tests.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2008%2f12%2f17%2fwhen-should-i-write-tests.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12801.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=lUhlAquV"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=lUhlAquV" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=qx77iUz0"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=kWy4BWzn"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=kWy4BWzn" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=qf1xyOnl"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=qf1xyOnl" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/ok1iIeE4Hjs" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2008/12/17/when-should-i-write-tests.aspx</guid>
            <pubDate>Wed, 17 Dec 2008 18:52:33 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2008/12/17/when-should-i-write-tests.aspx#feedback</comments>
            <slash:comments>20</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12801.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VNC to a Headless Ubuntu Box</title>
            <category>How-To-[Tech].</category>
            <link>http://stevenharman.net/blog/archive/2008/12/13/vnc-to-a-headless-ubuntu-box.aspx</link>
            <description>&lt;p&gt;I’ve been doing a good amount of Ruby development lately and I really wanted to have a dedicated box to use as an internal (w/in my house) &lt;abbr title="Continuous Integration"&gt;CI&lt;/abbr&gt; box… and possibly a staging server to host some Rails apps I was playing with. Anyhow, I had an old, unused box sitting in the basement – perfect!&lt;/p&gt;  &lt;p&gt;I installed the latest Ubuntu bits, 8.04 (&lt;i&gt;Hardy Heron&lt;/i&gt;) and had the box up and running in no time. However, as I intended to keep this box in the basement, without a monitor, keyboard, or mouse, I needed to be able to access and administer it remotely.&lt;/p&gt;  &lt;p&gt;Granted, most of the work I’d need to do could be accomplished via &lt;abbr title="Secure Shell"&gt;SSH&lt;/abbr&gt;, but there were a few things I was going to need a &lt;abbr title="Graphical User Interface"&gt;GUI&lt;/abbr&gt; for – I needed remote desktop! Or just &lt;abbr title="Virtual Network Computing"&gt;VNC&lt;/abbr&gt;. :)&lt;/p&gt;  &lt;h3&gt;Going headless&lt;/h3&gt;  &lt;p&gt;Ubuntu does support VNC out of the box, but you need to have an active X-Windows (Gnome, KDE, etc…) session already running before you fire up the VNC server. &lt;/p&gt;  &lt;p&gt;But this was going to be a headless box! So short of hauling a monitor and keyboard to the basement every time I needed to bounce the box, which is rare, I had no way to get an X session started.&lt;/p&gt;  &lt;h3&gt;VNC Server, to the rescue!&lt;/h3&gt;  &lt;p&gt;To enable full GUI remote login you need a VNC server instance running on the box, and you need to launch an x session – I’m a Gnome guy myself, so we’ll go that route.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;SSH into the box and install TightVNCServer      &lt;ul&gt;       &lt;li&gt;&lt;code&gt;sudo apt-get install tightvncserver&lt;/code&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Set Gnome to start when your VNC session starts      &lt;ul&gt;       &lt;li&gt;&lt;code&gt;vi ~/.vnc/xstartup&lt;/code&gt; &lt;/li&gt;        &lt;li&gt;         &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;#!/bin/sh&lt;/span&gt;

xrdb $HOME/.Xresources
xsetroot -solid black
gnome-session &amp;amp;&lt;/pre&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;Start the VNC Server 
    &lt;ul&gt;
      &lt;li&gt;&lt;code&gt;vncserver –geometry &lt;em&gt;width&lt;/em&gt;x&lt;em&gt;height&lt;/em&gt; –depth 24&lt;/code&gt; &lt;/li&gt;

      &lt;li&gt;You will probably be prompted to enter a password that you'll use later to connect to this VNC session... so enter one! &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;Start your VNC client on the remote machine, enter the password from step 3, and enjoy!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One side note. After logging into my VNC session I noticed that my keyboard mappings were all jacked-up. For example, typing &lt;code&gt;asdf&lt;/code&gt; would result in &lt;code&gt;abfh&lt;/code&gt;. After some searching, this appears to be an issue w/Gnome, but luckily I also &lt;a title="3 Solutions to GNOME/VNC keyboard mapping issue" href="http://blog.yclian.com/2007/12/3-solutions-to-gnomevnc-keyboard.html" rel="external"&gt;found a workaround&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Oh… and you should probably be connecting to your VNC session via an SSH tunnel, but that’s a topic for another blog post… or &lt;a title="vnc via ssh" href="http://www.google.com/search?q=vnc+via+ssh" rel="external"&gt;use your Google-fu&lt;/a&gt;!&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:93d31843-4df1-4ead-b33c-1b0149b4ece3" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/ubuntu" rel="tag"&gt;ubuntu&lt;/a&gt;,&lt;a href="http://technorati.com/tags/vnc" rel="tag"&gt;vnc&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ssh" rel="tag"&gt;ssh&lt;/a&gt;&lt;/div&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12800.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=YezKcdli"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=YezKcdli" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=rDQmvpN6"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=XN7BCkv9"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=XN7BCkv9" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=yz8iwr8l"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=yz8iwr8l" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/esFakxpOvrE" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2008/12/13/vnc-to-a-headless-ubuntu-box.aspx</guid>
            <pubDate>Sat, 13 Dec 2008 05:13:08 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2008/12/13/vnc-to-a-headless-ubuntu-box.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12800.aspx</wfw:commentRss>
        </item>
        <item>
            <title>KaizenConf Resources</title>
            <category>Updates &amp;amp; News.</category>
            <link>http://stevenharman.net/blog/archive/2008/11/20/kaizenconf-resources.aspx</link>
            <description>&lt;p&gt;&lt;img class="right" title="stone bridge" alt="stone bridge" src="http://stevenharman.net/images/stevenharman_net/blog/WindowsLiveWriter/LeanSoftwareEngineeringKaizenConfResourc_146CB/stones_4.jpg" /&gt; Even though the &lt;a title="Kaizen Conference" href="http://kaizenconf.com/" rel="external"&gt;Continuous Improvement in Software Development Conference&lt;/a&gt; may be over, there is still much work being done to distill and distribute the knowledge, value, and magic that happened made KaizenConf 2008 the great success it was.&lt;/p&gt;  &lt;h3&gt;Get the videos&lt;/h3&gt;  &lt;p&gt;As part of that distillation process I, and many others, are currently going through hundreds of Gigabytes of video footage we captured, we’re doing post production work, and eventually we’ll be uploading all of it to the Intar-webs.&lt;/p&gt;  &lt;p&gt;The primary location to find information on any of the pre-conference workshops or the sessions themselves is at the &lt;a title="Kaizen Conference - wiki" href="http://kaizenconf.pbwiki.com" rel="external"&gt;KaizenConf wiki&lt;/a&gt;. If you’re looking for the videos, you’ll want to pay particular attention to the &lt;a title="Kaizen Conference - Media" href="http://kaizenconf.pbwiki.com/Media" rel="external"&gt;media page&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Lean Software Engineering&lt;/h3&gt;  &lt;p&gt;Lean is one topic that I’ve been studying a lot as of late, and I’ve been putting it into practicing more and more every day. A fair amount of my time at KaizenConf was focused on the discussions and workshops around Lean – pull systems, Kanban boards, Value Stream Mapping, etc…&lt;/p&gt;  &lt;p&gt;And naturally, since those are the topics I’m interested in, I made sure to get those videos processed first. :) Here’s what I’ve got so far:&lt;/p&gt;  &lt;h4&gt;Pull, Don't Push - Lean Systems and Kanban&lt;/h4&gt;  &lt;p&gt;&lt;a title="Pull, Don't Push - Lean Systems and Kanban" href="http://kaizenconf.pbwiki.com/Pull,+Don%E2%80%99t+Push:+Lean+Systems+and+Kanban" rel="external"&gt;Workshop Description&lt;/a&gt; (from &lt;a title="Dave Laribee" href="http://codebetter.com/blogs/david_laribee/" rel="external friend met"&gt;Dave Laribee's&lt;/a&gt; original post on the workshops):&lt;/p&gt;  &lt;blockquote cite="http://kaizenconf.pbwiki.com/Pull,+Don%E2%80%99t+Push:+Lean+Systems+and+Kanban"&gt;   &lt;p&gt;I will say this will be aimed at getting you up and running with an iteration-less pull system or "Kanban." We'll cover some of the principles of Lean Software Development, queue and buffer patterns, and metrics/reporting.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We’ve got nearly three hours of video from this workshop.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.viddler.com/explore/stevenharman/videos/2/"&gt;Dave discusses some of the reasons, principles, and basics of Lean Software Development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.viddler.com/explore/stevenharman/videos/3/"&gt;Value Stream Mapping - a real-life example&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.viddler.com/explore/stevenharman/videos/4/"&gt;Building a Kanban Board&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;Kanban in Small Teams&lt;/h4&gt;  &lt;p&gt;I can’t take any credit for this one, but I can give credit to &lt;a title="Ryan Kelley" href="http://www.techfocus2.com/" rel="friend met external"&gt;Ryan Kelley&lt;/a&gt; and the Los Techies crew for getting this video ready.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The main topic I was trying to discuss in this space were the challenges that are out there with implementing Lean and Kanban in small teams.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You can read more info about &lt;a title="Kanban in Small teams" href="http://kaizenconf.pbwiki.com/Kanban+in+Small+Teams" rel="external"&gt;this session at the wiki&lt;/a&gt;. Oh, and be sure to check out &lt;a title="Kanban in Small Teams" href="http://www.viddler.com/explore/lostechies/videos/4/" rel="external"&gt;the video&lt;/a&gt; for the full impact!&lt;/p&gt;  &lt;h3&gt;More to come…&lt;/h3&gt;  &lt;p&gt;As I said, there is plenty more content to be processed… but it does take time. So a huge thanks goes out to all the other folks volunteering their time to help with this effort. Keep you eye on the wiki for more updates and content.&lt;/p&gt;  &lt;p&gt;Always be Improving!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2008%2f11%2f20%2fkaizenconf-resources.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstevenharman.net%2fblog%2farchive%2f2008%2f11%2f20%2fkaizenconf-resources.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:07878e03-7930-41d8-bd1b-41cf9dfff5df" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/kaizenconf" rel="tag"&gt;kaizenconf&lt;/a&gt;, &lt;a href="http://technorati.com/tags/lean" rel="tag"&gt;lean&lt;/a&gt;, &lt;a href="http://technorati.com/tags/kanban" rel="tag"&gt;kanban&lt;/a&gt;, &lt;a href="http://technorati.com/tags/altdotnet" rel="tag"&gt;altdotnet&lt;/a&gt;, &lt;a href="http://technorati.com/tags/video" rel="tag"&gt;video&lt;/a&gt;&lt;/div&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12794.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=wJ1cZGys"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=wJ1cZGys" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=8ysHYHzW"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=V7OhSfot"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=V7OhSfot" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=6vmqu2oZ"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=6vmqu2oZ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/og_lZ2zJEzY" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2008/11/20/kaizenconf-resources.aspx</guid>
            <pubDate>Fri, 21 Nov 2008 04:57:41 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2008/11/20/kaizenconf-resources.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12794.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Tab Completion and Syntax Coloring in IRB</title>
            <category>Tips &amp;amp; Tricks.</category>
            <category>How-To-[Tech].</category>
            <link>http://stevenharman.net/blog/archive/2008/11/13/tab-completion-and-syntax-coloring-in-irb.aspx</link>
            <description>&lt;p&gt;&lt;a title="Tab Completion and Syntax Coloring in IRB" href="http://stevenharman.net/images/stevenharman_net/blog/WindowsLiveWriter/TabCompletionandSyntaxColoringinIRB_149AC/bash_2.png" rel="lightbox"&gt;&lt;img class="right" title="Tab Completion and Syntax Coloring in IRB" height="162" alt="Tab Completion and Syntax Coloring in IRB" src="http://stevenharman.net/images/stevenharman_net/blog/WindowsLiveWriter/TabCompletionandSyntaxColoringinIRB_149AC/bash_thumb.png" width="200" /&gt;&lt;/a&gt; Again, this is just another little reminder for myself since I keep forgetting how to do it. Anyhow…&lt;/p&gt;  &lt;p&gt;If you don’t have tab-completion and syntax coloring in your IRB sessions, you’re missing out! But thanks to both some kick-ass terminals and Ruby itself, you can get both in just a few simple steps.&lt;/p&gt;  &lt;h3&gt;As easy as 1, 2, done!&lt;/h3&gt;  &lt;p&gt;Assuming you’ve already got Ruby and &lt;a title="Installing RubyGems in Cygwin" href="http://stevenharman.net/blog/archive/2008/11/12/installing-rubygems-in-cygwin.aspx"&gt;RubyGems installed&lt;/a&gt;, fire up a terminal window and install the &lt;a title="Pablotron: Wirble" href="http://pablotron.org/software/wirble/" rel="external"&gt;Wirble&lt;/a&gt; gem:&lt;/p&gt;  &lt;div class="dropshadow"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;gem install wirble&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Next, open (or create it if it doesn’t exist) the &lt;code&gt;.irbrc&lt;/code&gt; file in your home folder, typically located at &lt;code&gt;~/.irbrc&lt;/code&gt; in Linux, OSX, and Cygwin environments, and add the following:&lt;/p&gt;

&lt;div class="dropshadow"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;require &lt;span class="str"&gt;'rubygems'&lt;/span&gt;
require &lt;span class="str"&gt;'wirble'&lt;/span&gt;
Wirble.init
Wirble.colorize&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Restart your terminal, fire up an IRB session, and enjoy!&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7ae74757-1381-4357-8411-b31fa46baf34" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/ruby" rel="tag"&gt;ruby&lt;/a&gt;,&lt;a href="http://technorati.com/tags/irb" rel="tag"&gt;irb&lt;/a&gt;&lt;/div&gt;&lt;img src="http://stevenharman.net/blog/aggbug/12793.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=2sEdwhWx"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=2sEdwhWx" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=DUjdi12B"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=IzCmGlM2"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=IzCmGlM2" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevenharman.net/~f/stevenharman?a=wNOf7XfY"&gt;&lt;img src="http://feeds.feedburner.com/~f/stevenharman?i=wNOf7XfY" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/azpMBRFaEuU" height="1" width="1"/&gt;</description>
            <dc:creator>Steven Harman</dc:creator>
            <guid isPermaLink="false">http://stevenharman.net/blog/archive/2008/11/13/tab-completion-and-syntax-coloring-in-irb.aspx</guid>
            <pubDate>Thu, 13 Nov 2008 11:26:00 GMT</pubDate>
            <comments>http://stevenharman.net/blog/archive/2008/11/13/tab-completion-and-syntax-coloring-in-irb.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://stevenharman.net/blog/comments/commentRss/12793.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>
