About the author

Steven HarmanSteven Harman is a passionate developer who believes that writing great software isn't just a job, its a craft.

ASP.NET MVP

For recent posts and more about me, scroll to the bottom.

Subscribe

  • Subscribe to my feed. via RSS
  • Subscribe via email via email

Jobs

Badges

  • Subtext Project
  • Support Subtext
  • HiddenNetwork.com Banner

Being Lazy with Rake

I’ve noticed Rake has been gaining some traction within the .net community as of late, or at least within a certain segment of that community.

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.

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 SCM commands, compiling code, running specs, etc.

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

   1:  desc "Launch the solution in Visual Studio"
   2:  task :sln do
   3:    Thread.new do
   4:      system 'devenv #{@props[:solution_path]}'
   5:    end
   6:  end

This is a pretty simple task:

  • spins up a new thread within a block
  • then opens a new subshell via the system command
  • launches Visual Studio (via devenv) passing the path to the solution file.

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.

> rake sln

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 No Mouse Thursdays!

Full Disclosure: I didn’t come up with this little time saver on my own. I was inspired & then stole it from Aaron Jensen, though I’m sure he was motivated by a similar level of laziness. :)

kick it on DotNetKicks.com

Technorati Tags: ,,

Toward a Better Use of Context/Specification

If you’ve hand-rolled your own Context/Specification apparatus to support your test spec-first lifestyle, you’ve likely got a base class that looks something like the following:

   1:  public abstract class concerns
   2:  {
   3:    [SetUp]
   4:    public virtual void setup_context()
   5:    {
   6:      context();
   7:    }
   8:   
   9:    protected virtual void context() {}
  10:   
  11:    protected virtual void decontext() {}
  12:   
  13:    [TearDown]
  14:    public virtual void cleanup_context()
  15:    {
  16:      decontext();
  17:    }
  18:  }

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 MbUnit, adding a couple of hook methods that are responsible for

  1. setting up the context before an individual specification - context
  2. optionally doing any necessary teardown after each specification – decontext

An example

Using this base class, we’ll end up with specs that might looks something like

   1:  using Skynet.Core
   2:   
   3:  public class when_initializing_core_module : concerns
   4:  {
   5:    SkynetCoreModule _core;
   6:    
   7:    public void context()
   8:    {
   9:      //we'll stub it...you know...just in case
  10:      var skynetController = stub<ISkynetMasterController>();
  11:      _core = new SkynetCoreModule(skynetController);
  12:      _core.Initialize();
  13:    }
  14:    
  15:    [Specification]
  16:    public void it_should_not_become_self_aware()
  17:    {
  18:      _core.should_not_have_received_the_call(x => x.InitializeAutonomousExecutionMode());
  19:    }
  20:    
  21:    [Specification]
  22:    public void it_should_default_to_human_friendly_mode()
  23:    {
  24:      _core.AssessHumans().should_equal(RelationshipTypes.Friendly);
  25:    }
  26:    
  27:    // more specifications under this same context
  28:    // ...
  29:  }

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 classic unit testing 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 TDD is the_use_of_underscores, intention revealing names, and the context hook method.

Is that really any different?

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.

More directly, with Context/Specification we’ll often have many fixtures per class/feature/functional area 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.

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.

Make it explicit!

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? YES!

Consider the following tweak to the concerns base class

   1:  public abstract class concerns
   2:  {
   3:    [FixtureSetUp]
   4:    public virtual void setup_context()
   5:    {
   6:      context();
   7:    }
   8:   
   9:    protected virtual void context() {}
  10:   
  11:    protected virtual void decontext() {}
  12:   
  13:    [FixtureTearDown]
  14:    public virtual void cleanup_context()
  15:    {
  16:      decontext();
  17:    }
  18:  }

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

  • requires side effect free specifications
  • guides us toward smaller, more focused contexts
  • might actually make our specs run faster!

As for the running faster bit, that is not guaranteed as it really depends on how you were writing your specs before making this change.

Some things to watch for

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.

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.

Notes:

The portions of this article relating to changing from a standard context set up to a once-per-fixture style apply to most of the hand-rolled Context/Specification base classes I’ve seen in the wild.

If, however, you are using a tool like MSpec, then you’re in good shape as Aaron 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.

kick it on DotNetKicks.com

So Long Columbus, and Thanks for All the Fish!

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.

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.

Speaking of the biz, the decision to leave Quick Solutions was not an easy one. QSI 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.

So what’s next for me?

I’m headed to The ATL

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.

And then on the 16th, I’ll be starting my new gig as member of the rockin’ VersionOne 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.

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. Sweet, right!

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.

So long, and thanks for all the fish!

A Little More Sugar for Testing Routes in asp.net MVC

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 OOTB with asp.net MVC, I decided to lean on the great work Ben Schierman did in his fluent route testing extensions.

I whipped together a quick extension method that allows me to do the following:

   1:  public class when_requesting_a_gif_file : with_routes_configured
   2:  {
   3:      [Test]
   4:      public void should_ignore_the_route()
   5:      {
   6:          "~/my_file.gif".ShouldBeIgnored();
   7:      }
   8:  }

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 RouteHandler responsible for the given route pattern was a StopRoutingHandler. It looks something like this:

   1:  public static class RouteTestingExtensions
   2:  {
   3:      public static RouteData ShouldBeIgnored(this string relativeUrl)
   4:      {
   5:          RouteData routeData = relativeUrl.Route();
   6:          routeData.RouteHandler.ShouldBeOfType<StopRoutingHandler>();
   7:   
   8:          return routeData;
   9:      }
  10:  }

And that's all there is to it!

I’ll be submitting I have submitted this as a patch 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!

Technorati Tags: , , ,

kick it on DotNetKicks.com

A Sketch of our Ideation Pipeline

Initial sketch of our Ideation Pipeline This is an initial sketch of an Ideation Pipeline 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.

While we probably should have done a full on Value Stream Map, 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.

At any rate, later today I’ll be turning this loose sketch into a physical Kanban board that we’ll used to track and pull ideas through our ideation process, and feed the resulting features into our development process.

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!

Starting with an Idea

Our process starts with an idea. An idea can be nearly anything that someone thinks 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.

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.

And what does deliver value mean?

Value is…

Seen though the eyes of those who pay for, use, and derive value from the systems we create.

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.

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 Never state. In the physical world that means the Idea Kanban is taken off the board.

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?

YES, exactly! 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? DMZ that stuff!

Ready for Decomposition

Right now we have no queue limits on our Ready for Decomposition queue because we’re

  • thinking our throughput will be high enough to keep the queue short anyhow
  • going to help our customers be honest with themselves and diligent in determining which ideas really will provide value

However, if we find this queue to be a bottleneck, or a source of thrashing, we’ll likely put a limit on it.

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.

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 (MMF), 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.

When to decompose?

Idea decomposition is not a regularly scheduled activity, but is triggered by a downstream need for Feature Cards. That is, ideas are pulled through the Ideation Pipeline by some downstream activity that will move the idea closer to providing value. We’re pulling from Concept to Cash!

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.

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!

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!

On to the development pipeline!

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!

Other Resources

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 Kanban Software Development.

Technorati Tags: ,,,

Saving the World via… TDD?

Hot on the heels of my wildly (in)famous “When Should I Write Tests?” post, I have another fun tidbit about testing to share with you. Though, to be honest, I found this gem via my buddy Scott C Reynolds, so I can’t take all – actually, I can’t take any – of the credit.

Anyhow, Scott posted a great little snippet of code that does a couple of things:

  1. Shows the gist of Context/Specification style specs in use.
  2. Ensures we won’t need John Connor’s help after all.
using Skynet.Core

public class when_initializing_core_module
{
    ISkynetMasterController _skynet;

    public void establish_context()
    {
        //we'll stub it...you know...just in case
        _skynet = new MockRepository.GenerateStub<ISkynetMasterController>();
        _skynet.Initialize();
    }

    public void it_should_not_become_self_aware()
    {
        _skynet.AssertWasNotCalled(x => x.InitializeAutonomousExecutionMode());
    }

    public void it_should_default_to_human_friendly_mode()
    {
        _skynet.AssessHumans().ShouldEqual(RelationshipTypes.Friendly);
    }
}

public class when_attempting_to_wage_war_on_humans
{
    ISkynetMasterController _skynet;
    public void establish_context()
    {
        _skynet = new MockRepository.GenerateStub<ISkynetMasterController>();
        _skynet.Stub(x => 
            x.DeployRobotArmy(TargetTypes.Humans)).Throws<OperationInvalidException>();
    }

    public void because()
    {
        _skynet.DeployRobotArmy(TargetTypes.Humans);
    }

    public void it_should_not_allow_the_operation_to_succeed()
    {
        _skynet.AssertWasThrown<OperationInvalidException>();
    }
}

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.

But as a matter of full disclosure, here is a link to the original code on pastie.org.

kick it on DotNetKicks.com

When Should I Write Tests?

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.

So, inspired a conversation with my friend Corey, 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:

Go give them a read, I think you’ll get the gist pretty quickly.

(Thanks also to Brian Liles for the inspiration)

Technorati Tags: , , ,

kick it on DotNetKicks.com

VNC to a Headless Ubuntu Box

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) CI 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!

I installed the latest Ubuntu bits, 8.04 (Hardy Heron) 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.

Granted, most of the work I’d need to do could be accomplished via SSH, but there were a few things I was going to need a GUI for – I needed remote desktop! Or just VNC. :)

Going headless

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.

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.

VNC Server, to the rescue!

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.

  1. SSH into the box and install TightVNCServer
    • sudo apt-get install tightvncserver
  2. Set Gnome to start when your VNC session starts
    • vi ~/.vnc/xstartup
    • #!/bin/sh
      
      xrdb $HOME/.Xresources
      xsetroot -solid black
      gnome-session &
  3. Start the VNC Server
    • vncserver –geometry widthxheight –depth 24
    • You will probably be prompted to enter a password that you'll use later to connect to this VNC session... so enter one!
  4. Start your VNC client on the remote machine, enter the password from step 3, and enjoy!

One side note. After logging into my VNC session I noticed that my keyboard mappings were all jacked-up. For example, typing asdf would result in abfh. After some searching, this appears to be an issue w/Gnome, but luckily I also found a workaround.

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 use your Google-fu!

Technorati Tags: ,,

KaizenConf Resources

stone bridge Even though the Continuous Improvement in Software Development Conference 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.

Get the videos

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.

The primary location to find information on any of the pre-conference workshops or the sessions themselves is at the KaizenConf wiki. If you’re looking for the videos, you’ll want to pay particular attention to the media page.

Lean Software Engineering

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…

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:

Pull, Don't Push - Lean Systems and Kanban

Workshop Description (from Dave Laribee's original post on the workshops):

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.

We’ve got nearly three hours of video from this workshop.

  1. Dave discusses some of the reasons, principles, and basics of Lean Software Development
  2. Value Stream Mapping - a real-life example
  3. Building a Kanban Board

Kanban in Small Teams

I can’t take any credit for this one, but I can give credit to Ryan Kelley and the Los Techies crew for getting this video ready.

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.

You can read more info about this session at the wiki. Oh, and be sure to check out the video for the full impact!

More to come…

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.

Always be Improving!

kick it on DotNetKicks.com

Technorati Tags: , , , ,

Tab Completion and Syntax Coloring in IRB

Tab Completion and Syntax Coloring in IRB Again, this is just another little reminder for myself since I keep forgetting how to do it. Anyhow…

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.

As easy as 1, 2, done!

Assuming you’ve already got Ruby and RubyGems installed, fire up a terminal window and install the Wirble gem:

gem install wirble

Next, open (or create it if it doesn’t exist) the .irbrc file in your home folder, typically located at ~/.irbrc in Linux, OSX, and Cygwin environments, and add the following:

require 'rubygems'
require 'wirble'
Wirble.init
Wirble.colorize

Restart your terminal, fire up an IRB session, and enjoy!

Technorati Tags: ,