Physics And Testing

At a number of conferences I attended in the past, people connected several fields to software development in general and testing in particular, which (at first) seem unrelated.

Since then, I pondered this for a while (read: more than 4 years). With my background in physics, I see a number of parallels to software testing. This is also a great opportunity to answer a question I get asked frequently: How did you enter software testing, given your background in physics?

Physics

Let’s start with a definition for physics:

Physics is an experimental science. Physicists observe the phenomena of nature and try to find patterns that relate these phenomena.

— Young, Freedman. “Sears and Zemansky’s University Physics: With Modern Physics”. Pearson Education.
Also see the wikipedia article on physics.

The patterns that relate those phenomena are the theories (or laws) of physics. They are models that describe an aspect of reality. None of these models is complete, in the sense that it describes everything. There is no one physical theory that explains everything. A nice view of the landscape of physical models is shown in the image by Dominic Walliman (see sciencealert.com for details):

The landscape of physical theories, see
Dominic Walliman’s ‘Domain of Science’ video on YouTube

In physics (as in science in general), experimental results and predictions  created by models are compared, in order to find out how a model does not match observed behaviour. This is important: Experiments can only ever invalidate a model, but not generally confirm its correctness.

Software

To me software systems are models, too: Even though they may represent reality closely, a software system is not the thing it represents.
Peter Naur described the relationship between theory building and programming in his paper ‘Programming as Theory Building’ (Microprocessing and Microprogramming 15, 1985, pp. 253-261).

Testing

My mental model of software testing is very similar to the one of physics: I see software systems as partial implementations of aspects of a real expected behaviour. In my view testing a system means it and comparing observed results with expectations.
The expectations may come from requirements (written or otherwise), previous experiences with similar systems (i.e. another web application from the same company) or other sources.

There are many approaches to testing, in a similar way to the many approaches to physics. Some of them work good in one area but not so well in another. What kind of testing is done, heavily depends on the kind of the software system: Testing embedded software used in medical devices is drastically different from testing, say, a text editor.

Science

It is interesting to go one step further, from physics to science. The Cambridge Dictionary defines science as

the intellectual and practical activity encompassing the systematic study of the structure and behaviour of the physical and natural world through observation and experiment

https://dictionary.cambridge.org/dictionary/english/science

With a different wording, this seems to fit software testing as well:

Software testing the intellectual and practical activity encompassing the systematic study of the structure and behaviour of software systems through observation and experiment.

The definition with a different wording

To me, many very basic principles of scions in general and physic in particular apply to software testing, too. And that’s why I think that my physics background is very helpful in software testing.

Now, I interested in this: What is your background and how does it help you in software testing (especially if your background is not in computer science or software engineering)?

Writing a (Technical) Book in an IDE

I find myself writing again more, in particular writing technical books. For this I am using a number of tools, some of which I’ve described in Writing a Ruby Related book(let) on LeanPub.

In this post I focus on the writing itself including the setup I use. When starting fresh, I use the zip file with a default content provided by LeanPub. When unzipped, the folder structure looks like this:

% tree a_potential_book
a_potential_book
├── README.md
└── manuscript
    ├── Book.txt
    ├── chapter1.txt
    ├── chapter2.txt
    ├── chapter3.txt
    └── resources
        ├── palm-trees.jpg
        └── readme.txt

2 directories, 7 files

I have used Markdown in previous books and am now using Markua (a markup format created by LeanPub). Since both are similar and many editors & IDEs identify the file type by the file name suffix, I use ‘.md’ as the suffix for the files. Also, I find renaming the files ist easier than reconfiguring editors. To do this I use rename:

% rename -g  -s .txt .md  "a_potential_book/manuscript/chapter*.txt"
% tree a_potential_book
a_potential_book
├── README.md
└── manuscript
    ├── Book.txt
    ├── chapter1.md
    ├── chapter2.md
    ├── chapter3.md
    └── resources
        ├── palm-trees.jpg
        └── readme.txt

On a Mac rename can be installed using Homebrew:

brew install rename

Now the file Book.txt needs to be updated, to also list the ‘*.md’ files:

ls *.md > Book.txt

With this set up, I import the folder into RubMine, and have a look at ‘chapter2.md’:

Example chapter 2 of the default LeanPub book
The imported default book (click to enlarge image)

Notice this line

![Palm Trees](palm-trees.jpg)

This is the Markua (and Markdown) way of to insert an image (‘palm-trees.jpg’ in this case) into the text using the cation ‘Palm Trees’. In terms of RubyMine the image file is a resource — and it would be handy to be able to open it with just a click. Here’s how to configure this in the IDE:

  1. 320Hover the mouse pointer over the folder name ‘resources’ and
  2. Open the context menu with a right click:
  3. Open the sub menu entitled ‘Mark Directory as ▸’, and click ‘Resource Root’

Now, if you CMD-click the file name in the text, the image is displayed. Nice.

For my Ruby related book, I created a sub directory within ‘resources’ named ‘code’. Any files inside that folder will now also be found by the IDE and opened, when CMD-clicked.

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>.

%d bloggers like this: