Port/Adapter/Simulator and UI

May 12, 2015 at 8:19 am

I’ve been working on a little utility project, and I’ve been using port/adapter/simulator on both the server-side parts and on the UI parts. It has been working nicely, though it took me a while to get there.

Initially, I started with a single UI class. After a bit of extension, it looked a bit ugly, so I decided to break it apart by functional area – there’s a main working area, there’s a favorites area, there’s an executing area, and there’s a config area. For each area, it looks something like this:

IUIFavorites

-> UIFavorites
-> UIFavoritesSimulator (really more of a mock than a simulator)

FavoritesManager(IUIFavorites, IUIStore, etc. )

The UI side handles just that – the UI – and the manager part handles the business logic. The UI part exposes events for user actions a properties and methods for modification.

There was one slightly sticky part of this. There are times when the working area manager needs to add itself to the favorites. Options I thought of:

1) Passing the UIWorking object to the favorites manager.

2) Passing the working manager to the favorites manager.

3) Hooking the UIworking event to a favorites manager method in the main creation code.

4) Hooking a working manager event to a favorites manager method in the main creation code.

I didn’t like #1 or #2, so I ended up doing #4. #3 also seemed okay.

No bugs journey episode 2: It’s a matter of values…

February 21, 2015 at 4:54 pm

Read episode 1 first.

Here we are at episode 2, and time for another question. Of the three, which one do you value the most?

  1. Shipping on schedule
  2. Shipping with a given set of features
  3. Shipping with high quality

Write down your answer.

Ha ha! It was a trick question. Pretty much everybody is going to say, “it depends”, because it’s a tradeoff between these three. Let’s try an alternate expression:

  1. Build it fast
  2. Build a great product
  3. Build it right

All of these are obviously important. Hmm. Let’s try a different tact…

If you get in a situation where you need to choose between schedule, features, and quality, which one would you choose?

  1. Shipping on schedule with the right set of features but adequate quality
  2. Shipping late with the right set of features and high quality.
  3. Shipping on schedule and with high quality but with fewer features than we had hoped

Write down your answer.

Let’s talk about option #1. First off, it doesn’t exist. The reason it doesn’t exist is that there is a minimum quality level at which you can survive and grow as a company. If you are trying to hold features and schedule constant, as you develop features you are forcing the quality level down – it *has to* go down because something has to give if you get behind (short estimates, etc.). That means you start with a product that you just shipped, and then it degrades in quality as you do features, and then at some point you want to ship, so you realize you need quality, so you focus on getting back to *adequate*. Unfortunately, fixing bugs is the activity with the most schedule uncertainty, so there is no way you are shipping on time.

It’s actually worse than this. Typically, you’ve reached a point where your quality is poor and you know that there is no way that you are going to get the features done and reach acceptable quality, so you cut features.

And you end up with a subset of features that ships late with barely adequate quality. There’s an old saying in software that goes, “schedule/features/quality – pick 2”, but what few people realize is that it’s very easy to pick zero.

I hope I’ve convinced you that the first approach doesn’t work, and given that I’m saying this series is about “no bugs”, you probably aren’t surprised. Let’s examine the other options.

I’ve see #2 work for teams; they had a feature target in their head, built their software to high quality standards, and then shipped when they were done. This was common in the olden days when box products were common, when the only way to get your product out there was produce a lot of CDs (or even diskettes) and ship them out to people. It worked, in the sense that companies that used the approach were successful.

It is, however, pretty disruptive on the business as a whole; it’s hard to run a business where you don’t know:

  • If new revenue is going to show up 1 year or 3 years from now
  • When you’ll be spending money on sales and marketing
  • Whether the market has any interest in buying what you build

Not to mention making it tough on customers who don’t know when they’ll get that bug fix and enhancement they requested.

Which leaves option #3, which through an amazing coincidence, is the one that is the most aligned with agile philosophy. Here’s one way to express it:

Given that:

  • It is important to the rest of the business and our customers that we be predictable in our shipping schedule
  • Bugs slow us down, make customers unhappy, and pose significant schedule risk
  • The accuracy at which we can make estimates of the time to develop features is poor
  • Work always expands (people leave the team or get sick, we need to spend time troubleshooting customer issues, engineering systems break), forcing us to flex somewhere

The only rational option that we have is to flex on features. If we are willing to accept that features don’t show up as quickly as we would like (or had originally forecast), it is possible to ship on time with high quality.

I chose the phrase “it is possible” carefully; it is possible to build such a system but not get the desired result.

Flexing on features effectively

Time for another exercise. Studies have shown that you will get a much better review of a plan if you spend some focused time thinking about how it might go wrong.

Thinking about the world I just described, what could go wrong? What might keep us from shipping on time with high quality?

Write down your answers.

Here’s my list:

  1. At the time we need to decide to cut features, we might have 10 features that are 80% done. If we move out all 10 of them to the next iteration, we have nothing to ship.
  2. We might have a hard time tracking where we are early enough to make decisions; most people have seen a case where all the features were on schedule until a week before shipping and suddenly 25% were behind by a week or more. If this happens, it may be too late to adapt.
  3. We might have teams that are dependent on each other; the only way to make my schedule is to cut work from team A, but that means that teams B & C can’t finish their work as planned, and they will have to adjust, using time we don’t have.
  4. This release was feature A and a few bugfixes, and feature A isn’t on schedule. We’ll look silly if we just shipped bugfixes.

(At this point I’m really hoping that you don’t have something important on your list that I’ve missed. If so, that’s what comments are for…)

How can we mitigate? Well, for the first one, we can focus on getting one feature done before we move on to the next one. That means that we would have 8 features 100% done instead of 10 features 80% done. This is one of the main drivers for the agile “work together as a team” approach.

This mitigation works for the second one as well. If we make our tracking “is the feature fully complete and ready to ship”, we can tell where we are (3/10 features current done and ready to ship (“done done” in agile terminology)) and we have a better chance of predicting where we are going. This is another driver for “work together as a team”. Note that for both the first and the second one, the more granular our features are, the easier it is to make work; it works great if the team has 5-10 items per iteration but poorly if it only has two. This is the driver for “small self-contained stories” and “velocity measurement” in agile.

I have a few thoughts on the third one. You can mitigate by using short cycles and having teams B and C wait until A is done with their work. You can try to break the work A does into parts so the part the other teams need can be delivered further.  Or you can go with a “vertical team” approach, which works great. 

For the fourth one, the real problem is that we put all of our eggs in one basket. Chopping feature A up will give us some granularity and the chance to get part way there. I also think that a shorter cycle will be our friend; if we are giving our customers updates every month, they will probably be fine with a message that says, “this month’s update only contains bugfixes”.

To summarize, if we have small stories (a few days or less) and we work on them sequentially (limiting how many we are working on at one time), our problems about tracking and having something good enough to ship become much more tractable. We can predict early what features are not going to make it, and simply shift them to the next cycle (iteration). That is our pressure-relief valve, the way that we can make sure we have enough time to get features completed on the shipping schedule with great quality.

The world isn’t quite as simple as I’ve described it here, but I’ve also omitted a number of advanced topics that help out with that, so I think it’s a pretty fair overview.

Before I go on, I’d like to address one comment I’ve heard in relation to this approach.

If we flex on features, then I’m not going to be able to forecast where we will be in 6 months

The reality is that nobody has ever been able to do that, you were just pretending. And when you tried, you were often spending time on things that weren’t the most important ones because of new priorities.

Instead, how about always working on whatever is the highest priority for the business, and having the ability to adjust that on a periodic basis? How does that sound?

The culture of commitment

Time for another question:

What are the biggest barriers to making this work in your organization?

Write down your answers.

I have a list, but I’m only going to talk about one, because it is so much more important than the rest. It’s about a culture of commitment.

Does your organization ask development teams to *commit* to being done in the time that they estimated? Does it push back when developer estimates are too large? Do developers get emails or visits from managers telling them they need to be done on time?

If so, you are encouraging them to write crappy code. You have trained them that being on the “not done” list is something to be avoided, and they will do their best not to avoid it. They can either work harder/longer – which has limited effectiveness and is crappy for the company in other ways – or they can cut corners. That’s all they can do.

Pressure here can be pretty subtle. If my team tracks “days done” and I have to update my estimate to account for the fact that things were harder than I thought, that puts pressure on me to instead cut corners.

This is one reason agile uses story points for estimation; it decouples the estimation process from the work process.

Changing the culture

Here are my suggestions:

  1. Get rid of any mention the words “committed” or “scheduled” WRT work. The team is *planning* what work they will attempt in the next iteration.
  2. Change the “are you going to be done?” interaction to ask, “is there anything you would like to move out to the next iteration?” Expect that initially, people aren’t going to want to take you up on this, and you may have to have some personal interactions to convince somebody that it’s really okay to do this.
  3. When you have somebody decide to move something out, make sure that you take public note of it.

    “To adjust the amount of work to the capacity of the team and maintain shippable quality, the paypal feature has been moved out to the next iteration.”

  4. When teams/individuals check in unfinished features (buggy/not complete) instead of letting those features make it into the common build, force them to remove them or disable them. Make this part of the team-wide status report for the iteration (“the ‘email invoice’ feature did not meet quality standards and has been disabled for this iteration”).
  5. I highly recommend switching to a team-ownership approach. Teams are much more likely to change how they work and improve over time than individuals.

You will need to be patient; people are used to working in the old ways.

This cultural change is the most important thing you can do to reduce the number of bugs that you have.

No Bugs Journey Episode 1: Inventory

February 6, 2015 at 8:06 am

Over the past few years I had the opportunity to work in an environment in which we achieved a significant reduction in bugs and an associated increase in quality and developer satisfaction.

This series will be about how to start the journey from wherever you currently are to a place with fewer bugs, and a bunch of things to think about and perhaps try on your team. Some will be applicable for the individual developer, some will be about an engineering team, some will be for the entire group.

As with all things agile, some techniques will work great for your team, some may require some modification, and some may not work at all. Becoming agile is all about adopting an experimental mindset.

Whether you are on a team awash in bugs or you are already working towards fewer bugs, I hope you will find something of value.

Inventory

We’re going to start by stepping back, taking stock of the situation, and practicing the “Inspect” part of the agile “Inspect and adapt” cycle. We’ll be using a feedback technique that is often used in agile groups.

<aside>

The agile software community is very effective at finding useful techniques outside of the field and adopting them, which is great. They are not great at giving credit for where those techniques were created, so there are a lot of “agile” practices that really came from somewhere else. Which is why I wrote “is often used in agile groups” rather than “agile technique”…

The technique we’re going to use is known as “affinity mapping”, which has been around for a long time.

</aside>

(Note: the following exercise works great as a team/group activity as well. If you want to do it as a group exercise, go find a few videos on affinity mapping and watch them first).

Find some free time and a place where you won’t be disturbed. Get a stack of sticky notes and a pen.

Your task is to write down the issues that are contributing to having lots of bugs, one per sticky note. Write down whatever comes into your head, and don’t spend a lot of time getting it perfect. You can phrase it either as a problem (“lots of build breaks”) or a solution (“set up a continuous integration server”).

Start with what is in the forefront of your mind, and write them down until you run out of things to write. There is no correct number to end up with; some people end up with 4 notes, some people end up with 20.

Now that you have done that, look at this list below, and see if thinking about those areas leads you to get any more ideas. Write them down as well.

  1. Planning
  2. Process tracking and management
  3. Reacting to changes
  4. Interactions between roles (dev, test, management, design, customer)
  5. Recognition – what leads to positive recognition, what leads to negative recognition
  6. Who is respected on the team, and why?
  7. Promotion – what sort of performance leads to promotion
  8. Developer techniques
  9. How is training handled
  10. Who owns getting something done

This second part of the exercise is about thinking different (aka “out of the box”), in looking for non-obvious causes. I’m explicitly having you do it to see if you come up with some of the topics that I’m going to cover in the future.

Clustering

We now have a big pile of sticky notes. Our next task is to review the notes to see if there is any obvious clustering in them. Put all of the notes up on a wall/whiteboard, and look at them. If you find two notes that are closely related, put them next to each other. If you are doing this as an individuals, you will probably only find one or two clusters; if doing it as a group, you will find more.

Note that we are not doing categorization, where each sticky is in a group. At the end I expect to see a lot of notes that aren’t in clusters. That is expected.

Reflection

Take a few minutes and look at what you have. My guess is that you have a decent list of issues, and my hope is that you thought of things that you weren’t thinking about before.

At this point, you might be saying, “If I know what the issues are, why shouldn’t I just go off and start working to address them? Why do I need to read what Eric says?”

If you said that, I am heartily in support of the first statement. Determine which sticky/cluster you (or your team) wants to tackle, figure out a small/cheap/low-risk experiment that you can try, and start making things better.

As for my value-add, my plan is for it to add value in two ways:

First, I’ve been through this a few times, and my guess is that you missed a few issues during the exercise. I know that I missed a ton of stuff the first time I tried this.

Second, I’m hoping to give some useful advice around what techniques might be used for a specific issue, common pitfalls, and ordering constraints (you may have to address issue B to have a decent chance of addressing issue A).

Next time

Next time I’m to talk about the incentives that are present in a lot of teams and how they relate to bugs.

No bugs journey episode 2: Stop encouraging your developers to write bugs

It’s about to get real.

Unit test success using Ports, Adapters, & Simulators–kata walkthrough

December 1, 2014 at 4:27 pm

You will probably want to read my conceptual post on this topic before this one.

The kata that I’m using can be found at github here. My walkthrough is in the EricGuSolution branch, and I checked in whenever I hit a good stopping point. When you see something like:

Commit: Added RecipeManager class

you can find that commit on the branch and look at the change that I made. The checkin history is fairly coarse; if you want a more atomic view, go over to the original version of the kata, and there you’ll find pretty much a per-change view of the transformations.

Our patient

We start with a very simple Windows Forms application for managing recipes. It allows users to create/edit/delete recipes, and the user can also decide where to store their recipes. The goal is to add unit tests for it. The code is pretty tiny, but it’s pretty convoluted; there is UI code tied in with file system code, and it’s not at all clear how we can get tested.

I’m going to be doing TDD as much as possible here, so the first thing to do is to dive right in and start writing tests, right?

The answer to that is “nope”. Okay, if you are trying to add functionality, you can use the techniques in Feather’s excellent book, “Working Effectively with Legacy Code”, but let’s just pretend we’ve done that and are unhappy with the result, so we’re going to refactor to make it easier to test.

The first thing that I want you to do is to look at the application & code, and find all the ports, and then write down a general description of what each port does. A port is something that a program uses to interface with an external dependency. Go do that, write them down, and then code back.

The Ports

I identified three ports in the system:

  1. A port that loads/saves/lists/deletes recipes
  2. A port that loads/saves the location of the recipes
  3. A port that handles all the interactions with the user (ie “UI”)

You could conceivably break some of these up; perhaps the UI port that deals with recipes is different than the one that deals with the recipe storage directory. We’ll see what happens there later on.

If you wanted, you could go to the next level of detail and write out the details of the interface of each port, but I find it easier to pull that out of the code as I work.

How do I do this without breaking things?

That’s a really good question. There are a number of techniques that will reduce the chance of that happening:

  1. If your language has a refactoring tool available, use it. This will drastically reduce the number of bugs that you introduce. I’m working in C#, so I’m going to be using Resharper.
  2. Run existing tests (integrated tests, other automated tests, manual tests) to verify that things still work.
  3. Write pinning tests around the code you are going to change.
  4. Work in small chunks, and test often.
  5. Be very careful. My favorite method of being very careful is to pair with somebody, and I would prefer to do it even if I have pretty good tests.

Wherever possible, I used resharper to do the transformations.

Create an adapter

An adapter is an implementation of a port. I’m going to do the recipe one first. My goal here is to take all the code that deals with these operations and get it in one place. Reading through the code in Form1.cs, I see that there the LoadRecipes() method. That seems like something our port should be able to do. It has the following code:

private void LoadRecipes()
{
    string directory = GetRecipeDirectory();
    DirectoryInfo directoryInfo = new DirectoryInfo(directory);
    directoryInfo.Create();

    m_recipes = directoryInfo.GetFiles("*")
        .Select(fileInfo => new Recipe { Name = fileInfo.Name, Size = fileInfo.Length, Text = File.ReadAllText(fileInfo.FullName) }).ToList();

    PopulateList();
}

I see three things going on here. First, we get a string from another method, then we do some of our processing, then we call the “PopulateList()” method. The first and the last thing don’t really have anything to do with the concept of dealing with recipes, so I’ll extract the middle part out into a separate method (named “LoadRecipesPort()” because I couldn’t come up with a better name for it).

private void LoadRecipes()
{
    string directory = GetRecipeDirectory();
    m_recipes = LoadRecipesPort(directory);

    PopulateList();
}

private static List<Recipe> LoadRecipesPort(string directory)
{
    DirectoryInfo directoryInfo = new DirectoryInfo(directory);
    directoryInfo.Create();

    return directoryInfo.GetFiles("*")
        .Select(
            fileInfo =>
                new Recipe
                {
                    Name = fileInfo.Name,
                    Size = fileInfo.Length,
                    Text = File.ReadAllText(fileInfo.FullName)
                })
        .ToList();
}

Note that the extracted method is static; that verifies that it doesn’t have any dependencies on anything in the class.

I read down some more, and come across the code for deleting recipes:

private void DeleteClick(object sender, EventArgs e)
{
    foreach (RecipeListViewItem recipeListViewItem in listView1.SelectedItems)
    {
        m_recipes.Remove(recipeListViewItem.Recipe);
        string directory = GetRecipeDirectory();

        File.Delete(directory + @"\" + recipeListViewItem.Recipe.Name);
    }
    PopulateList();

    NewClick(null, null);
} 

There is only one line there – the call to File.Delete(). I pull that out into a separate method:

private static void DeleteRecipe(string directory, string name)
{
    File.Delete(directory + @"\" + name);
}

Next is the code to save the recipe. I extract that out:

private static void SaveRecipe(string directory, string name, string directions)
{
    File.WriteAllText(Path.Combine(directory, name), directions);
}

That is all of the code that deals with recipes.

Commit: Extracted recipe code into static methods

<aside>

You may have noticed that there is other code in the program that deals with the file system, but I did not extract it. That is very deliberate; my goal is to extract out the implementation of a specific port. Similarly, if I had been using a database rather than a file system, I would extract only the database code that dealt with recipes.

This is how this pattern differs from a more traditional “wrapper” approach, and is hugely important, as I hope you will soon see.

</aside>

The adapter is born

I do an “extract class” refactoring and pull out the three methods into a RecipeStore class. I convert all three of them to instance methods with resharper refactorings (add a parameter of type RecipeStore to each of them, then make them non-static, plus a bit of hand-editing in the form class). I also take the directory parameter and push it into the constructor. That cleans up the code quite a bit, and I end up with the following class:

public class RecipeStore
{
    private string m_directory;

    public RecipeStore(string directory)
    {
        m_directory = directory;
    }

    public List<Recipe> Load()
    {
        DirectoryInfo directoryInfo = new DirectoryInfo(m_directory);
        directoryInfo.Create();

        return directoryInfo.GetFiles("*")
            .Select(
                fileInfo =>
                    new Recipe
                    {
                        Name = fileInfo.Name,
                        Size = fileInfo.Length,
                        Text = File.ReadAllText(fileInfo.FullName)
                    })
            .ToList();
    }

    public void Delete(string name)
    {
        File.Delete(m_directory + @"\" + name);
    }

    public void Save(string name, string directions)
    {
        File.WriteAllText(Path.Combine(m_directory, name), directions);
    }
}

Commit: RecipeStore instance class with directory in constructor

Take a look at the class, and evaluate it from a design perspective. I’m pretty happy with it; it does only one thing, and the fact that it’s storing recipes in a file system isn’t apparent from the method signature. The form code looks better as well.

Extract the port interface & write a simulator

I now have the adapter, so I can extract out the defining IRecipeStore interface.

public interface IRecipeStore
{
    List<Recipe> Load();
    void Delete(string name);
    void Save(string name, string directions);
}

I’ll add a new adapter class that implements this interface:

class RecipeStoreSimulator: IRecipeStore
{
    public List<Recipe> Load()
    {
        throw new NotImplementedException();
    }

    public void Delete(string name)
    {
        throw new NotImplementedException();
    }

    public void Save(string name, string directions)
    {
        throw new NotImplementedException();
    }
}

The simulator is going to be an in-memory implementation of the recipe store, which which will make it very good for unit tests. Since it’s going to be in-memory, it doesn’t have any dependencies and therefore I can write unit tests for it. I’ll do that with TDD.

Commit: RecipeStoreSimulator with tests

It was a very simple interface, so it only took me about 15 minutes to write it. It’s not terribly robust, however; it has no error-handling at all. I now have a simulator that I can use to test any code that uses the RecipeStore abstraction. But wait a second; the tests I wrote for the simulator are really tests for the port.

If I slightly modify my tests so that they use an IRecipeStore, I can re-purpose them to work with any implementation of that port. I do that, but I start seeing failures, because the tests assume an empty recipe store. If I change the tests to clean up after themselves, it should help…

Once I’ve done that, I can successfully run the port unit tests against the filesystem recipestore.

Commit: Unit tests set up to test RecipeStore

RecipeStoreLocator

We’ll now repeat the same pattern, this time with the code that figures out where the RecipeStore is located. I make the methods static, push them into a separate class, and turn them back into instance methods.

When I first looked at the code, I was tempted not to do this port, because the code is very specific to finding a directory, and the RecipeStore is the only thing that uses it, so I could have just put the code in the RecipeStore. After a bit of thought, I decided that “where do I store my recipes” is a separate abstraction, and therefore having a locator was a good idea.

Commit: RecipeStoreLocator class added

I create the Simulator and unit tests, but when I go to run them, I find that I’m missing something; the abstraction has no way to reset itself to the initial state because the file persists on disk. I add a ResetToDefault() method, and then it works fine.

Commit: Finished RecipeStoreLocator + simulator + unit tests

Status check & on to the UI

Let’s take a minute and see what we’ve accomplished. We’ve created two new port abstractions and pulled some messy code out of the form class, but we haven’t gotten much closer to be able to test the code in the form class itself. For example, when we call LoadRecipes(), we should get the recipes from the store, and then push them out into the UI. How can we test that code?

Let’s try the same sort of transformations on the UI dependency. We’ll start with PopulateList():

private void PopulateList()
{
    listView1.Items.Clear();

    foreach (Recipe recipe in m_recipes)
    {
        listView1.Items.Add(new RecipeListViewItem(recipe));
    }
}

The first change is to make this into a static method. That will require me to pass the listview and the recipe list as parameters:

private static void PopulateList(ListView listView, List<Recipe> recipes)
{
    listView.Items.Clear();

    foreach (Recipe recipe in recipes)
    {
        listView.Items.Add(new RecipeListViewItem(recipe));
    }
}

And I’ll pull it out into a new class:

public class RecipeManagerUI
{
    private ListView m_listView;

    public RecipeManagerUI(ListView listView)
    {
        m_listView = listView;
    }

    public void PopulateList(List<Recipe> recipes)
    {
        m_listView.Items.Clear();

        foreach (Recipe recipe in recipes)
        {
            m_listView.Items.Add(new RecipeListViewItem(recipe));
        }
    }
}

This leaves the following implementation for LoadRecipes():

private void LoadRecipes()
{
    m_recipes = m_recipeStore.Load();

    m_recipeManagerUI.PopulateList(m_recipes);
}

That looks like a testable bit of code; it calls load and then calls PopulateList with the result. I extract it into a RecipeManager class (not sure about that name right now), make it an instance method, add a constructor to take the recipe store and ui instances, and pull the list of recipes into this class as well. I end up with the following:

public class RecipeManager
{
    private RecipeStore m_recipeStore;
    private RecipeManagerUI m_recipeManagerUi;
    private List<Recipe> m_recipes; 

    public RecipeManager(RecipeStore recipeStore, RecipeManagerUI recipeManagerUI)
    {
        m_recipeManagerUi = recipeManagerUI;
        m_recipeStore = recipeStore;   
    }

    public List<Recipe> Recipes { get { return m_recipes; } }

    public void LoadRecipes()
    {
        m_recipes = m_recipeStore.Load();

        m_recipeManagerUi.PopulateList(m_recipes);
    }
}

Commit: Added RecipeManager class 

Now to test LoadRecipes, I want to write:

[TestMethod()]
public void when_I_call_LoadRecipes_with_two_recipes_in_the_store__it_sends_them_to_the_UI_class()
{
    RecipeStoreSimulator recipeStore = new RecipeStoreSimulator();
    recipeStore.Save("Grits", "Stir");
    recipeStore.Save("Bacon", "Fry");

    RecipeManagerUISimulator recipeManagerUI = new RecipeManagerUISimulator();

    RecipeManager recipeManager = new RecipeManager(recipeStore, new RecipeManagerUISimulator());

    recipeManager.LoadRecipes();

    Assert.AreEqual(2, RecipeManagerUI.Recipes.Count);
    RecipeStoreSimulatorTests.ValidateRecipe(recipeManagerUI.Recipes, 0, "Grits", "Stir");
    RecipeStoreSimulatorTests.ValidateRecipe(recipeManagerUI.Recipes, 1, "Bacon", "Fry");
}

I don’t have the appropriate UI simulator, so I’ll extract the interface and write the simulator, including some unit tests.

Commit: First full test in RecipeManager

In the tests, I need to verify that RecipeManager.LoadRecipes() passes the recipes off to the UI, which means the simulator needs to support a property that isn’t needed by the new class. I try to avoid these whenever possible, but when I have to use them, I name them to be clear that they are something outside of the port interface. In this case, I called it SimulatorRecipes.

We now have a bit of logic that was untested in the form class in a new class that is tested.

UI Events

Looking at the rest of the methods in the form class, they all happen when the user does something. That means we’re going to have to get a bit more complicated. The basic pattern is that we will put an event on our UI port, and it will either hook to the actual event in the real UI class, or to a SimulateClick() method in the simulator.

Let’s start with the simplest one. NewClick() looks like this:

private void NewClick(object sender, EventArgs e)
{
    textBoxName.Text = "";
    textBoxObjectData.Text = "";
}

To move this into the RecipeManager class, I’ll need to add abstractions to the UI class for the click and for the two textbox values.

I start by pulling all of the UI event hookup code out of the InitializeComponent() method and into the Form1 constructor. Then, I added a NewClick event to the UI port interface and both adapters that implement the interface. It now looks like this:

public interface IRecipeManagerUI
{
    void PopulateList(List<Recipe> recipes);

    event Action NewClick;

    string RecipeName { get; set; }
    string RecipeDirections { get; set; }
}

And, I’ll go off and implement these in the UI class, the simulator class, and the simulator test class.

<aside>

I’m not sure that NewClick is the best name for the event, because “click” seems bound to the UI paradigm. Perhaps NewRecipe would be a better name…

</aside>

Commit: Fixed code to test clicking the new button

Note that I didn’t write tests for the simulator code in this case. Because of the nature of the UI class, I can’t run tests across the two implementations to make sure they are the same (I could maybe do so if I did some other kind of verification, but I’m not sure it’s worth it). This code mostly fits in the “if it works at all, it’s going to work” category, so I don’t feel that strongly about testing it.

The test ends up looking like this:

[TestMethod()]
public void when_I_click_on_new__it_clears_the_name_and_directions()
{
    RecipeManagerUISimulator recipeManagerUI = new RecipeManagerUISimulator();

    RecipeManager recipeManager = new RecipeManager(null, recipeManagerUI);

    recipeManagerUI.RecipeName = "Grits";
    recipeManagerUI.RecipeDirections = "Stir";

    Assert.AreEqual("Grits", recipeManagerUI.RecipeName);
    Assert.AreEqual("Stir", recipeManagerUI.RecipeDirections);

    recipeManagerUI.SimulateNewClick();

    Assert.AreEqual("", recipeManagerUI.RecipeName);
    Assert.AreEqual("", recipeManagerUI.RecipeDirections);
}

That works. We’ll keep going with the same approach – choose an event handler, and go from there. We’re going to do SaveClick() this time:

private void SaveClick(object sender, EventArgs e)
{
    m_recipeStore.Save(textBoxName.Text, textBoxObjectData.Text);
    m_recipeManager.LoadRecipes();
}

We’ll try writing the test first:

[TestMethod()]
public void when_I_click_on_save__it_stores_the_recipe_to_the_store_and_updates_the_display()
{
    RecipeStoreSimulator recipeStore = new RecipeStoreSimulator();
    RecipeManagerUISimulator recipeManagerUI = new RecipeManagerUISimulator();

    RecipeManager recipeManager = new RecipeManager(recipeStore, recipeManagerUI);

    recipeManagerUI.RecipeName = "Grits";
    recipeManagerUI.RecipeDirections = "Stir";

    recipeManagerUI.SimulateSaveClick();

    var recipes = recipeStore.Load();

    RecipeStoreSimulatorTests.ValidateRecipe(recipes, 0, "Grits", "Stir");

    recipes = recipeManagerUI.SimulatorRecipes;

    RecipeStoreSimulatorTests.ValidateRecipe(recipes, 0, "Grits", "Stir");
}  

That was simple; all I had to do was stub out the SimulateSaveClick() method. The test fails, of course. About 10 minutes of work, and it passes, and the real UI works as well.

Commit: Added Save

Commit: Added in Selecting an item in the UI

Commit: Added support for deleting recipes

To be able to support changing the recipe directory required the recipe store to understand that concept. This was done by adding a new RecipeDirectory property, and implementing it in both IRecipeStore adapters.

Commit: Added support to change recipe store directory

All done

Let’s look at what is left in the form class:

public partial class Form1 : Form
{
    private RecipeManager m_recipeManager;

    public Form1()
    {
        InitializeComponent();

        var recipeManagerUI = new RecipeManagerUI(listView1, 
            buttonNew, 
            buttonSave, 
            buttonDelete, 
            buttonSaveRecipeDirectory, 
            textBoxName, 
            textBoxObjectData, 
            textBoxRecipeDirectory);

        var recipeStoreLocator = new RecipeStoreLocator();
        var recipeStore = new RecipeStore(recipeStoreLocator.GetRecipeDirectory());
        m_recipeManager = new RecipeManager(recipeStore, recipeStoreLocator, recipeManagerUI);
        m_recipeManager.Initialize();
    }
}

This is the entirety of the form class; it just creates the RecipeManagerUI class (which encapsulates everything related to the UI), the RecipeStoreLocator class, the RecipeStore class, and finally, the RecipeManager class. It then calls Initialize() on the manager, and, at that point, it’s up and running.

Looking through the code, I did a little cleanup:

  1. I renamed RecipeDirectory to RecipeLocation, because that’s a more abstract description.
  2. I renamed Recipe.Text to Recipe.Directions, because it has been buggin’ me…
  3. Added in testing for Recipe.Size

Commit: Cleanup

Unit Test Success using Ports, Adapters, and Simulators

December 1, 2014 at 3:38 pm

There is a very cool pattern called Port/Adapter/Simulator that has changed my perspective about unit testing classes with external dependencies significantly and improved the code that I’ve written quite a bit. I’ve talked obliquely about it and even wrote a kata about it, but I’ve never sat down and written something that better defines the whole approach, so I thought it was worth a post. Or two – the next one will be a walkthrough of an updated kata to show how to transform a very simple application into this pattern.

I’m going to assume that you are already “down” with unit testing – that you see what the benefits are – but that you perhaps are finding it to be more work than you would like and perhaps the benefits haven’t been quite what you hoped.

Ports and Adapters

The Ports and Adapters pattern was originally described by Alistair Cockburn in a topic he called “Hexagonal Architecture”. I highly recommend you go and read his explanation, and then come back.

I take that back, I just went and reread it. I recommend you read this post and then go back and read what he wrote.

I have pulled two main takeaways from the hexagonal architecture:

The first is the “hexagonal” part, and the takeaway is that the way we have been drawing architectural diagrams for years (User with a UI on top, app code in between (sometime in several layers), database and other external dependencies at the bottom) doesn’t really make sense. We should instead delineate between “inside the application” and “outside of the application”.  Each thing that is outside of the application should be abstracted into what he calls a port (which you can just think of as an interface between you and the external thing). The “hexagonal” thing is just a way of drawing things that emphasizes the inside/outside distinction.

Dealing with externals is a common problem when we are trying to write unit tests; the external dependency (say, the .NET File class, for example) is not designed with unit testing in mind, so we add a layer of abstraction (wrapping it in a class of our own), and then it is testable.

This doesn’t seem that groundbreaking; I’ve been taking all the code related to a specific dependency – say, a database – and putting it into a single class for years. And,  if that was all he was advocating, it wouldn’t be very exciting.

The second takeaway is the idea that our abstractions should be based on what we are trying to do in the application (the inside view) rather than what is happening outside the application. The inside view is based on what we are trying to do, not the code that we will write to do it.

Another way of saying this is “write the interface that *you wish* were available for the application to use”.  In other words, what is the simple and straightforward interface that would make developing the application code simple and fun?

Here’s an example. Let’s assume I have a text editor, and it stores documents and preferences as files. Somewhere in my code, I have code that accesses the file system to perform these operations. If I wanted to encapsulate the file system operations in one place so that I can write unit tests, I might write the following:

class FileSystem
{
    public void CreateDirectory(string directory) { }
    public string ReadTextFile(string filename) { }
    public void WriteTextFile(string filename, string contents) { }
    public IEnumerable<string> GetFiles(string directory) { }
    public bool FileExists(string filename) { }
}

And I’ve done pretty well; I can extract an interface from that, and then do a mock/fake/whatever to write tests of the code that uses the file system. All is good, right? I used to think the answer is “yes”, but it turns out the answer is “meh, it’s okay, but it could be a lot better”.

Cockburn’s point is that I’ve done a crappy job of encapsulating; I have a bit of isolation from the file system, but the way that I relate to the code is inherently based on the filesystem model; I have directories and files, and I do things like reading and writing files. Why should the concept of loading or saving a document be tied to this thing we call filesystem? It’s only tied that way because of an accident of implementation.

To look at it another way, ask yourself how hard it would be to modify the code that uses FileSystem to use a database, or the cloud? It would be a pretty significant work item. That also means that my encapsulation is bad.

What we are seeing – and this is something Cockburn notes in his discussion – is that details from the implementation are leaking into our application. Instead of treating the dependency technology as a trivial choice that we might change in the future, we are baking it into the application. I’m pretty sure that somewhere in our application code we’ll need to know file system specifics such as how to parse path specifications, what valid filename characters are, etc.

A better approach

Imagine that we were thinking about saving and loading documents in the abstract and had no implementation in mind. We might define the interface (“port” on Cockburn’s lingo) as follows:

public interface IDocumentStore
{
    void Save(DocumentName documentName, Document document);
    Document Load(DocumentName documentName);
    bool DoesDocumentExist(DocumentName documentName);
    IEnumerable<DocumentName> GetDocumentNames();
}

This is a very simple interface – it doesn’t need to do very much because we don’t need it to. It is also written fully using the abstractions of the application – Document and DocumentName instead of string, which makes it easier to use. It will be easy to write unit tests for the code that uses the document store.

Once we have this defined, we can write a DocumentStoreFile class (known as an “adapter” because it adapts the application’s view of the world to the underlying external dependency).

Also note that this abstraction is just what is required for dealing with documents; the abstraction for loading/saving preferences is a different abstraction, despite the fact that it also uses the file system. This is another way this pattern differs from a simple wrapper.

(I should note here that this is not the typical flow; typically you have code that it tied to a concrete dependency, and you refactor it to something like this. See the next post for more information on how to do that).

At this point, it’s all unicorns and rainbows, right?

Not quite

Our application code and tests are simpler now – and that’s a great thing – but that’s because we pushed the complexity down into the adapter. We should test that code, but we can’t test that code because it is talking with the non-testable file system. More complex + untestable doesn’t make me happy, but I’m not quite sure how to deal with that right now, so let’s ignore it for the moment and go write some application unit tests.

A test double for IDocumentStore

Our tests will need some sort of test double for code that uses the IDocumentStore interface. We could write a bunch of mocks (either with a mock library or by hand), but there’s a better option

We can write a Simulator for the IDocumentStore interface, which is simply an adapter that is designed to be great for writing unit tests. It is typically an in-memory implementation, so it could be named DocumentStoreMemory, or DocumentStoreSimulator, either would be fine (I’ve tended to use “Simulator”, but I think that “Memory” is probably a better choice).

Nicely, because it is backed by memory, it doesn’t have any external dependencies that we need to mock, so we can write a great set of unit tests for it (I would write them with TDD, obviously) that will define the behavior exactly the way the application wants it.

Compared to the alternative – mock code somewhere – simulators are much nicer than mocks. They pull poorly-tested code out of the tests and put it into a place where we can test is well, and it’s much easier to do the test setup and verification by simply talking to the simulator. We will write a test that’s something like this:

DocumentStoreSimulator documentStore = new DocumentStoreSimulator();
DocumentManager manager = new DocumentManager(documentStore);
Document document = new Document("Sample text");
DocumentName documentName = new DocumentName("Fred");
manager.Save(documentName);

Assert.IsTrue(documentStore.DoesDocumentExist(documentName));
Assert.AreEqual("Sample text", documentStore.Load(documentName).Text);

Our test code uses the same abstractions as our product code, and it’s very easy to verify that the result after saving is correct.

A light bulb goes off

We’ve now written a lot of tests for our application, and things mostly work pretty well, but we keep running into annoying bugs, where the DocumentStoreFile behavior is different than the DocumentStoreMemory behavior. This is annoying to fix, and – as noted earlier – we don’t have any tests for DocumentStoreFile.

And then one day, somebody says,

These aren’t DocumentStoreMemory unit tests! These are IDocumentStore unit tests – why don’t we just run the tests against the DocumentStoreFile adapter?

We can use the simulator unit tests to verify that all adapters have the same behavior, and at the same time verify that the previously-untested DocumentStoreFile adapter works as it should.

This is where simulators really earn their keep; they give us a set of unit tests that we can use both to verify that the real adapter(s) function correctly and that all adapters behave the same way.

And there was much rejoicing.

In reality, it’s not quite that good initially, because you are going to miss a few things when you first write the unit tests; things like document names that are valid in one adapter but not another, error cases and how they need to be handled, etc. But, because you have a set of shared tests and they cover everything you know about the interface, you can add the newly-discovered behavior to the unit tests, and then modify the adapters so they all support it.

Oh, and you’ll probably have to write a bit of code for test cleanup, because that document that you stored in your unit tests will be there the next time if you are using the file system adapter but not the memory adapter, but these are simple changes to make.

Other benefits

There are other benefits to this approach. The first is that adapters, once written, tend to be pretty stable, so you don’t need to be running their tests very much. Which is good, because you can’t run the tests for any of the real adapters as part of your unit tests suite; you typically need to run them by hand because they use real versions of the external dependencies and require some configuration.

The second is that the adapter tests give you a great way to verify that a new version of the external dependency still works the way you expect.

The simulator is a general-purpose adapter that isn’t limited to the unit test scenario. It can also be used for demos, for integration tests, for ATDD tests; any time that you need a document store that is convenient to work with. It might even make it into product code if you need a fast document cache.

What about UI?

The approach is clearest when you apply it to a service, but it can also be applied to the UI layer. It’s not quite as cool because you generally aren’t about to reuse the simulator unit tests the same way, but it’s still a nice pattern. The next post will delve into that a bit more deeply.

Simulators or not?

October 3, 2014 at 8:47 pm

I’ve been spending some time playing with Cockburn’s hexagonal architecture  (aka “ports and adapters”), and the extension I learned from Arlo, simulators. I’ve found it to be quite useful.

I was writing some code, and I ended up at a place I didn’t expect. Here’s the situation. I have the following external class (ie “port”).

class EntityLoader
{
    public EntityLoader(string connectionInformation) {}

    public IEnumerable<Entity> Fetch(EntithyType itemType) { … }
}

I need to use this class to some different kinds of entities, do some light massaging of data, and then query against the data. I’ll start figuring out what the adapter should be, and I’ll define it by the question that I want to ask it:

interface IPeopleStore
{
    IEnumerable<Employee> GetAllEmployeesForManager(Employee employee);
}

Now that I have the interface, I can use TDD to write a simulator that implements the interface:

class PeopleStoreSimulator: IPeopleStore
{
    public IEnumerable<Employee> GetAllEmployeesForManager(Employee employee) { …}
}

The implementation for this will be pretty simple; I just add a way to get the list of employees for a manager into the simulator. Now I have unblocked my team members; they can code against the interface and use the simulator for their testing while I figure out how to write the version that talks to the EntityLoader.

And this is where it got interesting…

One of the cool things about port/simulator/adapter is that you can write one set of tests and run them against all of the adapters, including the simulator. This verifies that the simulator and the real adapter have the same behavior.

That’s going to be problematic because the interface for Entity doesn’t give me any way to put data into it, so I can’t use the simulator tests on it. It will also do two things; fetch the data from the entity and implement the GetAllEmployeesForManager() method, and because I can’t put data into it, I don’t have a way to write a test for the method().

It also violates one of my guidelines, which is to separate the fetching of data and the processing of data whenever possible. The problem is that we have the lookup method logic in a class that we can’t test – ie so we can’t adapt the data into what we need. That’s a good sign that adapter may not be a good choice here. How about a simpler approach, such as wrapper?

Let’s start with the lookup logic. We’ll make PeopleStore a simple container class, and that will make the lookup logic trivial to test.

class PeopleStore
{
    IList<Employee> m_employees;
    IList<Employee> m_managers;

    public PeopleStore(IList<Employee> employees, IList<Employee> managers)
    {
        m_employees = employees;
        m_managers = managers;
    }
   
    public IEnumerable<Employee> GetAllEmployeesForManager(Employee employee)
    {
        …
    }
}

Now, I’ll work on the wrapper level. After going with an interface, I end up switching to an abstract class, because there is a lot of shared code.

abstract class EntityStoreBase
{
    protected IEnumerable<Employee> m_employees;
    protected IEnumerable<Employee> m_managers;

    IEnumerable<Employee> FetchEmployees() { return m_employees; }
    IEnumerable<Employee> FetchManagers() { return m_managers; }
}

class EntityStoreSimulator: EntityStoreBase
{
    public EntityStoreSimulator(IEnumerable<Employee> employees, IEnumerable<Employee> managers)
    {
        m_employees = employees;
        m_managers = managers;
    }
}

class EntityStore : EntityStoreBase
{
    public EntityStore(string connectionInformation)
    {
        EntityLoader loader = new EntityLoader(connectionInformation);

        m_employees = loader.Fetch(EntityType.Employee)
                            .Select(entity => new Employee(entity));
        m_managers = loader.Fetch(EntityType.Manager)
                            .Select(entity => new Employee(entity));
    }
}

That seems to work fine. Now I need a way to create the PeopleStore appropriately. How about a factory class?

public static class EntityStoreFactory
{
    public static EntityStoreBase Create(IEnumerable<Employee> employees, IEnumerable<Employee> managers)
    {
        return new EntityStoreSimulator(employees, managers);
    }

    public static EntityStoreBase Create(string connectionInformation)
    {
        return new EntityStore(connectionInformation);
    }
}

This feels close; it’s easy to create the right accessor and the EntityLoader class is fully encapsulated from the rest of the system. But looking through the code, I’m using 4 classes just for the entity-side part, and the code there is either not testable (the code to fetch the employees from the EntityLoader), or trivial. Is there a simpler solution? I think so…

public static class PeopleStoreFactory
{
    public static PeopleStore Create(IEnumerable<Employee> employees, IEnumerable<Employee> managers)
    {
        return new PeopleStore(employees, managers);
    }

    public static PeopleStore Create(string connectionInformation)
    {
        EntityLoader loader = new EntityLoader(connectionInformation);

        var employees = loader.Fetch(EntityType.Employee)
                            .Select(entity => new Employee(entity));
        var managers = loader.Fetch(EntityType.Manager)
                            .Select(entity => new Employee(entity));

        return Create(employees, managers);
    }
}

This is where I ended up, and I think it’s a good place to be. I have a class that is well-adapted to what the program needs (the PeopleStore), and very simple ways to create it (PeopleStoreFactory).

Thinking at the meta level, I think the issue with the initial design was the read-only nature of the EntityStore; that’s what made the additional code untestable. So, as fond as I am of port/adapter/simulator, there are situations where a simple factory method is a better choice.

Identifying your vertical story skeleton

September 24, 2014 at 8:39 am

I’ve been leading an agile team for a while now, and I thought I would share some of the things we’ve learned. This one is about vertical slices, and learning how to do this has made the team more efficient and happier.

To make this work you need a team that is cross-functional and has the skills to work on your whole stack (database/server/ui/whatever).

As an example, assume that the team is working on the following story as part of a library application:

As a authenticated library user, I can view the list of the books that I have checked out.

The team discusses what this means, and here’s what they come up with:

  1. Authenticate the current user
  2. Fetch the list of book ids that are checked out by that user
  3. Fetch the book title and author for each book id
  4. Display the nicely-formatted information in a web page

My old-school reaction is to take these four items, assign each of them to a pair, and when all of them are done, integrate them together, and the story will be complete. And that will work; lots of teams have used that approach over the years.

But I don’t really like it. Actually, that’s not quite strong enough – I really don’t like it, for a bunch of reasons:

  • It requires a lot of coordination on details to keep everybody in sync. For example, changes need to be coordinated across the teams.
  • We won’t have anything to show until the whole story is done, so we can’t benefit from customer feedback.
  • Teams will likely be waiting for other teams to do things before they can make progress.
  • The different areas will take different amounts of time to finish, so some people are going to be idle.
  • Our architecture is going to be a bit clunky in how the pieces fit together.
  • It encourages specialization.
  • Nobody owns the end-to-end experience
  • Integrations are expensive; when we integrate the parts together we will likely find issues that we will have to address.

The root problem is that the units of work are too coupled together. What I want is a work organization where the units of work are an end-to-end slice, and a pair (or whatever grouping makes sense) can go from start to finish on it.

That seems to be problematic; the story describes a simple business goal, and it’s unclear how we can make it simpler. We *need* all the things we thought of to achieve success.

This situation blocks most teams. And they are right in their analysis; there is no way to be simpler and to achieve success. Therefore, the only thing that might work is to redefine success.

That’s right, we’re going to cheat.

This cheating involves taking the real-world story and simplifying it by making it less real-world. Here’s a quick list of ways that we could make this story simpler:

  • We don’t really need the book title and author, so we redefine “list of books” to “list of book ids”.
  • The display doesn’t have to be nicely formatted, it could just be a list of book ids on a web page.
  • The display could even just be the results of a call to a web API that we make in a browser.
  • We could build the initial version as a console app, not as a web app.
  • The story doesn’t have to work for every user, it could just work for one user.
  • The list of returned books doesn’t have to be an actual list of checked-out books, it could be a dummy list.

This is just a quick list I came up with, so there may be others. Once we have this list, we can come up with our first story:

As a developer, I can call an API and get a predefined list of book ids back

I’ve taken to calling this a “skeleton story”, because it’s a bare-bones implementation that we will flesh out later.

We will go off and implement this story, deploy it as a working system, and – most importantly – verify that it behaves as it should.

Getting to this story is the hard part, and at this point the remaining vertical slices are merely adding back the parts of the story that we took out. Here’s a possible list of enhancements:

  1. Fetch the list of book ids for a predefined user
  2. Fetch the list of book ids for a user passed into the api.
  3. Display the book ids in web page
  4. Display a book description instead of just a book id.
  5. Make the web page pretty.

These will all be converted to stories, and we will verify that each one makes the system more real in a user-visible way. They aren’t perfect; some of the slices depend on the result of earlier slices, so we can’t parallelize across all 5 of them, and we will still need to have some coordination around the changes we make. These issues are more tractable, however, because they are in relation to a working system; discussions happen in the context of actual working code that both parties understand, and it’s easy to tell if there are issues because the system is working.

Individual Empowerment and agile…

April 28, 2008 at 12:31 pm

(Interestingly, I find myself writing more about agile and team stuff now that I’m not on a development team….)


 


This is in response to a question about how you balance individual empowerment with the collaborative approach on a agile tem… 


 


*** 


 


Agile is all about the team, and being on an agile team requires participants to give up some autonomy towards the team. The team is empowered to do what they need to do to reach their goal. If there are issues around how things should be done or what decision is right, the team needs to come to a decision, and I would encourage management to let the team try to do it.  Further, the team needs to “meta rules” around how to make decisions, and they also need to develop those.


 


This is very different than the “alpha geek” culture that exists in some groups, where a small number of developers are interested in wielding power. There are some individuals who just aren’t willing/able to work collaboratively – I’ve worked with a few, and if you are trying to run an agile team, they are likely better in a different position.


 


One of the teams I was on basically came to this agreement:


 


Developers are expected to use their best judgement when deciding what advice to seek when they are doing development.   There are no rules around when you should seek advice, but as a rough guideline, extending functionality under existing patterns is something you can safely do on your own, and big refactorings or new components are areas when you should definitely seek advice. In between, think about the implications of any design choices you might make, and act accordingly.


 


The other approach is to adopt pair programming, which is a bigger cultural change, but generally if you get two people thinking about decisions they usually make the right decision about involving others.

Project managers for agile teams…

March 20, 2008 at 4:48 pm

A recent question about skill requirements for project managers of agile teams led me to write this:


In traditional project management, “project manager” means “person who is in charge”. In other words, that person makes the decisions, with varying degrees of depth (sometimes it’s high-level, sometimes it’s micro-management).


 


Agile doesn’t have somebody in change – inherent in the concept of agile is that the group is responsible and the group decides.


 


There *is* somebody who facilates (scrummaster in scrum, coach in XP), but their job is very explicitly not to make decisions. That means that the person who takes that role needs to be mindful of that and willing to push any decisions that rise up back down to the time. If the person has previous experience (and a preference) for “being in charge”, they are unlikely to do a good job in that role. If they aren’t thoughful about group dynamics in general, they may not do a good job in that role.


 


Double that comment if the group is not experienced with making decisions together. If they tend to defer upwards and the facilitator is used to making decisions, you probably won’t get a good result.


 

Moving from “write no tests” to TDD

October 19, 2007 at 12:05 pm

There was a post on an internal alias about moving a team that has not been creating any developer-written tests to one that does TDD. I wrote a reply that I think may be of more general interest…


Developers are fluent in code. I think any time you are talking to developers about engineering practices, you need to be showing them code. I think showing TDD workflow is very important. I also have stopped using the term “Unit test” as it means 45 different things before 10am.


 


I’m a big fan of selling the problem rather than the solution. Here are some problems that I think resonate with the developers I know:


 


Time Savings


 


Nearly every group with existing code has a section of code that either is or has been a bug factory, and most developers can make a decent estimate of what parts of new code are “tricky”. If you use TDD (or just write tests for) that set of code, you can save yourself a huge amount of time debugging. You can also factor in the difficulty of debugging certain parts of code – there is a big benefit there.


 


Flexiblity


 


People also tend to own code that a) needs changes and b) is brittle and c) nobody understands any more, and everybody knows how much of a pain that is.


 


Freedom to focus on new stuff


 


All devs like to work on new stuff rather than fixing old bugs. If you have good tests along the way, you won’t have to be dragged away from the new stuff to fix the old stuff as often.


 


Pride


 


Everybody likes to write code that works well, nobody likes to own the bug factory. In fact, I think people leave groups to get away from something they know is a bug factory but nobody else does.


 


Permission


 


Group dynamics often push devs toward meeting a team’s definition of code complete rather than spending the time writing tests. Now, I happen to think that TDD often gets you to code complete sooner (in a tradition milestone approach), but if you’re just learning it, that isn’t the case. You need an explicit declaration that it’s okay to be spending the time writing the tests


 


Tests as examples


 


If you are creating a component that is consumed by somebody else, you can save a bunch of your time by having unit tests. Not only do you spend less time responding to email and doing bugfixes, the tests often provide very nice examples of how to use your component.


 


 


You may not that I don’t list “Design by example” there at all.  I think that design by example is a much better way to create software, but it’s an experiential thing rather than something you can put on a powerpoint deck.


 


Hope that helps.