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.

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.

Beautiful code…

August 14, 2007 at 11:33 am

O’reilly publishes Beautiful Code


Jonathan Edwards counters with a beautiful explanation.


Now, I haven’t read the new book, but I have a strong resonance with what Edwards wrote.  You should definitely read the whole thing, but I few sentences jumped out at me.


A lesson I have learned the hard way is that we aren’t smart enough. Even the most brilliant programmers routinely make stupid mistakes. Not just typos, but basic design errors that back the code into a corner, and in retrospect should have been obvious.


and


It seems that infatuation with a design inevitably leads to heartbreak, as overlooked ugly realities intrude. 


Precisely.


If there’s anything that agile says, it says that we should build things simply and with a eye to revision because we not only are we “just not smart enough”, there are too many unknowns when we start.


The problem with “beautiful code” as a concept is that it is closely related to “beautiful design”, and I’ve mostly come to the conclusion that any design effort that takes more than, say, 30 minutes is a waste of time.


The concept also gets confused about what the goal of software is anyway. The goal is not to have beautiful, elegant, code. The goal is to have *useful* code that does what you need it to do.


Discuss and comment

YAGNI and unit tests…

June 28, 2007 at 12:48 pm

Thanks for your comments.


I decided to go ahead and write the unit tests for that layer, both because I knew what not writing them would be like, and I wanted to play with wrapping/mocking a system service.


I also decided – as some of you commented – to do the right thing and encapsulate it into a class. That would have happened long ago, but though I’ve written it several times, I don’t think I’ve ever duplicated it within a single codebase – and the codebases where I did write it are pretty disparate. Now, I have something where I could at least move the source file around…


Writing tests for this was a bit weird, because in some sense what I needed to do was figure out what the system behavior was, break that down, write a test against my objects, and then write mocks that allowed me to simulate the underlying behavior.


So, for example, I created a test to enumerate a single file in a single directory, wrote a wrapper around DirectoryInfo, and then created a mock on that object so I could write GetFiles() to pass back what I wanted. And so on with multiple files, sub-directories, etc.


So, I did that, went to write the little bit of code that I needed in the real version (to use the real GetFiles() calls and package the data up), hooked it up to my real code, and it worked.


*But*, when I went back and looked at the code, I found that what I had really done was create two sets of code. There was the real code that called the system routines and shuffled the data into my wrapped classes. And then there was my mock code that let me control what files and directories got returned. But there wasn’t any common code that was shared.


So, my conclusion is that I really didn’t get anything out of the tests I wrote, because the tests only tested the mocks that I wrote rather than the real code, because the only real code was the code that called the system functions.


In this case, TDD didn’t make sense, and I will probably pull those tests out of the system.TDD may make sense the next level up, where I’ve written a new encapsulation around directory traversal, but it seems like the only code there is hookup code.


So, the result of my experiement was that, in this case, writing the tests was the wrong thing to do.


 


 


 

Does YAGNI ever apply to tests?

June 27, 2007 at 1:03 pm

I’ve been writing a small utility to help us do some configuration setup for testing. It needs to walk a directory structure, find all instances of a specific xml file, and then make some modifications to the file.


I TDD’d the class that does the XML file stuff, and I’m confident that it’s working well. I’m now going to do the class to walk of the directory structure and find the files.


And there is my dilemna. I don’t know if I’m going to do TDD on that.


I know exactly how to write it, I’ve written it before, and my experience is that that is code that never changes nor breaks. And, figuring out how to write tests for it is going to be somewhat complex because I’ll have to isolate out the live file system parts.


So, I’ve already decided what I’m going to do, but I’m curious what you think. Does YAGNI apply to test code, or is that the first step to the dark side?

Feel the pain…

August 21, 2006 at 6:36 pm

Dare wrote a post talking about the advisability of making developers do operations.


Which is really part of a philosophical question…


When you’re setting up a software organization, how much specialization should you have, and where you should you draw the lines around the responsibilities of the various groups?


Some orgs take a very generalized view of what people own, and others take a very specialized view. I’ve worked in both sorts of environments.


I’ve worked for a startup where, as a developer, I wrote the code, tested the code, built the code, made tapes to ship out to customers, and answered customer support calls.


And I’ve worked in other organizations where the job of developer was to implement what was written down in the spec and pass it off to the QA org. Those orgs typically had structures and policies designed to insulate the developers, so they wouldn’t be distracted.


That eliminated a bunch of the outside noise that they would otherwise have to deal with, and make them more efficient at getting their development work done.


And how did those efficient organizations fare in their products?


Not very well.


They were reasonably good at shipping software, but their software didn’t turn out to be very good for users. New updates didn’t address issues that users had been hitting. New features were hard to use and/or didn’t hit the sweet spot. They answered questions that users didn’t ask.


All of this was because the developers were out of touch with people who had to deal with their software. They didn’t feel the pain that the users were experiencing setting up their software. They didn’t feel the pain when a bug in the software meant that the user’s business was loosing money. And they didn’t understand why users were having trouble using features that seemed obvious to them.


All that happened in DevDiv, and the issues showed up in our customer satisfaction numbers. So, it was decided to let developers (and the testers, and PMs…) talk directly with customers.


There was a fair amount of angst around this decision. It would take up too much dev time. Developers would insult customers. Customers didn’t know enough to give good feedback.


But it turned out that all of those things were wrong. The developers liked to solve problems, and they also liked to help people. They remotely debugged customer issues on other continents. And they listened very closely to the detailed feedback customers gave about how the current software didn’t meet business needs and what was good and bad about future plans.


And the organization adapted what they were planning, so that it addressed the areas that needed addressing.


Distraction is not the enemy. Pain is not the enemy. Pain is to be embraced, because only through feeling pain are you motivated to make it go away.

Other views on programming sins…

August 8, 2006 at 1:31 pm

At the beginning of the sin-tacular, I asked for people to come up with their own lists. And here they are:



My original plan was to comment on some of the individual sins that people listed, but they’re all great – you should go and read them all.


I was a bit intrigued, however, by Chris’ comment (or should that be “Chris’ Comments’ comment?):


Hey, Eric, what are the 7 Heavenly Virtues of Programmers?


Hmm…

Seven deadly sins of programming – Sin #1

August 3, 2006 at 5:24 pm

So, the time has come for the worst sin.


Just to recap – and so there is one post that lists them all – here are the ones that I’ve covered so far:



Some people have remarked that all of these are judgement calls, and really more a matter of aesthetics than actual sins.


That is true. I didn’t include things like “naming your variables i, j, & k” as sins, because I don’t think that’s a real problem in most of the code I’m likely to have to deal with, and there really isn’t much argument over whether it’s a good idea or not.


It perhaps would have been better to title this series, “Seven things Eric would really prefer that you don’t do in code that he has to work with”, but that is both ungainly and lacking the vitality of a post with the term “sin” in it.


It’s all marketing, you see – or you would if you were actually reading this post, but given my track record on the last six, it’s probably a good idea to cut your losses now and spend your time more productively, like in switching your entire codebase from tabs to spaces (or spaces to tabs…)


When I was a kid, I was fairly interested in WWII. I read a lot of books about it, from general histories about the war, to books on the warfare in the Pacific, to books about the ground war in Europe.


One of the interesting features of the military during that time – one that I didn’t appreciate until much later – was how they balanced the desire for advancement in their officer corps vs the need to only advance the most talented and capable. There were really two schools of thought at the time.


The first school advocated an approach where a lower-ranked officer – say, a colonel – would be promoted to fill a vacancy directly, on the theory that it made the chain of command cleaner, and you’d quickly find out if he had “the right stuff”.


The second group advocated using “field promotions”, in which a colonel would be temporarily promoted to see if he could perform in the job. The theory here was that the service would end up with only the best colonels promoted, and that it was much easier (and better for both the officer and the service) to let a field promotion expire rather than demote an officer already given a full promotion.


