Three lessons after three months of quality engineering

Three months ago I started a new job as a quality engineer, supporting two teams. So far it’s been an interesting challenge. The two teams were formed only a few months before I joined, although some team members had been working for the company before that. Each team has their own product manager. We also have an engineering manager, but he joined only two weeks before I did. And then I was added to the mix, with a job description that didn’t give a lot more guidance than: support the team in things related to testing and quality.

So my first task in my new job was figuring out what my job was. Or rather, figure out what concrete things I could do that fit that job description. This was not made easier by the fact that we’re a fully remote company. Not being in the same space throughout the day does make things harder when you’re trying to find your place. Reflecting on the past three months made me realize there are three things that are really important: visibility, connections, and patience.

Read more…

Agile tester or quality engineer, who’s to say?

In her article “Better Testing, Worse Quality?” Elisabeth Hendrickson makes an interesting case about independent testing, i.e. testing done by an independent test team. She discovered that beyond a certain point, investigating more in independent testing will make both quality and speed go down, not up. In episode 3 of the Idealcast, she summarizes her article as follows:

[…] when you ramp up the amount of investment in an independent test group, then given the amount of pressure that’s already on the developers to deliver, it is so easy1 for the developers to say, this isn’t my problem anymore. Thank goodness we’ve got the professionals over here. It’s their job to test.” (00:11:21)

Later in the article, Elisabeth Hendrickson gives advice on how to avoid or escape this spiral of decreasing quality and speed. There are four dials you can turn either up or down:

Read more…

Quality: different purposes, different definitions

For years when asked to define quality, I’ve said “value to a person who matters”1. Not too long ago I used that definition in the first post of my four-part series “Thinking about quality”. However, in the fourth post of that series I also said that quality is something emergent. And I continued with:

We can have long discussions about what quality is, but that’s a different question from how do you get quality?

Today I took this one step further, when I realized that depending on the context, I talk very differently about quality. And while I may not define ‘quality’ explicitly in every conversation, implicitly I’m still using different definitions. That alone, I think is interesting: instead of a single, general definition of quality that always applies, I have different definitions depending on their purpose2.

Read more…

The Agile Manifesto is a poor introduction to Agile

Last week Elizabeth Zagroba asked on Twitter:

If someone was completely new to working on software on an Agile team, what would you want them to read about Agile first?

My first thought was: “The Agile Manifesto!” After a second thought, though, I reconsidered and replied:

And I would recommend against reading the Agile Manifesto without consulting any secondary sources, except if you read it in the same way as you would visit a historical site “just to see where it all happened”.

As I wrote this, I could not really put my finger on why exactly I felt this way. The best I could come up with was that the Agile Manifesto is hard to understand on its own. You need some historical context and practical experience to make sense of it. Serendipity came to the rescue, though, as I’m currently reading Seeing Like a State by James C. Scott. Chapter 9 of the book focuses on the Greek concept of mētis (μῆτις) and how it relates to rules of thumb. Turns out that this explains why the Agile Manifesto is a poor introduction to Agile.

Read more…

Tester” is an overloaded variable

Yesterday I came across a post on LinkedIn explaining why there are no testers in Scrum1. What struck me most about the post was the amount of work the word “tester” was doing. In one sentence it meant one thing (a role in a team), in the next sentence something else (a step in the process), and so on. Hence the title of this post: the word “tester” was being used as an overloaded variable. So let’s do some unpacking.

Testers to people management

Having a tester” means that there are people with the official title of “tester” or “QA engineer” or whatever within the company. For the purposes of people management2, there’s a distinction between this role and the other roles in the company. This allows for more specific expectations about the role, for different career paths and salary scales, etc.

Read more…

Three thoughts on risk-based testing

The past month I’ve been thinking about risk-based testing. This post collects three thoughts on risk-based testing I kept returning to.

If not based on risks, then based on what?

About a month ago I tweeted:

What are the alternatives to risk-based testing?
Requirements-based? I’d argue that’s a subset of risk-based.
Unguided? That’s either a bad idea (“we hope to get lucky”) or aimed at the risk of unknown unknowns.
Any other options? Because something about the term is bothering me.

My question was inspired by the “opposite” heuristic from my talk about testing types: if we have some kind of category, what’s the name for the things not in that category? Applied to risk-based testing: what’s the name for testing that’s not risk-based?

Read more…

(clj 10) The mapify function of (clj 9) revisited

In my previous Clojure post I covered the code example at the end of Chapter 4 of “Clojure for the Brave and True”. Or rather, I focused on a single function in the example, called mapify, and described how I figured out what it does. At the end of that post I shared my disappointment:

Having done all this work (and writing) I can’t help but feel a bit disappointed. In the end, the function does not seem to do a lot.

And I shared a Python version of that same function, claiming that it basically does the same thing1.

However, less than a week after publishing the post, I got a very kind email by someone named Martin. And “in defence of clojure and to maybe reduce your disappointment” Martin pointed out the two versions are not as equivalent as I claimed, because the Clojure version is more general than the Python version. So I looked at the two version again and the way they are different turned out to be quite interesting - interesting enough to write a follow-up post.

Read more…

(clj 9) How to figure out what a function does

Chapter 4 of “Clojure for the Brave and True” concludes with a Vampire Data Analysis Program, serving as a summary of the chapter. The book shows some code, explains it, moves on to the next bit of code, etc. I’m not sure why, but I decided I wanted to figure out the code on my own and then read the explanation to see if I got it right. Afterwards I realized it might make a good blog post: both explaining what the program does and what techniques (for lack of a better word) I used to figure it out.

With most of the work in the program being done by a function called mapify, this blog post will focus on that single function. As it turns out, it took me more than 2000 words (footnotes not included) to describe what this function consisting of only 9 lines does. So feel free to read all of it, skim through it, or skip straight ahead to the techniques and some reflections.

Read more…

(clj 8) Some notes on lazy sequences and function parameters

Almost done with the chapter 4 “Core Functions in Depth” of “Clojure for the Brave and True“! Before wrapping up the chapter with a longer example, a summary, and some exercises, the book goes into lazy sequences, the collection abstraction, and function functions. In this post I will share some notes on infinite lazy sequences and function parameters, making comparisons between Clojure and Python.

Infinite lazy sequences

A lazy sequence is a sequence whose members aren’t computed until you try to access them. One advantage is that it’s more efficient: the whole sequence doesn’t have to be calculated and kept in memory from the start. Another advantage is that it allows you to create infinite sequences. Do that with a normal sequence and your program would never want to stop calculating.

Read more…