The Computer Is Always Right

The other day I had trouble getting a Cucumber scenario to work. Here’s what happened, partly to have a post I can come back to, when (!) my future self runs into a similar problem.

I am using Cucumber and a very stripped down version of the project looked like this:

% tree
└── features
    ├── example.feature
    ├── step_definitions
    │   └── step_def.rb
    └── support
        └── env.rb

All code is entirely contrived and tailored to demonstrate the issue I bumped into. The example file features/example.feature first:

Feature: What is happening?

Scenario Outline: Matching step definitions -- or not

Given a step that mentions '<a_string>'
And another step that uses <a_number> like this
Then all is good

|  a_string |  a_number |
|      word |        42 |
| two words | 3.1415927 |

There are very plain step definitions too (in file step_definitions/step_def.rb):

Given("a step that mentions {string}") do |string|
  pending # Write code here …

Given(/another step that uses ((\d+)|(\d+\.\d+)) like this/) do |number|
  pending # Write code here …

Then("all is good") do
  pending # Write code here …

Running this gives the expected result: Cucumber kindly informs that there are pending steps:

% bundle exec cucumber
Feature: What is happening?

  Scenario Outline: Matching step definitions -- or not # features/example.feature:3
    Given a step that mentions '<a_string>'             # features/example.feature:5
    And another step that uses <a_number> like this     # features/example.feature:6
    Then all is good                                    # features/example.feature:7

      | a_string   | a_number  |
      | word       | 42        |
      | two words  | 3.1415927 |

2 scenarios (2 pending)
6 steps (4 skipped, 2 pending)

However at some point, I started getting another result (comments added by cucumber removed):

% bundle exec cucumber
Feature: What is happening?

  Scenario Outline: Matching step definitions -- or not
    Given a step that mentions '<a_string>'
    And another step that uses <a_number> like this
    Then all is good

      | a_string   | a_number  |
      | word       | 42        |
      | two words  | 3.1415927 |

2 scenarios (2 undefined)
6 steps (4 skipped, 2 undefined)

You can implement step definitions for undefined steps with these snippets:

Given("a step that mentions {string}") do |string|
  pending # Write code here that turns the phrase above into concrete actions

Wait. What?!? I stared at the existing step definition for a while, comparing it with the one printed in the message above:

Given("a step that mentions {string}") do |string|
  pending # Write code here …

Confusion and disbelief kicked in.

One of the principles I use is this:

The computer is always right.

— Not sure where I picked this up. If you know the (or a) source, tell me please.

This is true even if the behaviour is wrong. In this case: If cucumber cannot find a step definition … it CANNOT find a step definition. But why would that be? Why did it happen in this particular case?

I even called in colleagues (remotely) and we stared at the code collectively. Still nothing.

Luckily a trace of a previous successful run was still available in the console output. So I copy-and-pasted the scenarios, and compared them piece by piece in a Pry session:

% pry
[1] pry(main)> works = 'features/works.feature'
=> "Feature: …"
[2] pry(main)> broken = 'features/broken.feature'
=> "Feature: …"
[3] pry(main)> works == broken
=> false

So there is in fact a difference. But what? Where?
Using the same pry session we found out:

[4] pry(main)>{|el| el[0] != el[1] }
=> [
    [0] [
        [0] 32,
        [1] 160

What this does: The codepoints of both strings are combined in pairs, and then the pairs that are different are selected. Here’s what the Ruby Documentation says about each_codepoint:

Passes the Integer ordinal of each character in str, also known as a codepoint when applied to Unicode strings to the given block. For encodings other than UTF-8/UTF-16(BE|LE)/UTF-32(BE|LE), values are directly derived from the binary representation of each character. If no block is given, an enumerator is returned instead.

“hello\u0639”.each_codepoint {|c| print c, ‘ ‘ }


104 101 108 108 111 1593

The small piece that changed the behaviour was a space, just not a ‘normal’ space, but a NO-BREAK SPACE (see, for example, for more about this topic).

Lessons I learned (again):

  1. Some problems are hard to see, and in this case it was even invisible.
  2. The message was correct: The step was not defined, it only looked (to the human eye) as if it was.
  3. Using <spacebar> gives a different result than <option>-<sapacebar>.

Agile Testing Days 2019: A Keynote

I’ll be giving a Keynote at the Agile Testing Days 2019 in Potsdam, Germany: “Being Lucky”.

Stehpan's Keynote at ATD: Being Lucky

Here’s the abstract:

Good fortune can be influenced, so let’s do it.
Do you think a little more luck in your life could help?
Someone at the Agile Testing Days once noticed that I seem to be a particularly lucky person. This made me ponder: Am I lucky? When? How often? Where? I also asked myself, whether it’s possible to influence luck.
Episodes, some from this very conference right from the beginning in 2009, illustrate how luck can strike. However, it doesn’t necessarily feel like a lucky moment at the time it happens. It may actually feel embarrassing and stressful. These stories also provide some heuristics to help you become more lucky.
Lesson learned: While luck can’t entirely be controlled, it might in fact be shaped in our favour.

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 😉

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 \

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

Word of the Year 2017

As before (see 20162015 and 2014) I’ve picked a Word of the Year.

During the past few weeks since the Agile Testing Days 2016 (see my posts Agile Testing Days 2016 — Part 3: Tutorial Day 1Agile Testing Days 2016 — Part 4: Conference Day 1Agile Testing Days 2016 — Part 5: Conference Day 2Agile Testing Days 2016 — Part 6: Conference Day 3 and Agile Testing Days 2016 — Part 7: Unconference Day), I had a few ideas about what to kick off in 2017.

Actually implementing some of these ideas will require some development, in various meanings of the word. So that’s my guiding word for 2017:


With a few lines from a Xavier Rudd song, let me wish you all a great year 2017:

Well, I wish you well on your journey
I hope your dreams they come alive
I hope your dreams back down and they, they thrive
I hope your dreams they come alive

— Xavier Rudd, “Shelter” from the album “Solace”, 2007


Agile Testing Days 2016 — Part 7: Unconference Day

The unconference days at the Agile Testing Days started with a brief introduction by Olaf Lewitz.

I found two sessions particularly interesting. One of them was about how to help new speakers to propose a session to a conference. Here’s the flip chart summary:


The tactical advice I have: Listen to what the organisers say and act on that. The submission page the Agile Testing Days for example, lists hot topics and also states that proposals that are related to such a topic will be more likely to be chosen. The page also states that providing a teaser video will increase the likelihood of being selected even further. I am sure other conferences have similar submission guidelines. Trust them.

Other good advice mentioned in the session: Like reading good code, reading already accepted proposals from previous conferences can help you see what gets accepted (because those already did). Also, while humour is great, it doesn’t always work well in all circumstances. Therefore, be sure to test it in a safe-to-fail environment, e.g. some work colleagues or a user group meeting.

One participant, Maarten Groeneweg, volunteered to be coached on making a conference proposal by Maaret Pyhäjärvi. Together they created an entire mind map Maarten can now use to figure out details of a topic he likes to talk about. If you get a chance to get this sort of support, by all means, take it! While it may well be outside your comfort zone, I’m definitely sure it helps a lot.

The other session I liked a lot was about “Gojko’s Future”. Again, there is a flip chart summary:gijkos-future_s

In his keynote, Gojko presented many aspects of software development and operations that may change, so that testers might become superfluous within about a decade.

Mike Sutton asked one question that I found particularly interesting (I’m paraphrasing): “What could you do, if Gojko’s future becomes the present?”

Some answers were a bit defensive, suggesting possible ways to prevent such a future and I worry about this a little bit as well. But there are many other professions that went out of fashion or disappeared almost completely. For example think about broom makers or rope makers.

Maybe with the advancing technology, we should be ready to find a new profession?


Now, after five intense Agile Testing Days, even the unicorn got tired and it was time for me to drive home. This conference was incredible and I met so many wonderful old and new friends! Thanks to everyone involved in making this such a special event!

Hope to see y’all again next year!


%d bloggers like this: