Tuesday, September 11, 2012

Configuring SEP Kanban board

In my last post, I showed how I’ve modified the State field of my TFS Work Item definitions to resemble my Kanban workflow.  This post we’ll take a look at how I’ve configure my digital board and highlight the pros and cons of my current approach. Maybe you’ll find this useful, maybe you’ve got some recommendations – either way, I’d love to hear from you.

Setting things up

  1. Download and install the SEP Digital Kanban board: http://www.sep.com/labs/teamworks/
  2. Run the MSI. Defaults all the way through.
  3. Run the app. You’ll need to configure the board with a few settings.
  4. Pick a server:

    sep-choose-server

  5. Select your TFS Server:

    sep-tfs
  6. Select your TFS project and select a Query that returns all your work items. I have a small query to return only Tasks and Bugs: 

    sep-project
  7. In order to get the workflow correct, you’ll need to manually order the States of the Work Item. Change the Work Item States –> Order.

    sep-options

    sep-options-panel

    The Item states should be in this order:

    • Proposed
    • Active
    • Selected
    • In Development
    • Ready for Test
    • Testing
    • Acceptance
    • Closed

  8. Depending on your Project collection, you may have additional work item definitions with their own states. You may have to turn off any states that aren’t included in our work item states. (This screen shot shows Resolved, Design and Ready states have been turned off)

    sel-visibility
  9. Set up some limits.

    sep-limits 

Cool Features

Touch enabled: While the main feature that I was interested in was representing my tasks in TFS, what sold me on this tool was the fact that it was designed for touch. My HP TouchSmart now operates as our digital kanban board.

Swim lanes: Another great feature is the ability to view the features in their own collapsible Swim Lane. There are many great uses for swim lanes such as grouping by Area, Iteration, Priority, Assigned to, Triaged, etc. Most scalar value fields can be used. What’s also great about this feature is that you can simply drag a work item into a swim lane to assign that field value. This makes it easy to keep your work items organized.

Create or Edit Work Items: The tool takes advantage of the form layouts defined in the work item definition, so you can get the same TFS Team Explorer editor experience right on your Kanban board. Large buttons at the top of the user-interface make it simple to add new bugs or tasks as they arrive, and I can open an item from a context-menu to get or edit details about the task at hand.

Caveats and Annoyances

Tasks and Bugs: Unfortunately, I’m only tracking Task and Bug work items because these are the items that I’ve customized. I would like to Use Stories where I describe the work as a high level story and then realize that effort in tasks. At the moment, I’m using TFS 2008 which doesn’t support hierarchal tasks, so I’m kind of stuck on that.  If I could track hierarchal tasks, I’m not entirely sure how I would use this tool – where should the Stories appear on the board if only some of the development tasks are complete?

No sub-columns: One of the features that this tool lacks is that ability to create sub-columns. Ideally I would like to treat Development as one column with two sub-columns (“In Development” and “Ready for Test”) and put a WIP limit on Development. Having this capability highlights testing bottlenecks and would ensure that the development team is invested in seeing their completed efforts are delivering into the client’s hands.

No central configuration: While I’m sure that the target usage for this application is to use it on a touch-device as a whiteboard replacement, the tool doesn’t offer any means to save the configuration externally or toggle between configurations. This is a minor annoyance because most of my team members are jumping on board with this tool to provide their status updates. Also, as I have multiple projects, a means to jump between configurations would be ideal.

All in all, it’s a great resource.

My next post will talk more about customizations to the Work Item definitions that support my workflow.

Friday, September 07, 2012

Using Kanban with TFS

I’ve been actively campaigning for Kanban within our organization. This means giving lunch info-sessions, lending my ear to projects that need a boost, speaking with management and project managers. What I find so fascinating is that people get charged by such a simple concept. It can’t be this easy – but it is – and it’s applicable to most projects. Really? Really.

I’m thrilled to see people “get it”, because it’s easy to draw parallels between work as a pipeline and continuous delivery. Concepts like “push-to-deploy”, continuous integration and regression testing graft directly to parts of your workflow. And while the core concepts of continuous delivery aren’t prerequisites to Kanban, they are certainly mutually beneficial. By leading with Kanban, it’s easier to see value proposition of continuous delivery.

A common theme from all my discussions is I strongly recommend teams “resist the urge to replace a whiteboard with software”. Software can be a trap if applied too early to the process. Pick the wrong tool and you’ll spend your time worrying about tooling rather than the issues that are preventing you from delivering value. Nothing beats the immediate, tactile capabilities of a post-it note moving from one column to another. Focus on the workflow, foster adoption within the team, optimize and then find software to fit your needs. It should rarely be the other way around.

Unless of course, your team is remote.

I’ve heard of some innovative ways to get around this limitation, including a webcam pointed at your Kanban board. This seems like too far a stretch for me, and it’s time for my project to move our spreadsheets and post-it notes into a more centralized digital format.

While there are many cloud-based solutions, a critical feature for me is to own the data. And integrate directly with Visual Studio. (Okay, two key features). Team Foundation Server does Work Items. Let’s start there.

Customizing Work Item Definitions

Out of the box, the definition for Task has all the fields we need to implement our Kanban workflow. The main customization that we need to make is to the State field: we’ll model the various stages of our workflow using this field.

Our current workflow looks something like this:

  • Proposed: This is our backlog
  • Active: Items that will be included in this release.
  • Selected: These are items that we will develop next.
  • In Development: Items being actively worked on.
  • Ready for Test: Development is complete and is pending deployment or verification.
  • Testing: Items that are being validated by testers.
  • Acceptance: Items at are ready for client review.
  • Closed: Completed items.

We’ll need to model these various states in our work item definition, which we can retrieve from TFS using the following command line:

witadmin exportwitd /collection:https://<tfs-server-name> /p:<project-name> /n:Task /f:task.xml

Our State field is represented in the work item definition as:

<witd:WITD application="Work item type editor"
           version="1.0"
           xmlns:witd="http://schemas.microsoft.com/VisualStudio/2008/workitemtracking/typedef">

  <WORKITEMTYPE name="Task">

    <FIELDS> <!—- simplified for clarity -->

      <FIELD name="State" refname="System.State" type="String" reportable="dimension">
        <HELPTEXT>The workflow state of the task</HELPTEXT>
      </FIELD>

    </FIELDS>

    <WORKFLOW> <!-- simplified for clarify -->

      <STATES>
        <STATE value="Proposed" />
        <STATE value="Active"/>
        <STATE value="Selected" />
        <STATE value="In Development" />
        <STATE value="Ready for Test" />
        <STATE value="Testing" />
        <STATE value="Acceptance" />
        <STATE value="Closed" />
      </STATES>

    </WORKFLOW>

  </WORKITEMTYPE>
</witd:WITD>

Transitioning between States

One of the powerful features of customizing the work item definition is the ability to define rules that govern how the item transitions between states.  There is a bit overhead to define these transitions and it can become cumbersome if you have a lot of states, but overall this is a good exercise to formalize what each column means and why something would move from one state to another.

State transitions are fairly easy but there are a few small caveats:

  • You must provide a default state (transitioning “” to “Proposed”)
  • Each transition must have a default reason, plus any number of additional reasons.
  • Any transition that is clearly not defined is not supported.

There are a lot of neat features that you can define here, some of which will have to wait for another post, but here’s a quick excerpt that demonstrates state transitions:

<witd:WITD application="Work item type editor" 
           version="1.0" 
           xmlns:witd="http://schemas.microsoft.com/VisualStudio/2008/workitemtracking/typedef">
    <!-- edited for clarity -->

    <WORKFLOW>
        <!-- snip -->
        
        <TRANSITIONS>
            <TRANSITION from="" to="Proposed">
              <REASONS>
                <DEFAULTREASON value="New" />
              </REASONS>
            </TRANSITION>
            <TRANSITION from="Proposed" to="Active">
              <REASONS>
                <DEFAULTREASON value="Scheduled in Release" />
              </REASONS>
            </TRANSITION>
        
            <!-- not shown:
                proposed -> development
                proposed -> closed

                active -> selected
                active -> development
                active -> proposed
                active -> closed
    
                selected -> development
                selected -> active

                development -> ready for test
                development -> selected
                development -> active

                ready for test -> testing
                ready for test -> development

                testing -> acceptance
                testing -> ready for test
                testing -> development
                testing -> selected
                testing -> active

                acceptance -> closed
                acceptance -> active

                closed -> active
             -->
    </WORKFLOW>

</witd:WITD>

With our customizations in place, we can push our work item definition back to TFS:

witadmin importwitd /collection:<server-name> /p:<project> /f:task.xml

Now when we open a Task definition, we see that the State transition drop-down is constrained by the transitions we’ve defined and the Reason column is prepopulated with our reasons.

WITD-state-transitions

Visualizing TFS Work Items in a Kanban tool

TFS has a rich API and many integrations available (especially with Office stack) but I certainly wouldn’t have gone through all of this trouble if there wasn’t a replacement for my whiteboard and post-it notes.

I recently found this free tool, provided by SEP, that does most of things I want. Because the application supports touch, I’m able to put my HP TouchSmart to good use.

Kanban-example

My next post will talk more about setting up the SEP teamworks tool.

Tuesday, September 04, 2012

A week with Windows Phone 7

I realize I’m probably a bit late to the party on this blog post as Windows Phone 8 is around the corner, but worth writing about anyway.

I've been an iOS boy for a long time, starting with my trusty 3G in 2008 and my iPhone 4 in late 2010. But when my iPhone 4 was stolen, my options here in Canada were pretty limited. I could either replace my iPhone 4 for over $600, or count the months remaining on my 3 year contract until I could afford an upgrade, where each month was a $20 savings from the $600. Disappointed and rejected, I reluctantly plopped a new SIM into my old iPhone 3G and over the course of a few months I began to realize the crushing effect of Apple's development philosophy: "Long live new hardware! Old hardware be damned."

I got tired waiting, and on a whim I scanned kajiji for used phones. I stumbled upon a lightly used Nokia Lumina 710 for a little over $100 – a bargain compared to my iOS options. As a windows developer who knows a thing or two about WPF and XAML, I couldn't resist.

First impressions

Although I want to focus on the Windows Phone operating system, I need to remark on the device a bit. As a phone, the Nokia performs well, fits comfortably in your hand, has a bright screen and a decent 5 megapixel camera. This device features a dedicated button for the camera which can bring the device out of stand-by so that you can use it as a camera, a feature all phone should have if they don't already.

It seems like a funny feature to showcase, but I'm quite impressed by the speakerphone, which takes up sizeable area of the lower back of the phone. I’ve found this feature to be lacking in both my iPhone and iPad, but now I can actually use the speakerphone to have conversations with people in the room, or hear the dialog in a YouTube video.

My only complaint is that the hardware buttons at the bottom of the device can't be used to bring the device out of stand-by – that feature is exclusively owned by the power button on the top. I don't know if this behavior is something specific to this Nokia device, but I find myself pressing these buttons constantly – an old habit that this iOS'er is certainly having a hard-time breaking.

User Interface

So far, I'm really quite impressed with my Windows Phone. From a look-and-feel perspective, the interface is a slick metro theme. Scrolling is smooth and transitions between screens are animated. Most importantly, applications start quickly and are responsive.

Hardware Buttons

Windows phones have three hardware buttons: "back", "windows", "search". The windows button can be pressed at any time and returns you to the Start screen where you can launch applications. More on the search button later.

If you’re used to iOS where navigating through an application is done through software-based buttons, the “back” button seems like an oddity the first time you use it.  Most applications in Windows Phone rely on the back button to provide backward navigation, similar to the behaviour of the back button in a web browser. However, if the application has reached its initial starting point, the back button will close the application and return you to the start screen.  If you have multiple applications open, the back button will close the current application and return you to the previously running application – this seems peculiar at first.  Alternatively, you can press-and-hold the back button which will allow you to switch between applications, much like switching tabs in your browser.

It's funny that after relying on software-based buttons in iOS for so long, I was reluctant to switch to hardware-based buttons for aesthetic reasons and it took a while to get used to. Once you've acclimatized to having these buttons, you realize that most applications take advantage of this concept so their user-interfaces aren't cluttered with software buttons. The Windows Phone operating system builds upon this by providing a consistent place in applications for software buttons, called the app bar, located at the bottom of the screen just above the hardware buttons. These two concepts work really well together and they quickly become second nature.

After a few days, I found myself wanting to tap the left-side of my iPhone whenever I picked it up.

Customization

On the iPhone, you can tell a lot about someone’s personality not only by the way they've customized the outside of the device but by the way they've arranged their applications: what's on their home screen? what's in the dock? With Windows Phone, i can drag tiles around to personalize my start screen, though it doesn't have the same feeling as folders and multiple screens on iOS. I'm not saying this is bad, it's just different. It’s stripped down simple. So simple, it works brilliantly.

Apart from the start screen, I can swipe to the right to bring up a full list of applications, which are sorted alphabetically. It's easy to find an application if you know its name, but grouping them by category or folder like Windows 8 would be a huge step up. It took iOS a few releases to introduce folders, maybe a future release will support this.

The phone also supports a simple theming concept which is comprised of a background and accent colour. The theme is based on the concept that darker colours use less power for the OLED screen. The accent colour is picked up by most applications and changes the colours used by the main home screen.

You can also customize the images on the lock screen and customize ringtones and other sounds. (I am so freaking bored with iPhone’s notifications and reminders.)

Live Tiles / Start Screen

In Windows Phone, the tiles are "live", meaning that each application can provide additional information to the Start screen. Whereas iOS applications are limited to small numeric overlays overtop of their applications (a handful of Apple applications like Weather and Calendar update their icons to reflect current conditions and date), Windows Phone allows applications to fully customize the front and back of their tiles.

As you would expect, the Weather application shows an icon for the current weather conditions with the current temperature and the Calendar application shows the time and details of your next appointment. Some of the apps provide a much more interesting display, like the Contacts app creates an animated mosaic of my friends cover photos, or the Photos app which rotates through some of my favourites.

Where the Live Tiles feature rocks is that some applications let you pin individual elements of the application to the Start screen. Most notably, I pinned my wife’s contact card to the start screen which shows me her photo and recent activity. Other apps, like FourSquare let you pin things like locations. It’s a mix between developer flexibility and user customization.

In the end, the Home Screen becomes more than just a launching point for your favourite applications – it’s a personal dashboard that provides meaningful information at a glance. This is extremely powerful.

The Social Connection

Windows Phone is touted as being great as a "social" phone, and it's easy to see how that connection is made. When you first turn the device on, my first inclination is to setup my address book. I started with my Google account because this holds my contacts, email and a few personal calendars. Easy.

But Windows Phone also natively supports Facebook. Following the same process to hook up my Google account, I plugged in my Facebook credentials and something magical happened: the phone merged my overlapping contacts between online providers (Facebook, Google, Windows Live, Twitter, LinkedIn) into a single holistic view. Not just their contact details, but their status updates and online photos are instantly available from their contact card. This alone is pretty awesome but it goes one further – all contact touch-points from the phone are also seen in the history for the contact: emails, phone calls, text messages are all in one place.

The social network integration in the phone runs deep. All of my Facebook photo albums are immediately available from the phone’s photo gallery. I can post to twitter, Facebook and LinkedIn simultaneously. The built in Camera application lets you post pictures and videos to Facebook with a single click. I’ve been more active on Facebook this month without ever launching Facebook. Cool.