Over time, the approach advocated by the second group was borne out as having far better results, and the danger of the first approach was recognized.


Which brings us on our roundabout journey to our final sin:


Sin #1 – Premature Generalization


Last week I was debugging some code in a layout manager that we use. It originally came from another group, and is the kind of module that nobody wants to a) own or b) modify.


As I was looking through it, I was musing on why that was the case. Not to minimize the difficulty in creating a good layout manager (something I did a bit of in a previous life), but what this module does really isn’t that complex, and it has some behavior that we would really like to change.


The problem is that there are at least three distinct layers in the layout manager. I write a line of code that says:


toolbarTable.SetColMargin(0, 10);


and when I step into it, I don’t step into the appropriate TableFrame. I step into a wrapper class, which forwards the call onto another class, which forward onto another class, which finally does something.


Unfortunately, the relation between the something that gets done and the TableFrame class isn’t readily apparent, because of the multiple layers of indirection.


Layers of indirection that, as far as I can tell (and remember that nobody wants to become the owner of this code by showing an any interest in it or, god forbid, actually making a modification to it…), aren’t used by the way we use the layout manager. They’re just mucking things up…


Why is this the #1 sin?


Well, as I’ve been going through the sins, I’ve been musing on how I ranked them. One of the primary factors that I used is the permanence of the sin.


And this one is pretty permanent. Once something is generalized, it’s pretty rare that it ever gets de-generalized, and I this case, I think it would be very difficult to do so.


<Agile aside>


This might be slightly different if there were full method-level tests for the component – one could consider pulling out that layer. But even with that, it would be hard to approach in a stepwise fashion – it could easily turn into one of those 3-hour refactorings that makes you grateful that your source code control system has a “revert” feature.


</Agile aside>


Or, to put it another, fairly obvious way:


Abstraction isn’t free


In one sense this seems obvious – when you develop a component that is used by multiple clients, you have to spend a little extra effort on design and implementation, but then you sit back and reap the benefits.


Or do you?


It turns out that you only reap the benefits if your clients are okay with the generalized solution.


And there’s a real tendency to say, “well, we already have the ListManager component, we can just extend it to deal with this situation”.


I’ve know teams where this snowballed – they ended up with a “swiss army knife” component that was used in a lot of different scenarios. And like many components that do a lot, it was big, complex, and had a lot of hard-to-understand behavior. But developing it was an interesting technical challenge for the developers involved (read that as “fun and good for their careers”…)


The problem came when the team found that one operation took about 4 times as long as it should. But because of the generalized nature of the component doing the operation, there was no easy way to optimize it.


If the operation had been developed from scratch without using the “uber-component”, there would have been several easy optimization approaches to take. But none of those would work on the generalized component, because you couldn’t just implement an optimization in one scenario – it would have to work for all scenarios. You couldn’t afford the dev cost to make it work everywhere, and in this case, even if you could, it would cause performance to regress in other scenarios.


(At this point, I’m going to have to have anybody thinking “make it an option” escorted out of this post by one our friendly ushers. How do you think it got so complex in the first place?)


At that point, you often have to think about abandoning the code and redeveloping in the next version. And in the next cycle, this group *did* learn from their mistakes – instead of the uber-component, they built a small and simple library that different scenarios could use effectively. And it turned out that, overall, they wrote less code than before.


HaHA. I make joke.


What they really did was build *another* uber-component that looked really promising early (they always do), but ultimately was more complex than the last version and traded a new set of problems for the old ones. But, building it was a technical challenge for the developers involved, and that’s what’s really important…


How do you avoid this sin?


Well, YAGNI is one obvious treatment, but I think a real treatment involves taking a larger view of the lifecycle costs of abstraction and componentization.


It that one general component really going to be better than two custom solutions?


(if you didn’t understand the story, look here and and see what rank is above a colonel…)