Author: Stephan

About Stephan

I'm a self-employed software tester. I test and write software, listen to music and go hiking — sometimes simultaneously. Prior to this was a physicist and oceanographer, among other things.

Agile Testing Days 2020 – the Other Two Days

In a previous post I summarised the 1st day of the Agile Testing Days 2020.

Lean Coffee

2020 was the first year, I facilitated a LeanCoffee. Thank you Janet Gregory & Lisa Crispin for inviting me to help!
Since this was an online-only conference, we used a web application and Janet selected LeanCoffeeTable. I found it easy enough to use. I particularly like the ability that all participants can enter actions and learnings during the topic discussions as well as generate a PDF to summarise the meeting. I found this a very pleasant experience.

Here are some of the ideas and insights, I kept:

  1. No Testing Column
    I’ve learned that some teams entirely remove the testing column(s) from their boards. Obviously, this simplifies the board. But more importantly, it also seems to help teams integrate testing tighter with the overall development. This in turn supports teams working as one entity, and not as a number of people who happen to work on the same story.
  2. After all those years: So many topics about testing
    Even after years, in some cases decades in testing, there are still areas that one can learn about, drive into and possibly thrive in. The next point is one that surprised me a bit.
  3. Automated accessibility testing
    At least some parts of accessibility (commonly abbreviated a11y) testing can be automated. More on that later.
  4. Productive ensemble testing
    Test in an ensemble testing (formerly known as ‘mob testing’, similar to mob programming) can be productive even with people that haven’t worked together. This was mentioned by a Lean Coffee participant who joined a group of people (with whom they never worked with before) for a testing session. To their surprise people worked together quite well.

The Last Talk On Software Testing

I had the great pleasure to moderate Rahul Verma’s talk ‘The Last Talk on SoftwareTesting’, where he explained were he thinks the business of tasting (no typo!) went wrong. Entertaining, hilarious and light hearted. And thankfully not actually the last talk on software testing at all. Here’s a very nice summary by Ekaterina Budnikov:

Automated Accessibility Testing

I participated in Cecilie Haugstvedt‘s workshop ‘Automatic Accessibility Testing for All‘.

I was really surprised how far automated testing of accessibility is possible – and how easy it is to get started! In addition to that, I found it interesting that automated a11y (the common abbreviation for accessibility) tests can and should be divided into unit and integration tests.

An important learning: The tests that check contrasts (e.g. of text and background) are integration tests: Most often colours are set site using CSS, so not every article, product description etc. needs to be checked individually. Also the computation of how good (or bad) the contrast is, seems to be more time consuming than I thought it is.

For a first step to get some idea of accessibility of a page in Chrome: Using “CMD-OPTION-I” (on a Mac) or “View ➙ Developer ➙ Developer Tools” (via the menu) open the developer tools. Then go to the ‘Lighthouse’ tab & click generate report.

Moderating a New Voices Track

I also really enjoyed moderating Chris Baumann‘s talk ‘Extreme learning situations as testers’. The talk & topic were so good, some of the attendees stayed in the Jitsi room to discuss the topic for the whole next time slot! The following tweets cover some of the ideas & insights Christian shared with us:

Thank you Mariia for the wonderful summary!

Do you also have insights and ideas you took home (where you probably were all the time anyway, this year)? What are they?

Agile Testing Days 2020 (and 2009)

These are some insights I had today, posted as Tweets:

And last, but certainly not least Miroslava Nikolova made me (re?) post a message on a piece of cardboard that circled around at the Agile Testing Days 2009.

I think it is still valid and covers the spirit of this very conference and the attitude of everyone taking part so well.

Here’s the plain text (and if you know who’s the original author, I would really like to know who they are):

We are a community of professionals. We are dedicated of our own continuing education and take responsibility for our careers. We support each other in learning and advancing our craft. We certify ourselves.

— Unknown author(s?) at the Agile Testing Days 2009

I thank everyone who made this day so great!

Following log files and other output

In many situations, especially when testing, I like to see the log file content (or other system output) on one of my open command line windows.

Most of the time

tail -f <log-file-name>

is just fine. However, sometimes I like to have more control of what displayed. In these cases, I use less (https://en.wikipedia.org/wiki/Less_(Unix)):

less +F <log-file-name>

is more convenient (and powerful): I can navigate the whole file, search for specific content.

Note, that while tail uses a lower-case ‘-f’ to follow the file as it’s being written to, less uses an uppercase ‘+F’.

Update (2022-02-04): Fixed it: less uses ‘+F’ (plus upper-case F) as the command line argument, not ‘-F’.

Autogenerate Path Visualisations

In the previous blog post I have described how to use GraphViz to describe a graph in a textual format and then generate an image from that.

This time, let’s do one more step and add some code so that the image gets generated automatically when the text file is updated.

For my project I use Guard, a Ruby gem that watches file system changes, and allows to define various reactions. Running unit tests whenever a file is saved is one example.

For my case, I let it generate a new image file, when a GraphViz file is saved. First of all, I installed the needed Ruby gems:

gem install guard guard-shell

With that in place, here’s the Guardfile I use to generate the images:

guard 'shell' do
  watch(/(.*\.gv)$/) { | m |
    dot_file = m[1]
    png_file = "#{File.basename(dot_file, '.*')}.png"
    command = "dot -Tpng -Gdpi=300 -o#{png_file} #{dot_file} && open #{png_file}"
    puts command
    puts `#{command}`
  }
end

Note: In the code above I had to revert to enter (0xff06) instead of & (0x26) in order to prevent the syntax highlighting feature from turing a & into `&amp;`… 🤷‍♂️

The part watch(/(.*.gv)$/) invokes the following code block when a file that matches the given regular expression changes. I am interested in files that match ‘*.gv’ in the directory that the Guardfile is stored in.

The line dot_file = m[1] extracts the file name from the parameter passed into the block, and uses it to create a _new_ file name for the image file that is going to be created.

Then the shell command is put together, logged, and finally called.

Component of the commandWhat it is/does
dot The command name that
translates the gv file into a PNG image
-TpngSet the output format to ‘png’
-Gdpi=300Set the resolution to 300 dpi
(gives a good resolution for printing)
-o#{png_file} Set the file name for the png file
#{dot_file}The name of the input file
&& open #{png_file}This appends another shell command to open the image file.
(I use this on my Mac to automatically (re-) open the file whenever it’s regenerated.)

In case you would like to experiment with this, I created https://github.com/s2k/autogen_images_for_graphviz/ as a starting point, including an example GraphViz file.

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… 🙂).