Other Perks

There are many other neat features in Windows Phone 7, but here’s a few notables:

  • Predictive Text: While iOS doesn’t provide auto-correct suggestions until you’ve misspelled or typed most of a lengthy word, WP7 provides a list of possible words above the keyboard as you type. The list is scrollable left/right and often provides suggestions that are exactly what you need, or darn close.
  • Search: One of the hardware buttons is for “search” which at first glance is just a shortcut for Bing. However, at the bottom of the search interface are three software buttons: one provides a handy feature to search by speaking to the device, the second leverages a built-in QR-Code (and MS-Tag) scanner, the third is a music search that can identify the currently playing song.
  • Speech: A slightly hidden feature, if you hold the windows key down for a second, a dialog will prompt you for voice commands. It’s not quite Siri, but you can text a message to someone without looking at the screen.
  • Office: Windows Phone 7 ships with a mobile version of Office, complete with OneNote.
  • Copy/Paste: While iOS didn’t have this until several releases in, the copy/paste feature within Windows Phone is pretty intuitive. And, it’s part of the initial release (jab, jab).

Drawbacks

Much like iOS users pined for Copy-Paste, Windows Phone has a few short comings.

  • Screen Capture. Surprisingly, Windows Phone does not let you take pictures of the current screen. This is a bit baffling, but apparently coming in the next release. There’s a way to get screen-captures of the device but it requires the device to be registered with a paid-developer account. (That sucks. I will post screen-shots once I get my accounts sorted out)
  • App Store. This is by far the biggest challenge for the platform as the lack of applications makes it clear that this is the forgotten player in this space. Although I hope to write a few applications, the platform currently lacks the critical day-to-day apps like online-Banking. These apps are desperately needed, but with the upcoming Windows 8 and overlapping Windows 8 Phone release eminent, it’s likely we’ll see a catch-up effect in the App Store.

Conclusion

I dig the Windows Phone platform. And if you get a chance to play with one, give it a shot – it will surprise you.

The real question is whether I will buy a Windows 8 phone or an iPhone 5 when it’s announced in a few months. Depends on what happens in the iPhone space, but it’ll have to be really convincing.  I’m more than willing to try out the next generation of Windows 8 phones.

Monday, March 05, 2012

How I organize my Local TFS Workspaces

It happens several times on most projects. Developer one, let’s call him Andy, adds a third-party library into the source control repository that isn’t referenced anywhere in the Visual Studio solution file that the team uses. Andy also modifies a few files that depend on this new library and checks his changes in. Developer two, let’s call him Eric, gets the latest from source control by right-clicking the top of the Solution in the Solution Explorer and selecting “Get Latest (recursive)” from the context menu. Although Andy’s local workspace and the build server work fine, Eric believes he has the latest but his code won’t compile.

It’s a frustrating problem with an easy fix: just get the latest copy of the source and rebuild the solution. You can get the latest from the Source Control Explorer in Visual Studio, or open a Visual Studio Command-prompt and issue this command at the root of your solution:

tf.exe get /recursive

I’ve worked to remedy this problem with my teams in several ways, including special buttons you can add to your IDE to make getting to the Source Control Explorer window faster. But when pair-programming on someone else’s machine, my buttons aren’t always available so I drop down to command-line as preferred choice. However, this sometimes has mixed results. If the command-line can’t figure out which workspace you’re in, sometimes it will get the latest from all local workspaces.

I don’t have this problem because I structure my workspaces differently than you. Here’s how I do it.

Multiple Workspaces per Client

This step is optional, but I think it’s worth mentioning. Rather than use a single workspace for all clients, I create one or more workspaces that reflect the client that I’m writing code for. To keep this information visible, I name the workspace after the client instead of the computer name.

TFS-AddWorkspace

I separate my TFS-Workspaces by client for a few reasons:

  • Some of my clients have their own repository which requires me to create a workspace for their server.
  • When I finish work with a client, I can safely delete an entire workspace without concern of breaking server-mappings for other clients.

Having multiple workspaces for the same client allows me to check out the same branch more than once. This allows me to:

  • Use an older copy of the source to reproduce a defect, validate unit tests or to run code analysis
  • Work on multiple defects in isolation from one another
  • Try out a refactoring in isolation from current development
  • Code review of a co-worker’s shelve-set

The practice of having multiple workspaces may not be required for all projects, but it’s a good habit to form.

Client Workspaces separated using Folders

As stated above, I create multiple workspaces for each client. In order to keep those workspaces organized, I keep them separated in their own folder using a simple naming convention (A,B,C, etc). This makes it simple to remove an entire workspace when no longer needed.

Building upon the folder structure that I outlined in my last post (Using Windows 7 Libraries to Organize your code), my folder structure for a client looks like this:

Client Workspace Name Folder Location
Client1 Client1-A C:\Projects\Infusion\Code\Client1\A
Client1 Client1-B C:\Projects\Infusion\Code\Client1\B
Client2 Client2-A C:\Projects\Infusion\Code\Client2\A

A,B,C is a simple naming convention, and it doesn’t need to get too fancy. I’ve worked with some projects with some long folder names, but I haven’t yet exceeded the 260 character limit with MSBuild.

Putting it all together

With the above in place, I can check out separate copies of the same branch into different folders: Client1\A\trunk, Client1\B\trunk, etc. Opening a command-prompt at the root of my solution and executing:

tf.exe get /recursive

…gets me just the updated code for that branch. I especially love this approach because I can get latest before I open the solution file, which is immensely helpful because I don’t have to wait for Visual Studio to reload projects if they’ve changed.

Code happy.

Organize your Code with Libraries (redux)

A while back, I mentioned how I was using the Document Library feature of Windows 7 to organize the different types of content on my machine. This approach has worked very well for me since I started, though I have made one small adjustment from the original post: I was keeping both my project documents and code files in the same folder and I’ve since deviated from that. At the time this made sense to keep the documents and source code as close together as possible, but it wasn’t very practical in terms of navigating the code from Visual Studio or when working with multiple TFS workspaces.

Here’s an updated snippet from the original post. My “Code” library is comprised of the following folders:

    • C:\Projects\Infusion\Code (my employer) 3
    • C:\Projects\lib (group of common libraries I reference a lot) now using Nuget for this.
    • C:\Projects\Experiments (small proof of concept projects)
    • C:\Projects\Personal (my pet projects)

The main difference is that I’ve added the “Code” folder as the primary container for all my work-related source. Each client that I work with gets their own folder below this root, which provides a convenient way to navigate all of my work projects.

I also now use a “Projects” library that contains an entry for each client. I like this approach because I can set a particular library entry as the default save location, so any time I create a document and click “Save” it will get dumped into a folder for my current client. Here’s a quick peek at my sanitized Project Library.

image_thumb[1]

My next post will show how I organize my Visual Studio workspaces within this structure.

submit to reddit

Monday, February 20, 2012

My first month with Kanban

Just before the Christmas break, I took over an existing project that was approaching a major milestone. It's a great project: a small team, working with a high profile client to build a modular MS Surface application that ships a new release every few months.

You would think that taking over a project in the late stages of development would be a bad thing, however it's been fairly positive experience. Although the project suffered in the beginning as our bandwidth was reduced while I was ramping up, the opportunity to introduce a fresh set of eyes with a different perspective has allowed the team to innovate and challenge their assumptions (I’d like to think it’s been for the better).

One initiative that I felt that the project needed was some form of Agile methodology.  Although we had a set of high level stories that we knew had to be implemented, there was no breakdown of the tasks or ability to gauge progress. Despite this obvious need, I knew Agile was going to be a tough sell: the project has a highly dynamic, fast pace environment where requirements and tasks change daily. Adopting a full-on Agile agile process seemed too formal. I might be able to establish a backlog, maybe some task estimates -- but trying to establish planned iterations with client involvement? Not a chance. Besides, I'd likely wind up losing a good chunk of my day managing the status of tasks and justifying burn down charts to management.

This was a great opportunity to try something new. I had heard about Kanban before, but didn't understand it enough to put it into practice. I found this great eBook (free) that explains Kanban by outlining the differences between Scrum and Kanban. I highly, highly recommend. Download it now.

The following is an account of how we put Kanban in place…

Kanban in a nutshell

Kanban is a very lean process methodology that is based on a subset of agile/scrum. Whereas Scrum comes with rules about how to work with iterations and stories, Kanban comes with nearly no rules at all. In fact, you often have to add your own rules to Kanban in order to align it to your project/organization.

At a high level, Kanban is all about visualizing the work as a workflow on a "Kanban board". User stories are often depicted using sticky-notes, and they travel through the workflow on the board. Although you could easily do the same thing with Scrum, the key difference is that a scrum board would be reset at the end of the iteration. Kanban doesn't have the concept of iterations, so the board is the project.

Visualizing our Workflow

Before we could dive into realizing our project in a sticky-note form, we collaborated a bit to determine what our development workflow would look like. Although our process utilizes graphic designers from time to time, we decided to limit the scope of our Kanban board to the development pipeline only.

As mentioned previously, our process for this project isn’t very well defined. The majority of our work is based on a SharePoint list that our client has access to, and we log defects and work items there. Each day, we pull things from the list and work on them until we reach a deadline for a release or have completed all tasks to the best of our ability. It’s not the best system, but it’s just enough to work. The team decided that the best place to start with our Kanban workflow was in the middle where we were most involved, so we’d have two columns to represent the development tasks:

  • In progress: Items that the team is actively working on.
  • Done: Items that the team has completed development and are ready for testing.

Of course, our process doesn’t end once development is complete. From here, we package up a release and deploy it to a local Surface device in the office where other members of the team can see our progress. The team decided that we should do this more frequently and with some consistency, so we added another column for this:

  • Surface: Items that have been deployed to a local surface machine for verification. If we identify problems with any of these features, they go back to the beginning of our process.

Eventually, once all the stories and tasks have been completed, we bundle up our changes and deploy it to our client’s surface machine for their testing and feedback. The process repeats until the client accepts the current package and it is released to their Surface machines. We represent these steps with another two columns:

  • Client: Items that have been deployed to the clients’ location. It’s rare that stories are rejected by the client, but there’s often a lot of feedback that gets added to the beginning of our pipeline.
  • Live: Items that have shipped.

At this point in the exercise, we’ve captured how things are currently executed on this project. The astute will recognize that the beginning of the workflow is lacking definition – I’ve not outlined how we account for tasks that aren’t actively being worked on, or how effort is prioritized. I’ve deliberately left this out, partly because I feel the pipeline has two distinct parts (an incoming and outgoing flow) but mainly because it’s a good way to explain one of Kanban’s core features: work-in-progress limits.

Keeping the team focused by establishing Limits

Clearly, our workflow will have a column that represents a backlog for our remaining effort. Although I could add it to the beginning of our workflow, which would make our Kanban board look a lot like a standard Scrum burn-down chart, there isn’t anything that would prevent us from falling into our old habits. In a highly dynamic project like this one, there’s a constant barrage of client requests and other noise that is beset with a sense of immediate urgency – most tasks get assigned to a developer and go straight to an “In Progress” state as they arrive. Essentially, if there aren’t any rules about when things are allowed to be considered In Progress, then there aren’t any reasonable expectations for the schedule of that work. This creates a real problem with managing client expectations and keeping track of what tasks people are actually working on. While there’s something to be said about multi-tasking, a team without focus gets nothing done.

To resolve this issue, we take advantage of one of Kanban’s unique features. At the top of our In Progress column, we add a number that represents the maximum limit for items in that column. This is known as a work-in-progress (WIP) limit. Since developers only have one head and two hands, we assume that developers should only work on one task at a time. This is easy math for a team of two developers.

By limiting our In Progress items to 2 we put a spotlight on the items that the team is actively working on, but this also creates a visibility problem about which items will be worked on next. To help visualize the priority of items, we add another column:

  • Accepted: These are the work items that the developers will work on after they complete the In Progress tasks. We refer to them being as “Accepted” because the development team has reviewed the tasks and has committed to delivering these features.

To prevent the Accepted column from getting bloated, we give it a WIP limit of 4. This ensures that the developers have just enough prioritized items in their queue to keep them busy for the day. We could go higher, but 4 is a very manageable number.

Adding Rules and Events

As mentioned previously, Kanban doesn’t have many rules and you need to add your own to suit your needs. Here are a few rules that we’ve established:

  • Our project manager is not able to manage any of the columns except the Accepted and Backlog columns. This means he plays a key role in helping to direct the work towards client expectations. Indirectly this also means that he’s not able to interfere with work in progress.
  • When the Done column has enough items (we’re still trying to figure out a proper WIP for Done) we halt development and deploy what we have to our local Surface machine. We do this to keep the amount of regression testing to a minimum.
  • Before we deploy to the client environment, we must validate the work items against the local surface machine. This ensures that we use the same installation media, and use the items in our Surface column as a list of regression tests. We are actively looking to automate our deployment process so that we can deploy more frequently.

Results so Far

There are some really interesting side-effects from implementing our Kanban board:

Kanban-board

  • The most notable impact is that our stand-ups have changed considerably. Rather than spending 15-20 amnesiac minutes trying to remind each other what each of us did 16 hours ago, we spend a few minutes reviewing the current items on the board and prioritizing next steps. We then talk about the issues. It’s a night-and-day difference from previous projects.
  • Having the board highly visible on our wall simplifies communication and makes managing the tasks much easier. We get immediate feedback when a developer finishes a task because they have to get up from their desk and physically move their item to another column. And since we have an Accepted column that contains prioritized ready-to-go items, there’s never any guess work or wasted allocation trying to figure out what developers should do next.
  • The visual representation of the board makes it easy to gauge the health of the pipeline. If the Accepted column is full at the beginning of the day, I’ll likely get a few extra cycles to focus on development tasks. If the Accepted column is low, I can quickly scan the backlog and determine if we’re going to have any issues.
  • There’s some interesting metrics that come out of tracking the status of the board daily, something I’ll likely write more about in another post. But in short, I count up the number of items in each column at the beginning of the day and add a small journal note that summarizes the changes in the board.  From this I can easily track our last deployment and where the backlog changed.

Challenges

There are a few minor challenges we’ve encountered:

  • From a project management perspective, it’s difficult to gauge remaining effort in hours. Although we’ve applied a sizing rank to our tasks (Small, Medium, Large – where large is 8 hours), it’s difficult to glance at the board and determine if we’ll make a target date. The Kanban eBook suggests that all post-it notes on the board should have the same weight which would solve this problem, but we are still struggling how to group and organize our tasks to fit within this concept.
  • The board only works when we’re all in the office. I’ve adjusted the columns in our SharePoint list to align closely to our board, and there is some duplication of effort trying to keep the board in sync. The system that I’ve found to work best is to ensure that all tasks are born within SharePoint, and they’re considered Pending until there’s a post-it note on our Kanban board. Periodically throughout the week, I spend a few minutes updating our SharePoint list to reflect the board’s current status. The SharePoint list acts as a digital memory that can provide additional details and attachments, but the board is the most accurate representation. There are still some discrepancies between the two systems, and we either need some formal process or tweaks to make this work better.

Conclusion

For the last month, the team has been putting the final touches on a release which has involved completing some features and fixing defects. This type of work changes daily and our Kanban board has allowed us to visualize the outstanding work in a meaningful way. We’ve started having scheduled retrospectives to gather feedback and adjust our process. Generally, that feedback has been positive and we’ve course corrected a few times for the better. The true test will come shortly when we start working on the next release – will the Kanban format work or should we adopt formal sprints?

As a final word, I feel it’s important to mention the feedback that I’ve received from other teams. Some glance at our board and are intrigued, others look at the post-it notes as archaic technology and feel that our process could be brought into the 21st century with some software package. While there may be a great software package for this, the eBook warns about this – all developers will have this reaction. Our Kanban board requires no licenses, doesn’t take time to boot, responds instantly to tactile input and is always on. Besides, there is no equivalent software package that allows you to ceremoniously march a stack of post-it notes around the room as they go live.

Happy coding.

Monday, January 23, 2012

Execute Batch from Visual Studio

Since as long as I can remember, I’ve kept a command-line window open while I worked. It’s a warm fuzzy feeling of how computers used to work. I tend to structure commonly used tasks as msbuild or nant scripts, and then add handy batch files that pass the appropriate parameters to the script.

Unfortunately, most of my team-mates don’t live in the command-line, so running a batch file breaks their traditional flow.

Here’s a short tip on how to execute batch files without having to leave the comfort of the IDE. You’ve probably seen this tip before, but as always, I often use my blog as a digital memory. If it helps you, great.

Visual Studio supports the ability to associate tools and alternate editors for different files. Adding support for batch files is simply a matter of opening the context-menu for a file and choosing “Open With..”. Unfortunately, there’s no mechanism to supply parameters to your program, so adding support for a Command Prompt requires a small subtle hack that passes our parameters to the program we want.

To Associate Batch files to a Custom Command

First, we need to create a simple batch file that passes the arguments that Visual Studio provides onto our batch file.

  1. If you haven't already, add your batch file to your solution. These are best treated as Solution items that aren’t part of your compilation process.
  2. Open notepad and save the following script as C:\ExecuteBatch.cmd
@cmd /c %1

Once this is in place,

  1. Associate the batch file in Visual Studio to the command line by right-clicking on the batch file and choose "Open With...".
  2. In the dialog that appears, provide a name and associate it to the ExecuteBatch.cmd.

image

Optional: You can associate the Command as the default program for this extension, by selecting your custom command and clicking on the “Set as Default” button. Note that if you edit the file frequently you might want to skip this step, but you’ll have to right-click the file and choose “Open With…” anytime you want to run your custom command.

Gotchas & Caveats

Just a few closing points:

  • If you set your custom command as the default, note that there is no confirmation if you accidentally double-click the batch file. If your script is potentially destructive or long-running, you might want to add a prompt at the beginning of the batch file before running.
  • The ExecuteBatch.cmd provided above will close the window immediately after the batch terminates. If you want to review the output of the script before the window closes, you might want to add a pause to the end of the script.
  • Lastly, when adding new scripts to Visual Studio it will perform the default action when the file is added to the solution. If you don’t want to run the script when the file is added, you might want to temporarily assign a different editor (Source Code Editor) before you precede.

Happy Coding.

submit to reddit

Monday, November 28, 2011

Fixing Parallel Test Execution in Visual Studio 2010

As the number of tests in my project grow, so does the length of my continuous integration build. Fortunately, the new parallel test execution of Visual Studio 2010 allow us to trim down the amount of time consumed by our unit tests. If your unit tests meet the criteria for thread-safety you can configure your unit tests to run in parallel simply by adding the following to your test run configuration:

<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="Local" id="5082845d-c149-4ade-a9f5-5ff568d7ae62" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
  <Description>These are default test settings for a local test run.</Description>
  <Deployment enabled="false" />
  <Execution parallelTestCount="0">
    <TestTypeSpecific />
    <AgentRule name="Execution Agents">
    </AgentRule>
  </Execution>
</TestSettings>

The ideal setting of “0” implies that the test runner will automatically figure out the number of concurrent tests to execute based on the number of processors on the local machine. Based on this, a single-core CPU will run 1 test simultaneously, a dual-core CPU can run 2 and a quad-core CPU can 4. Technically, a quad-core hyper-threaded machine has 8 processors but when parallelTestCount is set to zero the test run on that machine fails instantly:

Test run is aborting on '<machine-name>', number of hung tests exceeds maximum allowable '5'.

So what gives?

Well, routing through the disassembled source code for the test runner we learn that the number of tests that can be executed simultaneously interferes with the maximum number of tests that can hang before the entire test run is considered to be in a failed state. Unfortunately the maximum number of tests that can hang has been hardcoded to 5. Effectively, when the 6th test begins to execute the test runner believes that the other 5 executing tests are in a failed state so it aborts everything. Maybe the team writing this feature picked “5” as an arbitrary number, or legitimately believed there wouldn’t be more than 4 CPUs before the product shipped, or simply didn’t make the connection between the setting and the possible hardware. I do sympathize for the mistake: the developers wanted the number to be low because a higher number could add several minutes to a build if the tests were actually in an non-responsive state.

The Connect issue lists this feature as being fixed, although their are no posted workarounds and a there’s a lot of feedback that feature doesn’t work on high-end machines even with the latest service pack. But it is fixed, no-one knows about it.

Simply add the following to your registry (you will likely have to create the key) and configure the maximum amount based on your CPU. I’m showing the default value of 5, but I figure number of CPUs + 1 is probably right.

Windows 32 bit:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\EnterpriseTools\QualityTools\Agent]
"MaximumAllowedHangs"="5"
Windows 64 bit:
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\EnterpriseTools\QualityTools\Agent]
"MaximumAllowedHangs"="5" 

Note: although you should be able to set the parallelTestCount setting to anything you want, overall performance is constrained by the raw computing power of the CPU, so anything more than 1 test per CPU creates contention between threads which degrades performance. Sometimes I set the parallelTestCount to 4 on my dual-core CPU to check for possible concurrency issues with the code or tests.

Epilogue

So what’s with the Connect issue? Having worked on enterprise software my guess is this: the defect was logged and subsequently fixed, the instructions were given to the tester and verified, but these instructions never tracked forward with the release notes or correlated back to the Connect issue. Ultimately there’s probably a small handful of people at Microsoft that actually know this registry setting exists, fewer that understand why, and those that do either work on a different team or no longer work for the company. Software is hard: one small fissure and the whole thing seems to fall apart.

Something within the process is clearly missing. However, as a software craftsman and TDD advocate I’m less concerned that the process didn’t capture the workaround as I am that the code randomly pulls settings from the registry – this is a magic string hack that’s destined to get lost in the weeds. Why isn’t this number calculated based on the number of processors? Or better, why not make MaximumAllowedHangs configurable from the test settings file so that it can be unit tested without tampering with the environment? How much more effort would it really take, assuming both solutions would need proper documentation and tests?

Hope this helps.

Thursday, November 24, 2011

iPhone to PC Adapter

Merry Happy Thanks Giving! I had some time on my hands so I decided to try something new.

Here’s a quick review of my iPhone headset to PC adapter that I bought a few weeks ago. Hopefully this video comes just in time for Christmas ideas and Black Friday shopping.

By the way, Thanks Giving was 5 weeks ago.

Tuesday, November 22, 2011

Static is Dead to Me

The more software I write with a test-first methodology, the more I struggle with the use of singletons and static classes. They’ve become a design smell, and I’ve grown to realize that if given enough care and thought towards a design most static dependencies aren’t needed. My current position is that most singletons are misplaced artefacts without a proper home, and static methods seem like an amateurish gateway to procedural programming.

Despite my obvious knee-jerk loathing for static, in truth there’s nothing really wrong with it -- it’s hard to build any real-world application without the use of some static methods. I continue to use static in my applications but its use is reserved for fundamental top-level application services. All told, there should only be a handful of classes that are accessible as static members.

From a test-driven development perspective, there are several strong arguments against the use of static:

  • Lack of Isolation. When a class uses a static method in another type, it becomes directly coupled to that implementation. From a testing perspective it becomes impossible to test the consuming class without satisfying the requirements of the static dependency. This increases the complexity and fragility of the tests as the implementation details of the static dependency leak into many tests.
  • Side Effects. Static methods allow us to define objects that maintain state that is global in nature. This global state represents a problem from a testing perspective because any state that must be set up for a test fixture must be reset after the test completes. Failure to clean-up the global state can corrupt the environment and lead to side-effects in other tests that depend on this shared state.
  • Inability to run tests in parallel. A fundamental requirement for reliable tests is a predictable, well-known state before and after each test. If tests depend on global state that can be mutated by multiple tests simultaneously then it is impossible to run more than one test at a time. Given the raw computing power of a hyper-threaded, multi-core machine, it seems a crime to design our code that limits testing to only one core.
  • Hidden dependencies. Classes that pull dependencies into them from a static singleton or service-locator creates an API that lies to you. Tests for these classes become unnecessarily complex and increasingly brittle.

An Alternative to Static

Rather than designing objects to be global services that are accessed through static methods, I design them to be regular objects first. There are no static methods or fields. Classes are designed to be thread-safe, but make no assumptions about their lifetime.

This small change means that I expect all interaction to be with an instance of my object rather through a member that is Type specific. This suggests two problems: how will consumers of my class obtain a reference to my object, and how do I ensure that all consumers use the same object?

Obtaining a Reference

Not surprisingly, the problem related to obtaining a reference to my object is easily solved using my favourite Inversion of Control technique, Constructor Injection. While there are many IoC patterns to choose from, I prefer constructor injection for the following reasons:

  • Consuming classes do not have to depend on a specific framework to obtain a reference.
  • Consuming classes are explicit about their required dependencies. This fosters a consistent and meaningful API where objects are assembled in predictable and organized manner rather than randomly consumed.
  • Consuming classes don’t have to worry about which instance or the lifetime of the object they have received. This solves many testing problems as concurrent tests can work with different objects.

The difference between accessing my object through a static member versus an object instance is very subtle, but the main distinction is that using the object reference requires some forethought as the dependency must be explicitly defined as a member of the consuming class.

Obtaining the Same Reference

By forgoing the use of static, we’ve removed the language feature that would simplify the ability to ensure only a single instance of our object is consumed. Without static we need to solve this problem through the structure of our code or through features of our application architecture. Without a doubt it’s harder, but I consider the well structured and tested code worth it (so don’t give up).

Eliminating Singletons through Code Structure:

My original position is that most singletons are simply misplaced artefacts. By this I mean static is used for its convenience rather than to expose the class as a global application service. In these situations it’s far more likely that the static class provides a service that is used in one area of the application graph. I’d argue that with some analysis the abstraction or related classes could be rearranged to create and host the service as an instance thereby negating the need for a singleton.

This approach typically isn’t easy because the analysis requires you to understand the lifetime and relationship of all objects in the graph. For small applications with emergent design, the effort is obtainable and extremely rewarding when all the pieces fit together nicely. The effort for larger applications may require a few attempts to get it right. Regardless of application size, sticking with an inverted dependencies approach will make the problem obvious when it occurs.

An inversion of control container can lessen the pain.

Eliminating Singletons through Architecture:

Perhaps my favourite mechanism for eliminating singletons is to use an Inversion of Control container and configure it with the responsibility of maintaining the object lifetime.

This example shows programmatic registration of a concrete type as a singleton.

private void InitializeGlobalServices(IUnityContainer container)
{
   // configure the container to cache a single instance of the service
   // the first time it is used.
   container.RegisterType<MyServiceProvider>(new ContainerControlledLifetimeManager());
}

The real advantage here is that any object can be made static without rewriting code. As a further optimization, we can also introduce an interface:

private void InitializeGlobalService(IUnityContainer container)
{
   container.RegisterType<IServiceProvider,MyServiceProvider(
       new ContainerControlledLifetimeManager());
}

Conclusion

Somewhere in my career I picked up the design philosophy that “objects should not have a top”, meaning that they should be open-ended in order to remix them into different applications. Eventually the "top" is the main entry-point into the application which is responsible for assembling the objects to create the application.

Dependency Injection fits nicely into this philosophy and in my view is the principle delivery mechanism for loosely coupled and testable implementations. Static however works against this in every regard: it couples us to implementations and limits our capability to test.

The clear winner is dependency injection backed by the power of an inversion of control container that can do the heavy lifting for you. As per my previous post, if you limit usage of the container to the top-level components, life is simple.

Happy coding.

submit to reddit

Monday, October 24, 2011

Guided by Tests–Wrap Up

This post is ninth and last in a series about a group TDD experiment to build an application in 5 7 days using only tests.  Read the beginning here.

This last post is aimed at wrapping up the series by looking back at some of the metrics we can collect from our code and tests. There’s some interesting data about the experiment as well as feedback for the design available.

We’ll use three different data sources for our application metrics:

  • Visual Studio Code Analysis
  • MSTest Code Coverage
  • NDepend Code Analysis

Visual Studio Code Analysis

The code analysis features of Visual Studio 2010 provide a convenient view of some common static analysis metrics. Note that this feature only ships with the Premium and Ultimate versions. Here’s a quick screen capture that shows a high level view of the metrics for our project.

Tip: When reading the above graph, keep an eye on the the individual class values not the roll-up namespace values.

image

Here’s a breakdown of what some of these metrics mean and what we can learn from our experiment.

Maintainability Index

I like to think of the Maintainability Index as a high level metric that summarizes how much trouble a class is going to give you over time. Higher numbers are better, and problems usually start below the 20-30 range. The formula for the maintainability index is actually quite complex, but looking at the above data you can see how the other metrics drive the index down.

Our GraphBuilder is the lowest in our project, coming in at an index of 69. This is largely influenced by the density of operations and complexity to lines of code – our GraphBuilder is responsible for constructing the graph from conditional logic of the model. The maintainability index is interesting, but I don’t hold much stock in it alone.

Lines of Code

Lines of Code is the logical lines of code which means code lines without whitespace and stylistic formatting. Some tools, like NDepend, record other metrics for lines of code, such as number of IL instructions per line. Visual Studio’s Lines of Code metric is simple and straight forward.

There are a few interesting observations for our code base.

First, the number of lines of code per class is quite low. Even the NDependStreamParser which tops the chart at 22 lines is extremely low considering that it reads data from several different Xml Elements. The presence of many small classes suggests that classes are designed to do one thing well.

Secondly, there are more lines of code in our test project than production code. Some may point to this as evidence that unit testing introduces more effort than writing the actual code – I see the additional code as the following:

  • We created hand-rolled mocks and utility classes to generate input. These are not present in the production code.
  • Testing code is more complicated than writing it as there are many different paths the code might take. There should be more code here.
  • We didn’t write the code and then the tests, we did them at the same time
  • Our tests ensured that we only wrote code needed to make the tests pass. This allowed us to aggressively remove all duplication in the production code. Did I mention the largest and most complicated class is 22 lines long?

Cyclomatic Complexity

Cyclomatic Complexity, also known as Conditional Complexity, represents the number of paths of execution a method can have – so classes that have a switch or multiple if statements will have higher complexity than those that do not. The metric is normally applied at the method level, not the class, but if you look at the graph above, more than half of the classes average below 5 and the other half are less than 12. Best practices suggest that Cyclomatic Complexity should be less than 15-20 per method. So we’re good.

Although the graph above doesn’t display our 45 methods, the cyclomatic complexity for most methods is 1-2. The only exception to this is our NDependStreamParser and GraphBuilder, which have methods with a complexity value of 6 and 5 respectively.

In my view, I see cyclomatic complexity as a metric for how many tests are needed for a class.

Depth of Inheritance

The “depth of inheritance” metric refers to the number of base classes involved in the inheritance of a class. Best practices aim to keep this number as low as possible since each level in the inheritance hierarchy represents a dependency that can influence or break implementers.

Our graph shows very low inheritance depth which supports our design philosophy of using composition and dependency inversion instead of inheritance. There are a few red flags in the graph though: our AssemblyGraphLayout has an inheritance depth of 9, a consequence of extending a class from the GraphSharp library and it highlights possible brittleness surrounding that library.

Class Coupling

The class coupling metric is a very interesting metric because it shows us how many classes our object consumes or creates. Although we don’t get much visibility into the coupling (NDepend can help us here) it suggests that classes with a higher coupling are much more sensitive to changes. Our GraphBuilder has a Class Coupling of 11, including several types from the System namespace (IEnumerable<T>, Dictionary, KeyValuePair) but also has knowledge of our Graph and model data.

Class coupling combined with many lines of code and high cyclomatic complexity are highly sensitive to change, which explains why the GraphBuilder has the lowest Maintenance Index of the bunch.

Code Coverage

Code coverage is a metric that shows which execution paths within our code base are covered by unit tests. While code coverage can’t vouch for the quality of the tests or production code, it can indicate the strength of the testing strategy.

Under the rules of our experiment, there should be 100% code coverage because we’ve mandated that no code is written without a test. We have 93.75% coverage, which has the following breakdown:

DependencyViewer-Coverage

Interestingly enough, the three areas of with no code coverage are the key obstacles we identified early in the experiment. Here are the snippets of code that have no coverage:

Application Start-up Routine

protected override void OnStartup(StartupEventArgs e)
{
    var shell = new Shell();
    shell.DataContext = new MainViewModelFactory().Create();

    shell.Show();
}

Launching the File Dialog

internal virtual void ShowDialog(OpenFileDialog dialog)
{
    dialog.ShowDialog();
}

Code behind for Shell

public Shell()
{
    InitializeComponent();
}

We’ve designed our solution to limit the amount of “untestable” code, so these lines of code are expected. From this we can establish that our testing strategy has three weaknesses, two of which are covered by launching the application. If we wanted to write automation for testing the user-interface, these would be the areas we’d want early feedback from.

NDepend Analysis

NDepend is a static code analysis tool that provides more detailed information than the standard Visual Studio tools. The product has several different pricing levels including open-source and evaluation licenses and has many great visualizations and features that can help you learn more about your code. While there are many visuals that I could present here, I’m listing two interesting diagrams.

DependencyGraph:

This graph shows dependencies between namespaces. I’ve configured this graph to show two things:

  • Box Size represents Afferent Coupling where larger boxes are used by many classes
  • Line Size represents the number of methods between the dependent components.

DependencyMatrix-Graph

Dependency Matrix:

A slightly different view of the same information is the Dependency Matrix. This is the graph represented in a cross-tabular format.

DependencyMatrix-Namespaces

Both of these views help us better visualize the Class Coupling metric that Visual Studio pointed out earlier, but the information it provides is quite revealing. Both diagrams show that the Model namespace is used by the ViewModels and Controls namespaces. This represents a refactoring or restructuring problem as these layers really should not be aware of the model: Views shouldn’t have details about the ViewModel; Service layer should only know about the Model and ViewModels; Controls should know about ViewModel data if needed; ViewModels should represent view-abstractions and thus should not have Model knowledge.

The violations have occurred because we established our AssemblyGraph and related items as part of the model.  This was a concept we wrestled with at the beginning of the exercise, and now the NDepend graph helps visualize the problem more concretely. As a result of this choice, we’re left with the following violations:

  • The control required to layout our graph is a GraphLayout that uses our Model objects.
  • The MainViewModel references the Graph as a property which is bound to the View.

The diagram shows a very thin line, but this model to view model state problem has become a common theme in recent projects. Maybe we need a state container to hold onto the Model objects and maybe the Graph should be composed of ViewModel objects instead of Model data. It’s worth consideration, and maybe I’ll revisit this and blog about this problem some more in an upcoming post.

Conclusion

To wrap up the series, let’s look back on how we got here:

I hope you have enjoyed the series and found something to take away. I challenge you to find a similar problem and champion its development within your development group.

Happy Coding.

submit to reddit

Tuesday, October 11, 2011

Guided by Tests–Day Seven

This post is eighth in a series about a group TDD experiment to build an application in 5 7 days using only tests.  Read the beginning here.

Today is the day we test the untestable. Early in the experiment we hit a small road block when our code needed to interact with the user-interface. Since unit-testing the user-interface wasn’t something we wanted to pursue, we wrapped the OpenFileDialog behind a wrapper with an expectation that we would return to build out that component with tests later. The session for this day would prove to be an interesting challenge.

The Challenges of Physical Dependencies

Although using a wrapper to shield our code from difficult to test dependencies is a common and well accepted technique, it would be irresponsible not to test the internal implementation details of that wrapper. Testing against physical dependencies is hard because they introduce a massive amount of overhead, but if we can isolate the logic from the physical dependency we can use unit tests to get 80-90% of the way there. To get the remaining part, you either test manually or write a set of integration or functional tests.

The technique outlined below can be used for testing user-interface components like this one, email components and in a pinch it can work for network related services.

Testing our Wrapper

Time to write some tests for our IFileDialog. I have some good news and bad news.

The good news is Microsoft provides a common OpenFileDialog as part of WPF, meaning that I don’t have to roll my own and I can achieve a common look and feel with other applications with little effort. This also means we can assume that the FileOpenDialog is defect free, so we don’t have to write unit tests for it.

The bad news is, I use this common so infrequently that I forget how to use it.

So instead of writing a small utility application to play with the component, I write a test that shows me exactly how the component works:

[TestMethod]
public void WhenSelectAFileFromTheDialog_AndUserSelectsAFile_ShouldReturnFileName()
{
    var dialog = new OpenFileDialog();
    dialog.Show(); // this will show the dialog

    Assert.IsNotNull(dialog.FileName); 
}

When I run this test, the file dialog is displayed. If I don’t select a file, the test fails. Now that we know how it works, we can rewrite our test and move this code into a concrete implementation.

Unit Test:

[TestMethod]
public void WhenSelectingAFile_AndUserMakesAValidSelection_ShouldReturnFileName()
{
    var subject = new FileDialog();
    string fileName = subject.SelectFile();
    Assert.IsNotNull(fileName);
}

Production Code:

public class FileDialog : IFileDialog
{
    public string SelectFile()
    {
        var dialog = new OpenFileDialog();
        dialog.Show();

        return dialog.FileName;
    }
}

The implementation is functionally correct, but when I run the test I have to select a file in order to have the test pass. This is not ideal. We need a means to intercept the dialog and simulate the user selecting a file. Otherwise, someone will have to babysit the build and manually click file dialog prompts until the early morning hours.

Partial Mocks To the Rescue

Instead of isolating the instance of our OpenFileDialog with a mock implementation, we intercept the activity and allow ourselves to supply a different implementation for our test. The following shows a simple change to the code to make this possible.

public class FileDialog : IFileDialog
{
    public string SelectFile()
    {
        var dialog = new OpenFileDialog();

        Show(dialog);

        return dialog.FileName;
    }

    internal virtual void Show(OpenFileDialog dialog)
    {
        dialog.Show();
    }
}

This next part is a bit weird. In the last several posts, we’ve used Moq to replace our dependencies with fake stand-in implementations. For this post, we’re going to mock the subject of the test, and fake out specific methods on the subject. Go back and re-read that. You can stop re-reading that now.

