Visualising Paths

In one of my projects we were faced with a high number of execution paths the system could take. While this is normal and, in fact, expected for all systems these days, in this particular project it was obvious even for the users of the system. The software accepts (interactive) input and then demands more information, as needed in the specific context. There were numerous paths through a network of decisions to get to the point where the final result could be presented to the user.

This is basically describing layers of decisions, leading to various outcomes. To get an overview of the decision tree, I created a diagram using an app (OmniGraffle in this case). The result for one real tree (with abstracted labels) is this:

Paths trough a decisions tree, updating an attribute of the result

This isn’t trivial, but it doesn’t look too hard. But then, there are 9 different paths thought the graph. The following image shows each path in one colour:

Showing all paths for the image above

That’s not as simple anymore. Also note, that the attribute is sometimes updated, leading to different result types (res1 for attribute == 0, res2 for all other cases). It was tedious to create these images to help me see the paths — and fiddling the the arrow to make it look reasonably good, was extra work. To deal with more cases I wanted another approach.

I remembered a tool I had used in a similar situation: GraphViz. It’s the combination of a text format (a graph describing language) and programs to turn this into a graphical representation: images.

Here’s the textual representation of the graph above:

digraph {
  size="40";
  bgcolor="transparent";

  node [fontsize=9, shape=rectangle, style="rounded", color=black];
  edge [fontsize=7, fontcolor=red arrowhead=onormal];

  D1[ label = "Decision 1\nattribute = 0" ];
  D2[ label = "Decision 2" ];
  D3[ label = "Decision 3" ];
  D4[ label = "Decision 4" ];

  R1[ label = "Res 1 | Res 2\ndepending on attribute" ];
  R2[ label = "Res 1 | Res 2\ndepending on attribute" ];
  R3[ label = "Res 1 | Res 2\ndepending on attribute" ]; 

  D1 -> D2 [label = "Yes"];

  D2 -> D3 [label = "Yes\nattribute += 1"];
  D2 -> D3 [label = "No"];

  D3 -> R1 [label = "≤x times"];
  D3 -> D4 [label = ">x times"];

  D4 -> R2[label = "<Y units\nattribute += 1"];
  D4 -> R3[label = "≤Y units"];
}

I find it easy to see which node there are, and how the node connect. Here is the command I used to generate a PNG file:

dot -Tpng -Gdpi=300 -o decisions.png decisions.dot

dot is one of the layout programs that comes with GraphViz. With -Ddpi=300 I’ve set the resolution to 300 dpi (to generate a file with a higher resolution than the default). The resulting image file log like this:

The generated PNG file, using dot

While the positioning of the edge labels is not perfect, it happened automatically, as the whole layout of the image. I didn’t have to move things, I could set the styles for all nodes & edges in one place, so that they are guaranteed to look consistent.

In the cases when I used this approach, I could generate the graph description automatically from a (more or less) formal description. In these cases, I could avoid mistakes by ‘hand-drawing’ the graph entirely (well, having tests for the generator code in place… 🙂).

Homebrew & Pinning Versions

I recently started using Tomcat for a project I’m working on. Since I work on a Mac and am using Homebrew anyway, the installation was as easy:

brew install tomcat

The location of the installed files is /usr/local/Cellar/tomcat on a Mac, BTW. Now, occasionally and out of habit, I run this:

brew update && brew upgrade && brew cleanup

I prefer (usually) small issues with small version jumps to upgrading rarely with bigger version changes (and issues). Also cleaning up seems a good idea, not only on the working desk or kitchen sink.

This time, though, the upgrade removed the previously installed version of Tomcat — including stuff that I had put into a sub folder of the location given above. Not only was the Tomcat installation upgraded, but everything I’ve put in there was gone. 😳

Lesson No. 1: Maybe I shouldn’t have put the stuff there in the first place.
Lesson No. 2: Learn how to pin a version of installed software, when using Homebrew.

It’s easy. Use, for example

brew pin tomcat

to, well, pin the tomcat version. To find out later, when you want to upgrade a piece of software and wonder why it does not happen, use

brew list --pinned

to find out, what software is pinned. Last but not least, a package can be unpinned using:

brew unpin <package_name>

Reading the Homebrew FAQ is also a good idea.

Docker’s ‘docker stats’ & names

This is mostly a technical reminder to my future self and a selection of the tips from a proposal I found at https://github.com/moby/moby/issues/20973. 😉

When using Docker, now and then I need to keep an eye on the run-time behaviour of the Docker containers. To do this, there’s a nice docker command:

docker stats

How ever, in the current version (17.05.0-ce, build 89658be), the containers are listed using the container ID.

I find it much easier to use the container names instead of the IDs, so here are two ways to display them:

  1. On an environment I don’t control (a colleagues machine when pairing, a test environment…) there’s a way to change the display of ‘docker stats’ for a single use of the command:
    docker stats $(docker ps --format={{.Names}})
  2. On my machine, I like to have this all the time, so I edited ~/.docker/config.json and added the following key-value pair:
    "statsFormat": "table {{.Name}}\t \
    {{.CPUPerc}}\t \
    {{.MemUsage}}\t \
    {{.MemPerc}}\t{{.NetIO}}\t \
    {{.BlockIO}}\t{{.PIDs}}"

    (The backslash at the end of the line indicates the the line is actually continuing.)

Announcement: Workshop & ebook: “Fast Feedback Using Ruby”

At the “London Tester Gathering Workshops 2015” (also see #LTGWorkshops on Twitter) I offer a workshop “Fast Feedback Loops & Fun with Ruby”. For this, I wanted to give attendees a handout, to make applying the stuff covered easier and it was planned to be a list of brief recipes.
Suffice to say that the handout grew (and it’s entirely possible that this is ‘feature creep’ in action). In fact, it grew to the point that I decided to turn it into an ebook. The book is not done yet, there’s some copy editing to do.

Fast Feedback Using Ruby

In any case: There will be an ebook, and it will be available on LeanPub at https://leanpub.com/fastfeedbackusingruby/. If you’re interested, please leave a note on the book’s pages.

London Tester Gathering Workshops 2015: Early News

There’s news about the London Tester Gathering Workshops 2015: I’ll offer one of the workshops!

I’m sure we’ll have a couple of exiting days talking about software testing. And not only talking but also some hands-on stuff using Ruby for fun and (fast) feedback.

Before I publish more information about my workshop, I’d like it to…

look right

Stay tuned!

%d bloggers like this: