A Community Written Book

An Update: It‘s available on LeanPub!

The book is now available at LeanPub ➙ https://leanpub.com/softwarepeopleworkfromhome.

@MaikNog and I (@S_2K on Twitter) are preparing a community e-book, similar to Viv Richards’ (who agreed to contribute to this one. Yay!) wonderful “Around the World with 80 Software Testers“.

It’s entitled “Software People … Work From Home — Insights & Experiences From Planet Earth” and it will contain reports about life and work in these times of lockdown, personal limitation and remoteness. They are personal experiences, unfiltered authentic … and safe for work. 🙂 I would love each contribution to be easily seen as the work of a person, the human behind the words. This is intended to be a very humane collection of individual works covering one topic.

Folks have already promised to contribute material – and here’s a map marking the countries: https://drive.google.com/open?id=1riRbKTZMGdwShPZJ0f884CIbXFD2Vhli&usp=sharing

World map displaying countries with contributors to the book

If you identify as a software person and would like to contribute, we (@MaikNog and @S_2K) would like to hear (or read) from you — especially (but not exclusively!) if you’re not from one of the countries marked in that map.

All the best to you and yours — stay healthy (or a speedy recovery, should that be needed)

Update on 27th April 2020: The name changed, the map is updated and the description more precise..

Update on 10^th^ May 2020: Updated the map, now including Greece and Italy. Thank y’all!

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

Examples:
|  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 …
end

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

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

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

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

2 scenarios (2 pending)
6 steps (4 skipped, 2 pending)
0m0.012s

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

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

2 scenarios (2 undefined)
6 steps (4 skipped, 2 undefined)
0m0.009s

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
end

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 …
end

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 = File.read 'features/works.feature'
=> "Feature: …"
[2] pry(main)> broken = File.read '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)> works.each_codepoint.zip(broken.each_codepoint).select{|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, ‘ ‘ }

produces:

104 101 108 108 111 1593

https://ruby-doc.org/core-2.7.1/String.html#method-i-each_codepoint

The small piece that changed the behaviour was a space, just not a ‘normal’ space, but a NO-BREAK SPACE (see, for example, https://en.wikipedia.org/wiki/Non-breaking_space 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>.

Writing a Ruby Related book(let) on LeanPub

I wrote “Fast Feedback Using Ruby” using LeanPub. The original version was published back in 2015. Since I’m updating it to cover the most recent (at the time of this writing) Ruby 2.7 and RubyGem versions. I figured, it’s a good idea to leave a trace of my workflow and setup. 🙂

My workflow look like this:

  1. Edit Text (or image) file
  2. Save file to local disk
  3. Commit to local Git repository
  4. Push to GitHub
  5. Generate preview PDF on LeanPub using a (post push) web hook
  6. Have Leanpub automatically push files to Dropbox
  7. Have Dropbox synchronise PDF file to local folder
  8. Restart at 1
Writing workflow using LeanPub, GitHub and Dropbox

Whenever I push changes to GitHub, a new preview of the book is generated and sent to my computer. This means I get frequent and fast feedback about how the newly written text looks.

This nicely fits my working preferences and it also matches the topic of this particular book.

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.

Looking For A New Project

It’s time to find a new project!

What I’m looking for is a role as an agile software tester in a team that really strives to improve on agile techniques in both, testing and programming. I’m interested in learning more about DevOps, continuous delivery and automation, including but not limited to test automation.

Travelling in Northern Germany or Denmark is fine and a possibility to work (partially) remote would be lovely.

Technically, a project using Ruby and/or Rails would be fantastic. In case the team is working on steps to also use Elixir, that would be a bonus.

More about my previous work is available over at ‘work with me‘ as well as on my Xing profile.

%d bloggers like this: