Browsing Posts published by James

Recently I was doing a simple kata – the Roman Numeral kata – to practice my Ruby and RSpec skills. (The Roman Numeral kata is to build an algorithm test-first that converts a number into its Roman numeral equivalent. For example, 1 to i, 7 to vii, 10 to x, etc. The problem is intended to be simple so that you can focus on the process.) I had the following RSpec code:

require 'roman_numeral'

describe RomanNumeral do
  # specify is just an alias for it. specify reads better in this case
  specify '1 should be i' do
    numeral = RomanNumeral.new(1)
    numeral.to_s.should == 'i'
  end
end

I go through the Red/Green/Refactor cycle and get this first spec working. (I won’t show the production code as it’s not that interesting.) I move onto the second spec.

require 'roman_numeral'

describe RomanNumeral do
  specify '1 should be i' do
    numeral = RomanNumeral.new(1)
    numeral.to_s.should == 'i'
  end

  specify '2 should be ii' do
    numeral = RomanNumeral.new(2)
    numeral.to_s.should == 'ii'
  end
end

Red/Green/Refactor and all is good. But I’m seeing some repetition in my specs and it’s only going to get worse. The specs are almost identical except for the data. So I start hunting through the RSpec docs for something akin to NUnit’s [TestCase] or xUnit’s [Theory]. I find nothing. Maybe, like MSpec, RSpec wasn’t designed to do this sort of data-driven testing.

Undaunted I turn to Google and stumble upon this StackOverflow question asking exactly the same question that I had. Matt Di Pasquale, the OP (original poster), found his own answer and that answer was fascinating! No, RSpec doesn’t have a syntax for test cases because it doesn’t need one. Use the Ruby, Luke!

require 'roman_numeral'

describe RomanNumeral do
  cases = {
    1 => 'i',
    2 => 'ii'
  }

  cases.each do |k, v|
    specify "#{k} should print as #{v}" do
      numeral = RomanNumeral.new(k)
      numeral.to_s.should == v
    end
  end
end

For those not as well-versed in Ruby, “cases” is simply a variable that contains a hash. I then iterate over the key/value pairs and define my specifications. It’s that simple. I didn’t need any special attributes or framework support from RSpec. I didn’t need to learn the inner workings of RSpec to write my own custom extension or attributes. I simply wrote some Ruby code. Let that sink in for a second. I simply wrote some Ruby code.

Now think about that a bit more. I’m writing regular Ruby code to implement the notion of test cases. Rather than defining test cases, I could have used very similar code to define a benchmark that verifies an algorithm scales linearly with number of input elements. Or I could have fuzz tested an external API for my application. The possibilities are only limited by my imagination and don’t require me to gain an ever deeper understanding of my testing/specing framework to implement.

For someone who cut his teeth on C, C++, and C# (with some JavaScript thrown in for good measure) and is used to learning (or building) frameworks to solve problems, the notion that you can just write plain old code to solve these types of meta problems is eye-opening. It is one of those ah-ha moments that matures you as a developer. Not every problem needs a framework to solve it. Sometimes it just requires a little code.

factory_girl.jpgAs some of you might have noticed, I’ve been talking about Ruby and Ruby on Rails more recently. It’s often good to get outside your comfort zone and see how other (web) developers live. One of the areas where Ruby really excels is the wealth of innovative testing/spec’ing libraries available. When writing tests/specs, we need objects to play with. Ruby has a variety of options in this regard, but I particularly like the factory approach espoused by gems such as factory_girl or machinist. I’m partial to factory_girl. So let’s take a look at the syntax and see if we can create something similar for .NET. First off, let’s take a look at the usage syntax:

describe Site do
  it "should register a new user" do
    user = FactoryGirl.build(:user)
    site = Site.new
    site.register(user)
    site.users.should include(user)
  end
end

If we want to customize the instance, we can do that too by passing in a hash as the second argument:

describe Site do
  it "should not register new admin users" do
    user = FactoryGirl.build(:user, :admin => true)
    site = Site.new
    site.register(user)
    site.should_not include(user)
  end
end

What is interesting about factory_girl is that we can create instances of objects without the visual clutter of irrelevant properties. A user requires a first and last name, but in the above cases, we don’t care what they are. In the second case, we can see that the user being an admin is important for this test/spec. By removing the irrelevant properties, we can quickly see at a glance the data that matters for this spec. We also have the advantage that as properties are added to the User class, we have one place to update them (e.g. in the factory_girl definition) and we don’t have to wade back through all our tests adding values for required properties.

ASIDE: Now you might be tempted to say that we’ve been doing something like this in .NET with the Object Mother pattern. The Object Mother pattern is a factory of sorts. The problem is that it tends to be a dumping ground for different variations of the test objects. For example, ObjectMother.CreateUser(), ObjectMother.CreateAdminUser(), ObjectMother.CreateUserWithFirstName(string firstName), ObjectMother.CreateAdminUserWithFirstName(string firstName). The result is a tightly-coupled big ball of testing mud where the team is loathe to re-use ObjectMother methods for fear of breaking other tests. So you end up with this sprawling mass of methods for creating test data, which is separated from the tests themselves. Not a good place to be in.

Let’s look at the syntax for defining our factories in factory_girl:

FactoryGirl.define do
  factory :user do
    first_name 'John'
    last_name  'Doe'
    admin      false
  end
end

There is a lot more to factory_girl than I’ve covered above. When defining factories, you can create associations, lazy attributes, aliases, sequences, callbacks, and much more to keep your factories clean, lean, and mean. When using the factories, there is more than just FactoryGirl.build. There is also FactoryGirl.create, which saves the built instance to the database, FactoryGirl.attributes_for, which provides you with a hash of values often useful for testing Controller create actions, and FactoryGirl.build_stubbed, which returns a stubbed out instance. Here we’re going to focus on FactoryGirl.build to see how close we can get to the Ruby syntax, but written in C#.

Let’s start by looking at what our definition syntax could look like in C#.


FactoryGirl.Define(() => new User());


We give FactoryGirl a Func<T> that creates an instance of the object. Note the use of C# type inferencing so that we don’t have to specify the generic method argument on FactoryGirl.Define.


public static class FactoryGirl {
  private static readonly IDictionary<Type, Func<object>> builders = new Dictinonary<Type, Func<object>>();

  public static void Define<T>(Func<T> builder) {
    if(builders.ContainsKey(typeof(T))) throw new DuplicateFactoryException();
    builders.Add(typeof(T), () => builder());
  }
}


Basically I’m just keeping a hash table of Type versus Func<T>. That way when I get asked to build an object later, I can look it up and run the Func<T>. I have to play some games with the C# type system. My hash table has to store Func<object> because the generic parameter is declared on the methods, not the class. C# is also not able to implicitly convert Func<T> to Func<object>. So I have to add a lambda to the hash table that calls the builder rather than adding the builder directly.


builders.Add(typeof(T), builder); // Compiler error


Whereas the following makes the C# compiler happy.


builders.Add(typeof(T), () => builder()); // Compiler is happy


Now let’s look at the API for building an object.


var user = FactoryGirl.Build<User>();


From an implementation standpoint, we simply need to find the appropriate Func<T> and execute it.

public static class FactoryGirl {
  public static T Build<T>() {
    return (T) builders[typeof(T)];
  }
}


Simple enough. Now if we want to customize the object built…


var admin = FactoryGirl.Build<User>(x => x.Admin = true);


We really just need to accept an Action<T>, which we will execute after the object is constructed.

public static class FactoryGirl {
  public static T Build<T>(Action<T> overrides) {
    var result = (T) builders[typeof(T)];
    overrides(result);
    return result;
  }
}


With this simple implementation, we now have a central place to define our factories and build objects. Any customizations required are in the tests/specs themselves making it easier to understand our intentions in the tests/specs. When we add a new required property, we need to simply update our factory definition with an appropriate default. If needed, you can easily call FactoryGirl.Build() from within a factory definition. I have used this FactoryGirl technique in a production application and it dramatically cleaned up our specification code as compared to a previous project that used Object Mother. I hope it gives you some ideas of how to clean up your own test/spec code. If you are curious about the code or interested in extending FactoryGirl.NET to add some missing capabilities, such as Create, AttributesFor, BuildStubbed, or anything else, you can find the code on GitHub.com here.

UPDATE: A few people have asked me about customizing multiple properties when building an object. FactoryGirl.NET already supports this using the following syntax:

var user = FactoryGirl.Build<User>(x => {
                x.Admin = true;
                x.Age = 42;
           });

logo.gifTo say that I’m a big fan of JetBrains is a bit of an understatement. I’m always talking about ReSharper, dotTrace, dotCover, dotPeek, TeamCity, and many other JetBrains products in person, on Twitter, on my blog, in talks, … Many years ago I released a (now-defunct) ReSharper test runner plug-in. (Defunct because the functionality is now included in ReSharper itself.) I’m one of a team of people running http://teamcity.codebetter.com, which is a widely-used OSS build server run by CodeBetter.com and Devlicious.com in collaboration with JetBrains. I’m on the board of the JetBrains Development Academy. I was JetBrains booth babe/demo monkey at PDC a few years back. I authored the ReSharper course for Pluralsight. (N.B. Through a cross-promotion deal, JetBrains includes one-month access to my Pluralsight ReSharper course for new and existing ReSharper users.) I’m sure there are things that I’m forgetting.

Recently JetBrains approached me about joining their team as a technical evangelist. I was flattered and honoured at being considered for such a position. Then came the hard questions…

Me: I don’t want to be pushing products for the sake of products.

JB: We don’t want you to. We want you to evangelize software best practices and talk about where JetBrains products make developers’ lives easier.

Me: My interests extend beyond .NET. I’ve also done a lot of JavaScript and web work. Plus I’ve been getting into Ruby and Ruby on Rails a lot recently. And I’d like to do some iOS development.

JB: That sounds great! As you know we’ve got products in all those areas and can use someone with that kind of breadth.

Me: I don’t want to put Hadi out of a job.

JB: No worries. You’ll be Hadi’s counterpart in North America. We’ve got enough to keep both of you busy for a long time.

So Hadi and I will be working closely with the rest of the JetBrains team to bring you more awesomeness from JetBrains. More awesome blog posts. More awesome screencasts. More awesome presentations. And of course more awesome information about JetBrains products. (Let’s be realistic. We’ve all got mortgages/expenses to pay.) If you have questions, comments, or quibbles about JetBrains products – especially how we can make them better – Hadi and I are the people you want to talk to. And we want to talk to you, our community.

Canadian Maple LeafTo answer a few burning questions that I’m sure people have… I’ll still be based out of Calgary, Alberta, Canada. I’ll still be speaking at various conferences and user groups – and not just about JetBrains products. (It will be the usual mix of software practices, development techniques, and technologies. So expect to see me at conferences and events both as a speaker and representing JetBrains.) I’ll still be producing Pluralsight videos. (NHibernate Fundamentals will be available soon and I’m already work on Git Fundamentals. JetBrains and Pluralsight will continue to partner on various initiatives.) I’ll still be involved in open-source software. And I’ll still be causing the usual amount of trouble on Twitter and elsewhere. Happy coding!

InfoQ has made another of my DevTeach talks available online – TDD/BDD as Architectural Tools. Enjoy!

TDD/BDD as Architectural Tools

As architects, we have all experienced the folly of BDUF (Big Design Up Front) – spending weeks or months perfecting an architecture that fails when it meets the real requirements and real code. Is it possible to design in the small? How can we avoid unintended complexity, which cripples so many code bases? Can we build enough of an architecture to start writing code and then flesh out our architecture as the code evolves? In this session we examine how Test-Driven Development (TDD) and Behaviour-Driven Development (BDD) allow us to solve these conundrums. We will see how we can use TDD/BDD to focus our architectural efforts in the high-value areas of our code base to achieve just-in-time architecture.

A friend just pointed out that my presentation on “Convention-over-Configuration in an Agile World” is being featured by InfoQ. (The speaker is always the last to know.) I’m honoured and humbled by the great responses from folks. Worst criticism so far is that the presentation isn’t about TDD/BDD. Well, it’s not. Here is my original description:

Convention-over-Configuration in an Agile World

As developers, we spend an inordinate amount of time writing “glue code”. We write code to transform database rows to domain objects… domain objects to view-models or DTOs… We write code to configure inversion of control containers and wire dependencies together. We write code to style our UIs and respond to UI events. Wouldn’t it be nice if this could happen automagically for us? This session will look at using convention-based approaches using Fluent NHibernate and Castle Windsor to reduce the amount of repetitive code and accelerate application development.

So check it out and let me know what you think…

A question I often get asked is why psake does not include something similar to NAnt’s <replacetokens>. The reason is because it’s so darn easy to do it in PowerShell. Given foo.txt.template:

@@foo@@ is @@bar@@!!!

The following script will perform the replacement:

# replace.tokens.ps1
$foo = 'PowerShell'
$bar = 'da bomb'
(cat foo.txt.template) -replace '@@foo@@', "$foo" `
                       -replace '@@bar@@', "$bar" `
                       > foo.txt

(Note the backticks (`) at the end of the line to denote continuation.)

This script will produce:

PowerShell is da bomb!!!

You could easily write a function that would take care of the nitty gritty details. The @@var@@ is arbitrary. You could use any sequence you like. You can even perform regex matches in the @@var@@ expression if needed. Note the double quotes around "$foo". This is PowerShell for performing variable replacements in strings. So "$foo" results in the word PowerShell whereas ‘$foo’ results in the word $foo.

So there you have it. Token replacement built right into PowerShell. Happy Scripting!

Another year, another fun time at DevTeach. Thanks to everyone who came out to my sessions and asked questions. For those interested, you can download slides and demos from here:

TDD/BDD as Architectural Tools (slides | code)

Convention-over-Configuration (slides | code)

Agile Development with IoC and ORM (slides | code)

N.B. Code is compressed with 7-Zip, a free and awesome file archiver. It supports a wide variety of archive formats, including the high compression ratio 7z format. It integrates into Windows Explorer and is much, much, much faster than the Windows built-in zip archiver. Highly recommended.

Once upon a time there were four friends – two TextBoxes and two ComboBoxes. They all lived happily on a WPF Window bound together in blissful MVVM harmony. The TextBoxes were bound to the ViewModel’s TextBoxText property and the ComboBoxes to the ComboBoxSelectedItem property.

MVVM ComboBox

<Window x:Class="MvvmComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mvvm="clr-namespace:MvvmComboBox"
        Title="MVVM ComboBox" Width="300" Height="150">
    <Window.Resources>
        <mvvm:MainWindowViewModel x:Key="viewModel"/>
    </Window.Resources>
    <StackPanel DataContext="{StaticResource viewModel}">
        <TextBox Text="{Binding TextBoxText.Value}"/>
        <TextBox Text="{Binding TextBoxText.Value}"/>
        <ComboBox ItemsSource="{Binding ComboBoxItems}"
                SelectedItem="{Binding ComboBoxSelectedItem.Value}"/>
        <ComboBox ItemsSource="{Binding ComboBoxItems}"
                SelectedItem="{Binding ComboBoxSelectedItem.Value}"/>
    </StackPanel>
</Window>

TextBoxText and ComboBoxItem are both Observable<T> so that INotifyPropertyChanged notifications are broadcast properly to all interested parties.

public class Observable<T> : INotifyPropertyChanged where T:class {
    public event PropertyChangedEventHandler PropertyChanged = (o,e) => { };

    private T value;
    public T Value {
        get { return value; }
        set {
            if(this.value == value) return;
            this.value = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Value"));
        }
    }
}

ASIDE: Notice the event definition in line 2. By assigned a NOP (no operation) lambda, I don’t have to check whether any listeners are registered for the event. I can simply fire the event and worse case scenario, I execute an empty function body rather than throwing a NullReferenceException. This is tidier in my opinion than the if(PropertyChanged != null) nonsense that we’ve been using for years.

The view model is similarly simple.

public class MainWindowViewModel {
    public MainWindowViewModel() {
        TextBoxText = new Observable<string>();
        ComboBoxSelectedItem = new Observable<string>();
    }

    public Observable<string> TextBoxText { get; set; }
    public Observable<string> ComboBoxSelectedItem { get; set; }

    public IEnumerable<string> ComboBoxItems {
        get {
            yield return "One";
            yield return "Two";
            yield return "Three";
            yield return "Four";
            yield return "Five";
        }
    }
}

With the INotifyPropetyChanged in place, changing one TextBox will cause its twin to display the same value and same for the two ComboBoxes.

MVVM ComboBox synchronized

We get a strange new requirement that every second change should be ignored. (The actual business requirement was more sensible. I was displaying a list of entities for editing. If the previous entity wasn’t saved, the user would be presented with a save dialog and standard “yes/no/cancel” options. On cancel, I wanted to disregard the ComboBox change and revert back to the previously selected entity.)

public class Observable<T> : INotifyPropertyChanged where T:class {
    public event PropertyChangedEventHandler PropertyChanged = (o,e) => { };

    private T value;
    private int count;
    public T Value {
        get { return value; }
        set {
            if(this.value == value) return;

            if(count++ % 2 == 0) return;

            this.value = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Value"));
        }
    }
}

So based on business rules, we’ve ignored a change to the view model. The TextBoxes always remain synchronized – reverting back to the previous value if the change is ignored. Unfortunately the changed ComboBoxes becomes unsynchronized with the view model if the view model ignores a change.

MVVM ComboBox unsynchronized

If you examine the view model in the debugger, the TextBoxText is “Hello, world! Hello, again!” as expected. You can change either TextBox as many times as you want. Every other edit is ignored and causes its changes to revert, as expected. Examining the current state of the view model’s ComboBoxSelectedItem, its value is “Four” and not “Two”. I selected “Two” in the first ComboBox, which was the ignored change. The first ComboBox is now unsynchronized with the view model. If you change the selection again, both ComboBoxes have the correct value. The problem is only with changes ignored by the view model.

Let’s create a new type derived from ComboBox to fix this problem.

namespace JamesKovacs.MvvmComboBox {
    public class ComboBox : System.Windows.Controls.ComboBox {
        protected override void OnSelectionChanged(SelectionChangedEventArgs e) {
            base.OnSelectionChanged(e);
            var binding = GetBindingExpression(SelectedItemProperty);
            if(binding != null) {
                binding.UpdateTarget();
            }
        }
    }
}

I perform the normal OnSelectionChanged event and then update the ComboBox’s SelectedItemProperty from the bound ViewModel if a binding exists. This ensures that if the view model ignores changes or modifies the selection in some way, the ComboBox displays the correct value. Minor note: I am defining a derived ComboBox in my own namespace, which is also called ComboBox. I do this so that in my XAML, I can apply the fix by prepending <ComboBox/> with my namespace <mvvm:ComboBox/>. With this fix in place, my MVVM ComboBox remains synchronized with its view model.

image

In most cases, MVVM model binding dramatically simplifies your WPF code. Unfortunately there are some cases where bugs in the framework prevent it from working properly. Fortunately in many cases you can work around these limitations by simply deriving your own custom control from the one supplied with WPF to fix these problems.

For those of you who want to play around with the code, you can find it here. Happy coding!

ADDENDUM: As noted by Michael L. Perry in this comment, WPF behaviours can also be used to inject code without subclassing ComboBox. The code sample now includes his behaviour code in addition to the subclassing option. Also to note is that a bug in .NET 4.0 prevents the fix from working. The ComboBox (regulard, subclassed, or behavioured) becomes unsynchronized from the view model. The subclassing code works correctly in .NET 3.5. If there are any WPF gurus out there who can understand why it works in .NET 3.5, but not .NET 4.0, I would love to hear an explanation.

imageSystem.Type and XML are the nuts and gum of the development world. You can stuff a System.Type into an XML file, but it leaves a bad taste in your mouth. Sometimes you don’t have much choice. For example:

  • Custom configuration sections in App.config/Web.config
  • Handlers and modules in Web.config
  • ProxyFactoryFactory, 2nd-level cache provider, database dialect, and other pieces of configuration in hibernate.cfg.xml*
  • XML-based IoC configuration**

* NHibernate Loquacious configuration is now a better option for configuring NHibernate IMHO and I use it in all my new apps rather than hibernate.cfg.xml.

** For IoC containers, convention-over-configuration is a better choice followed by code-based configuration. I use XML-based configuration only as a last resort, but it can sometimes be useful for configurable overrides.

When you do need to encode a System.Type into a XML file, JetBrains ReSharper makes your life a lot easier. (This is a little-known feature of ReSharper shown to me by Ilya “Orangy” Ryzhenkov, ReSharper Product Manager.) I decided to create a completely silly, contrived example where we need to display a list of hot peppers and their Scoville heat units and the information is stored in App.config. (Yes, I know. A database or flat file would be a better place. I told you that it was a contrived example.) I have created a PeppersConfigurationSection class that is defines the <peppers> configuration section. I need to specify the type name in the <configurationSections> where it says <INSERT_TYPE_NAME_HERE>

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="peppers" type="<INSERT_TYPE_NAME_HERE>" />
  </configSections>
  <peppers>
    <pepper name="Crazy Jerry's Brain Damage" scovilles="11000" type="sauce"/>
    <!-- more peppers -->
  </peppers>
</configuration>

Rather than typing out the namespace-qualified type name, I simply type PCS for PeppersConfigurationSection and press ReSharper’s Import Symbol Completion (IDEA: CTRL-ALT-Space; VS: ALT-SHIFT-Space).

Import Type Completion

You can see the normal ReSharper completion pop-up appear. Selecting the first one, I get:

Type Completed

This is fine and dandy if the custom configuration section is defined in your project, but what if you need to specify the assembly name too? ReSharper once again comes to our rescue with a Quick Fix (ALT-Enter).

Add module qualification

Selecting the Add module qualitication Quick Fix and we end up with this. (I added linebreaks between the parts of the fully qualified type name for ease of readability in the screenshot.)

ImportTypeCompletion4

Add module qualification is even handier if the assembly has a public key token as those are a hassle to look up. Once again, ReSharper does the hard work of inserting the type name – I only typed NVSH CTRL-ALT-Space – and then the quick fix to get the qualification with assembly name, version, culture, and public key token:

ImportTypeCompletion5

I hope this little ReSharper gem makes your coding lives just a little bit easier…

N.B. ReSharper 5.1 and 6.0 EAP (up to at least build 2136) has a bug that causes Import Symbol Completion to fail for files named Web.config in a ASP.NET project. If you rename Web.config to Foo.config – no other changes necessary – you can use Import Symbol Completion. Just remember to rename the file back to Web.config when you’re done. Another option is to copy Web.config to another project type (Console and Class Library both work), make your changes, and then copy back. I have reported the issue to JetBrains here and the team is working on a fix.

[Originally published on Telerik blog here. Republished with permission.]

As developers, we like to believe that only raw data matters. And what is more raw than the written word? Does this mean that email is a more efficient communication mechanism than in-person meetings? Email contains just the raw words of our intent, right? The receiver can scan through looking for relevant content. Their computer can index and search our email. Why don’t we communicate everything in email? We’ve all experienced the miscommunication that can happen in email. So what are we missing?

The reality is that humans are social animals. We are attuned to many communication side channels – tone of voice; verbal pauses; facial expressions; body language. These side channels communicate additional information above and beyond the written (or spoken) word. What we are effectively doing with these side channels is increasing our communication bandwidth and when it comes to communication, more bandwidth is better. Just like increasing bandwidth in your computer network means pushing more bits of data per second through the pipe, you can do the same thing with your personal and team communications. Arranging some common forms of communication from lowest to highest bandwidth.

  • One-way text (email/tweet/txt)
  • Two-way text (IM)
  • Voice
  • Video
  • Face-to-Face

As you go from low to high, the amount of information communicated per unit time increases and the likelihood of asking for clarification goes up. You’re much more likely to ask for clarification on an uncertain point when talking to someone than when you’re texting. Having to craft a reply creates a certain amount of impedance and if you’re fairly certain you know what the person is talking about, you won’t send that clarifying text or email. When talking, you’re much more likely to simply say back, “Let me see if I understand what you’re staying” and proceed to paraphrase your understanding of what they said.

Let’s look at daily stand up meetings as an example of high-bandwidth communication. The purpose of the daily stand up meetings is to keep team members apprised of progress on the project. Daily stand up meetings aren’t the only way to do this. Everyone could write daily status reports. Or the project manager could walk around asking everyone for a verbal update. Or team members could update a central progress report wiki. But most successful agile teams use daily stand up meetings. Why are daily stand up meetings more effective than the other techniques? It all has to do with communication bandwidth…

Let’s say a team member emails everyone, “I’m going to finish the enrolment feature on the website today.” Sounds great. No reason to doubt them. Now let’s say that they say exactly the same thing in a daily stand up meeting, but now you notice that they say it while avoiding eye contact with other team members and shuffling their feet? Most people can tell that the developer is quite uncertain about their ability to accomplish the task today. Same raw information, but you’re receiving additional information from the communication sideband of body language. If the developer instead said the same thing, but looks other team members in the eye and says it with confidence in their voice, other team members will feel more certain about the task being completed. (If the person has been saying the same thing for a week straight now, the team has a different issue to deal with – that of honesty and integrity in communication.)

Knowing why agile teams value daily stand up meetings also helps us compensate when face-to-face stand ups aren’t possible or feasible. Let’s say that we have a geographically dispersed team, video calls are going to have higher bandwidth than a voice call or emails. Similarly if the geographically dispersed team is centred in two different locations, it would be better to have two separate face-to-face meetings linked by video rather than everyone calling in separately via video conference. The team’s goal is to maximize efficient information exchange between team members as much as possible.

Daily stand up meetings aren’t the only way that agile teams leverage high bandwidth communications. Other examples include:

  • Pair programming: two developers focused on solving a single problem
  • Team rooms: immersing project members in team-related communications
  • User stories: a reminder to have a conversation with a stakeholder
  • Story walls or Kanban boards: surrounding the team in relevant project data

In each of these cases, successful agile teams use high bandwidth communication to facilitate understanding between team members and with other project stakeholders. Notice that story walls and Kanban boards are a form of non-verbal high bandwidth communication. Team members and stakeholders can quickly glance at the board and see the current status of their project. A well-placed board cannot help but be noticed often and frequently throughout the day. It is a constant visual reminder of what the team is doing and where it is at. It often becomes a focal point of conversation and acts as an information radiator about the project.

This isn’t to say that teams should avoid written communication, but use it when it’s appropriate. Written communication is more easily archived and searchable than verbal communication. Good written communication summarizes and condenses a lot of information into a more useful form. Written communication also decouples the availability of the sender and receiver. If you need a new server set up or need to confirm a meeting time, often a quick email is more efficient than standing outside someone’s office waiting for them to have a moment to talk to you. The lesson here is use the appropriate form of communication for the job at hand. And next time you’re having trouble understanding an email from a team member or project stakeholder, don’t hesitate to increase your communication bandwidth by picking up the phone or inviting them out for coffee…