As an aside: I often don’t like showing this technique because I’ve seen it get abused. I’ve seen abuses where developers use this technique to avoid breaking classes down into smaller responsibilities; they fill their classes with virtual methods and then stub out huge chunks of the subject. This feels like shoddy craftsmanship and doesn’t sit well with me – granted, it works, but it leads to problems. First, the areas that they’re subverting never get tested. Secondly, it’s too easy for developers to forget what they’re doing and they start to write tests for the mocking framework instead of the subject’s functionality. So use with care. In this example, I’m subverting one line of a well tested third-party component in order to avoid human-involvement in the test.

In order to intercept the Show method and replace it with our own implementation we can use Moq’s Callback feature. I’ve written about this Moq’s support for Callbacks before, but in a nutshell Moq can intercept the original method and inbound arguments for use within your test.

Our test now looks like this:

[TestMethod]
public void WhenSelectingAFile_AndUserMakesAValidSelection_ShouldReturnFileName()
{
    // setup a partial mock for our subject
    var mock = new Mock<FileDialog>();
    FileDialog subject = mock.Object;

    // The Show method in our FileDialog is virtual, so we can setup
    //    an alternate behavior when it's called.
    // We configure the Show method to call the SelectAFile method
    //    with the original arguments
    mock.Setup( partialMock => partialMock.Show(It.IsAny<OpenFileDialog>())
        .Callback( SelectAFile );

    string fileName = subject.SelectFile();
    Assert.IsNotNull(fileName);
}

// we alter the original inbound argument to simulate
//    the user selecting a file
private void SelectAFile(OpenFileDialog dialog)
{
    dialog.FileName = "Foo";
}

Now when our test runs the FileDialog returns “Foo” without launching a popup. Now we can write tests for a few extra scenarios:

[TestMethod]
public void WhenSelectingAFile_AndTheUserCancelsTheFileDialog_NoFileNameShouldBeReturned()
{
    // we're mocking out the call to show the dialog,
    // so without any setup on the mock, the dialog will not return a value.

    string fileName = Subject.SelectFile();

    Assert.IsNull(fileName);
}

[TestMethod]
public void WhenSelectingAFile_BeforeUserSelectsAFile_EnsureDefaultDirectoryIsApplicationRootFolder()
{
    // ARRANGE:
    string expectedDirectory = Environment.CurrentDirectory;

    Mock.Get(Subject)
        .Setup(d => d.ShowDialog(It.IsAny<OpenFileDialog>()))
        .Callback<OpenFileDialog>(
            win32Dialog =>
            {
                // ASSERT: validate that the directory is set when the dialog is shown
                Assert.AreEqual(expectedDirectory, win32Dialog.InitialDirectory);
            });

    // ACT: invoke showing the dialog
    Subject.SelectFile();
}

Next: Review some of the application metrics for our experiment in the Guided by Tests – Wrap Up.

submit to reddit

Tuesday, October 04, 2011

Guided by Tests–Day Six

This post is seventh in a series about a group TDD experiment to build an application in 5 7 days using only tests.  Read the beginning here.

Today is the day where we put it all together, wire up a user-interface and cross our fingers when we run the application. I joked with the team that “today is the day we find out what tests we missed.” Bugs are simply tests we didn’t think about.

Outstanding Design Concerns

At this point we have all the parts for our primary use case. And although we’ve designed the parts to be small with simple responsibilities, we’ve been vague about how the structure of the overall application. Before we can show a user-interface, we’ve got a few remaining design choices.

Associating the Command to the View

In the last post we looked at the NewProjectCommand. After reviewing our choices about the relationship between the Command and the ViewModel we decided that the most pragmatic choice was to have the Command hold a reference to the ViewModel, though we didn’t define where either object fit into the overall application. The next question presented to the team was whether we make the command independent of the ViewModel and reside in a menu-control or other top-level ViewModel, or should we add a Command property to the ViewModel?

The team decided to take the convenience route and put our NewProjectCommand as a property on our MainViewModel. Ultimately, this decision means that our MainViewModel becomes the top-level ViewModel that the View will bind to. This decision is largely view-centric and should be easy to change in the future if we need to reorganize the structure of the application.

With this decision resolved, we’ve got a better picture of how the user-interface and logical model will work. Before we start working on the xaml, we need to figure out how all these pieces come together.

Assembling the MainViewModel

The parts of our application have been designed with the Dependency Inversion Principle in mind – our objects don’t have a “top” and expect that the caller will pass in the proper configuration. Eventually, something must take the responsibility to configure the object graph. The next question is: where should this happen?

Someone suggested stitching the components together in the application start-up routine. While this is logically where this activity should occur, it doesn’t make sense to burden the start-up routine with these implementation details. If we did, we’d likely have a monster start-up routine that would change constantly. Plus, we’d have little means to test it without invoking the user-interface.

Achieving 100% code coverage, though a noble effort, is not always realistic. In most applications it’s likely that 10% of the codebase won’t have tests because those areas border on the extreme edges of the application. Writing unit tests for extreme edges is hard (“unit” tests for user-interface components is especially difficult) and it helps to have a balanced testing strategy that includes unit, system integration and functional UI automation to cover these areas.

Rather than including these details in the application start-up routine, we’ll move as much code as possible into testable components. The goal is to make the start-up routine so simple that it won’t require changes. This will minimize the untestable areas of the application.

To accomplish this, we decided to create a Factory for a MainViewModel.

Realizations for the MainViewModel Factory

The primary responsibility of our factory is to assemble our ViewModel with a fully configured NewProjectCommand. The test looks something like this:

[TestMethod]
public void CreatingAViewModel_WithDefaults_ShouldSetupViewModel()
{
    var factory = new MainViewModelFactory();
    var viewModel = factory.Create();
    
    Assert.IsNotNull(viewModel, "ViewModel was not created.");
    Assert.IsNotNull(viewModel.NewProject, "Command was not wired up.");
}

In order to make the test pass, we’ll need to wire-up the all the components of our solution within the factory. The argument checking we’ve introduced in the constructors of our command and loader guarantees that. Ultimately, the factory looks like this:

public class MainViewModelFactory
{
    public MainViewModel Create()
    {
        var vm = new MainViewModel();

        IFileDialog dialog = new MockFileDialog();
        IGraphDataParser graphParser = new NDependStreamParser();
        var graphBuilder = new GraphBuilder();

        var loader = new ProjectLoader(dialog, graphParser);

        vm.NewProject = new NewProjectCommand(vm, loader, graphBuilder);

        return vm;
    }
}

With that all in place, the application start-up routine is greatly simplified. We could probably optimize it further, but we’re anxious to see our application running today, so this will do:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        var shell = new Shell();
        shell.DataContext = new MainViewModelFactory().Create();
        shell.Show();
    }
}

Running the App for the first time

Ready for our first bug? We borrowed some XAML from Sacha’s post, and after we discovered that we needed a one-line user control, we wired up a crude Button to our NewProject command. Then we launched the app, crossed our fingers, and upon clicking the “New Project” button….. nothing happened!

We set a breakpoint and then walked through the command’s execution. Everything was perfect, except we had forgotten one small detail: we forgot to notify the user-interface that we had produced a graph.

As a teaching opportunity, we wrote a unit test for our first bug:

[TestClass]
public class MainViewModelTests
{
    [TestMethod]
    public void WhenGraphPropertyChanges_ShouldNotifyTheUI()
    {
        string propertyName = null;

        var viewModel = new MainViewModel();
        viewModel.PropertyChanged += (sender,e) => 
            propertyName = e.PropertyName;

        viewModel.Graph = new AssemblyGraph();

        Assert.AreEqual("Graph", propertyName,
            "The user interface wasn't notified.");
    }
}

And on second attempt (read: messing with xaml styles for a while) the app produces the following graph:

WPF-ComponentDependenciesDiagram

Next: Read about polishing off the File Dialog in Day Seven

submit to reddit