Linky #7 - Building Quality That Lasts
Why refactoring beats rewriting, root causes oversimplify, and tests buy you freedom
Welcome to the seventh edition of Linky (scroll to the bottom for past issues). In each issue, I highlight articles, essays, or books that I've recently enjoyed, providing commentary on why they caught my attention and why I believe they're worth your time.
This week's Linky No. 7 explores why “shift-left” testing often fails in practice, how rewriting your system can lead to quality loss, and how the Japanese concept of Ikigai can help you find purpose in your role. We look at the difference between striving and neurotic perfectionism, why searching for a single root cause is misguided, and how Jevons Paradox explains the unintended consequences of efficiency. There's a peek into the evolving nature of programming, a reminder to distinguish between building programs and products, and a breakdown of human error types. Finally, we close with a compelling argument for why investing in code quality pays off, often in ways we don’t immediately see.
Latest post from the Quality Engineering Newsletter
"Shift-left" is a great slogan and encapsulates a lot of what we're trying to do with Quality Engineering, but the problem with slogans like this is that we begin to assume everyone interprets them the same way. We're at a point now where we need to stop and check that we all understand. Otherwise, it risks becoming just another fad.
From the Archive
This post explores how quality is created, maintained, and lost, using two hypothetical teams: one that works harder and one that works smarter. It introduces practical techniques QEs can use to study quality within their teams. I consider it foundational to understanding this key concept in Quality Engineering.
I’m speaking at Agile Manchester this May with my new talk, Building Quality in: A Framework for Engineering Teams. If you can make it, I’d love to see you there. The programme is available at https://agilemanchester.net, and you can get a 10% discount by using the code '10Jitesh'.
The easiest way to lose quality? Rewrite your system
This is 25 years old now, but still as relevant as ever:
Each of these bugs took weeks of real-world usage before they were found. The programmer might have spent a couple of days reproducing the bug in the lab and fixing it. If it’s like a lot of bugs, the fix might be one line of code, or it might even be a couple of characters, but a lot of work and time went into those two characters.
When you throw away code and start from scratch, you are throwing away all that knowledge. All those collected bug fixes. Years of programming work.
You are throwing away your market leadership. You are giving a gift of two or three years to your competitors, and believe me, that is a long time in software years.
Why do dev teams want to rewrite codebases? Because reading code is harder than writing it. This usually shows up in one of three ways:
Architectural problems are making the code hard to change
Hard-to-read code makes it hard to change
Ugly code makes it hard to change
But all of these can be addressed through refactoring rather than rewriting. As QEs, we should really dig into why a rewrite is being proposed because when we do, we risk throwing away the quality already built into the system. Read the full post: Things You Should Never Do, Part I – Joel on Software
Finding your purpose: Ikigai
I talk to a lot of Principal Testers and Developers (what some call Staff+ individual contributors), and one conversation comes up more than any other: What is your purpose?
To operate effectively at the Staff+ level, I believe you need to genuinely love the work. What I like about the concept of Ikigai is how it weaves together what you love, what the world needs, what you’re good at, and what you can be paid for. If your work hits most of those, you’ve probably found your purpose.
I use it as a temperature check - is the work I’m doing still aligned with what energises me? If not, how long will it take before that becomes a problem?
Learn more at Ikigai – Psych Safety.
Quality Engineering is about striving for perfection
A striving perfectionist is someone who aims to be better but focuses on doing their best, enjoys the process of striving rather than falling short, celebrates what has been achieved, and learns from what could have been.
Whereas neurotic perfectionism is associated with poor outcomes - like avoiding risk, not trying new things for fear of failure, and ruminating on missed opportunities.
Perfectionism is often viewed as a flaw, but I prefer this framing as it highlights that there are different types of perfectionism. A striving perfectionist keeps pushing themselves and their teams forward. They know that “good enough” helps you ship, but “better” helps you learn.
From: Is It Okay to Be Average? – No Stupid Questions – Apple Podcasts.
There is no root cause
What you call "root cause" is simply the place where you stop looking any further. That means that any policy or standard that gets you to identify root causes, or probable causes, is of necessity:
Selective. There are only so many things you can label "causal" before the word "causal" becomes meaningless.
Exclusive. They leave out factors that were also necessary and only jointly sufficient to "cause" the failure.
Oversimplified. They highlight only a few hotspots in a long, twisted and highly interconnected, much finer-grained web that spreads far outside the causes you come up with.
A powerful reminder from Sidney Dekker’s Field Guide to Understanding Human Error (2014). We need to move away from searching for neat causes and instead focus on understanding the whole system in which the issue occurred.
Also see: Post-accident attribution to a 'root cause' is fundamentally wrong from my How software systems fail series.
Quote taken from this LinkedIn post by Ben Hutchinson.
Jevons Paradox
The term arrived in 1865 when William Stanley Jevons noticed something peculiar about coal: make it more efficient to use, and people burned more, not less. This paradox has shadowed every technological leap since. Efficiency doesn't tame our appetites; it wets them. Our innovations become trampolines for our desires.
AI is no different. The cheaper and easier it becomes to use, the more we’ll rely on it. But what happens when everyone becomes 10x more productive and can do what everyone else can? Our measures of productivity will need to change or we’ll find ourselves on a never-ending treadmill.
Read the full post: Jevons Paradox: A personal perspective – Tina He.
The end of programming as we know it
Nowadays, the word “writing” no longer refers to this physical act but the higher abstraction of arranging ideas into a readable format.
Similarly, once the physical act of coding can be automated, the meaning of “programming” will change to refer to the act of arranging ideas into executable programs.
Mehran Sahami, the chair of Stanford’s CS department, put it simply: “Computer science is about systematic thinking, not writing code.”
The long-term shift isn’t about replacing programmers—it’s about transforming what programming means. We've transitioned from writing assembly code to higher-level languages, and AI will take that even further. In a world where creation gets easier, debugging and systems thinking will become more valuable than ever.
From: The End of Programming as We Know It - O’Reilly.
Are you building a programme or a product?
One of the genuinely positive things about tools like Copilot and ChatGPT is that they empower people with minimal development experience to create their own programs. Little programs that do useful things - and that’s awesome. More power to the users.
But that’s not product development, it’s programming. They aren’t the same thing. Not even close.
With a product, you have to consider edge cases, unpredictable user behaviour, and scaling challenges. Automating the main use case is easy - it’s the 20% of edge cases that often take 80% of the effort (The Pareto Principle). This is where real product thinking and quality engineering comes in.
More from: The Problem with “Vibe Coding” – Dylan Beattie.
Human errors happen on three different levels
1. Skill-based (slips/lapses); routine actions gone wrong;
2. Rule-based; applying the wrong rule to a familiar situation;
3. Knowledge-based; flawed reasoning in unfamiliar territory.
Human error is a byproduct of how our brain normally works. Understanding this is important to building safer systems, better designs, and collaboration.
Errors are inevitable when working in socio-technical systems, so expecting them and working with them is the most effective approach. This post from Human Error Types | SKYbrary Aviation Safety goes into even more detail about the types of human errors with examples. The quote above is also worth reading and is taken from Human Error by James Reason (1990). See here.
Low quality code costs you more than you might think
When the quality is low, when (not if) you find something wrong, you have to pay to write the code a second time. Now, add to that the opportunity cost of the code you couldn’t write because you were rewriting the first bit, and you have a minimum 3x hit (in money).
But wait! There’s more! After you write that first buggy thing, you’ll be off writing something else. When that bug needs fixing, you must finish what you’re doing to get around to the fix. Those waits can easily add another 5-10x to the lead time.
When you see it laid out like this, investing in quality makes a lot of sense. But when you're in a startup or under pressure, it's tempting to skip the tests and "just ship".
Alan Holub has strong thoughts on that too:
Even small changes (or bug fixes) take vastly longer than it would have taken to write a few tests before you wrote the code (or in the case of unit tests, while you're writing it). If it takes longer to write tests than it does the code, you're either doing way too much work without testing or your code is too large and complex for the job at hand. (Build exactly what you need, not one semicolon more—futureproofing is a death trap.) Work small. Test small
Start small with unit tests they make change safer and build confidence. Add a layer of exploratory testing, and you'll have a solid grip on what you're shipping.
Read the full piece: Go fast, and make more money, by going slow – Alan Holub
Which one resonated most with you this week? Hit reply or leave a comment - I’d love to hear your thoughts.