Where Do Bugs Come From? Part V

Gil Zilberfeld explains bugs appearing due to translation errors
This series is about the origin of bugs. Although they did not come from an apocalypse, they are sure leading us towards it.
Part IPart IIPart III
Part IV
Part V

We’re getting there. Here’s the final nail in the coffin: We are bad at translation and unfortunately, we do a lot of translations.

In a typical application development, we’ve got a user who has a problem:

“Why can’t I see the content when I open the app?”

The business person translates that into a vision:

“Of course, that makes sense. Every time the app starts, it should show the content”.

He then turns that into a requirement:

“The start screen should look like this, and the latest content should be shown”.

The architect takes the requirement and says:

“When the main module loads, it should get the latest data from the database. Oh and let’s separate  it into a new micro-service”.

The developer (I know I’m stereotyping, but role-playing is fun) gets that from the high level design, and writes a detailed design for the code saying:

“For performance reasons, when the new data gets there, it is also cached for other retrievals. Oh and let’s make that two micro-services”

On the other side of the table, our tester looks at the requirement and says:

“I’ll need two staging environments, one for testing in a standalone configuration and one distributed, I’ll load the data differently each time, and I expect every time to see the newest data when I reset”.

Just a short example. Of course, after all this is release, the user says:

“Well it works most of the times, but not always. Why can’t I get my content?

Communication is hard, especially when we’re working cross-domain working on complex issues. We don’t speak the same language. Whenever there is a translation error, two bugs get their wings. That’s how the Tower of Babel started.

To summarize: Bugs happen because we are not good at what we do, we don’t admit it, we don’t communicate well, and after all that, we still relying on pure luck that the thing would work.

How do you fix a bug? You understand what the correct behavior should be, plug the hole up stream and check that it works now, and again, and in two days – again.

How do you fix a buggy process? The same way.


Where Do Bugs Come From? Part IV

Gil Zilberfeld describes how bugs arrive from where we trusted the most: other people's hardware and software.
This series is about the origin of bugs. Although they did not come from an apocalypse, they are sure leading us towards it.
Part IPart IIPart III
Part IV
Part V

On to the next issue: We trust in the “others”. Way too much.

Have you ever considered how much of the code we actually write makes of the whole application?

I mean, let’s start with hardware. Computers, wires, antennas, satellites. We use them as part of our solution, and they are not even code. Then there’s servers and routers. There are runtimes and libraries. There’s open (remember heartburn?) and closed code. There’s code that’s been running for fifteen years that nobody can read, but works in production. And then there’s our code that integrates with all of them.

Oh, our code doesn’t really run. There are the compilers that turn into into runnable bits.

So how much of that whole thing does our code weigh?

Let’s be generous and say 5%. Yeah, the “others” are not what runs between our pieces of our code. Our code IS really the “others”. And we don’t only trust everything out there, we don’t even think about those things and how they work.

Until they don’t, but then, once we upgrade/reintegrate/replace them, we usually forget and move on to the new trendy framework that must be better than the old one because… trust?

Our view of testing is limited too, because of our optimistic assumptions that “these things work”. Bugs come out of the cracks and they surprise us every time, because we didn’t even get a flashlight.

Our concept of building software should be a skeptic and cynical. The idea of standing on the shoulders of giants is a good one, as long as the giants are stable.

We’re a pretty optimistic bunch. And optimism gets us every time.

When were you last surprised (in a bad way?)

Where Do Bugs Come From? Part III

Gil Zilberfeld discusses where bugs come from when we don't TDD clean code etc.
This series is about the origin of bugs. Although they did not come from an apocalypse, they are sure leading us towards it.
Part IPart IIPart III
Part IV
Part V

We’ve looked at a couple of excuses to where bugs come from, now let’s dig deeper.
And we’re going to start with something that’s hard to admit: We don’t know exactly what we’re doing.

The best of us already know that, and the rest of us have not figured it out yet. If you’re offended, I’m sorry, but hey, if we knew what you were doing, it wouldn’t be that hard, would it?

I used to think I know everything. And then I understood I don’t, but thought that even if that’s the case, I can learn everything. And if anything happens, I can control it.

I’m better now.

Our skill level plays a part in making mistakes, obviously. We are less prone to small stupid bugs. We think.

And it’s our hubris that tells us that bugs are caused by other, inferior people. We won’t make the mistakes that “they” do.

Nope. We still make mistakes. Big and small ones.

And I’m not talking about just developers here, if you haven’t figured that out yet. Anyone and everyone on the value stream is not as good as they should be. Nobody is exempt from contributing to the bug pool.

Misunderstanding, using the wrong tools, wasting time on Facebook and working on magnificent plans that never pan out – We still don’t do our job well. We are not focused, we are not weary of the risks, and don’t do our best to get remove those pesky bugs.

Funnily enough (or not), agile development (especially eXtreme programming) has a couple of cures for that. Even “old” methodologies had those.
Processes that focus on delivery, quality and feedback. TDD, clean code, design, exploratory testing, design reviews, code reviews. There’s a lot more we can do.

We’re still learning how to be better, and we should be better at that too.

What are the things you know you can improve right now?

Where do bugs come from? Part II

Gil Zilberfeld talks more about bugs, quality and a bit of organization culture and safety
This series is about the origin of bugs. Although they did not come from an apocalypse, they are sure leading us towards it.
Part IPart IIPart III
Part IV
Part V

While we’re on the subject of favorite excuses, let’s talk about a couple more I got.

It looks more like an escape pod than a bug. Ironically, “don’t look at me” does the exact opposite. It looks very unprofessional. But let’s dig deeper.

We need to ask, how this became a “who”, rather than a “how” thing. Even if you isolate everyone in the process, and have them contact each other through taped recording, it would be very hard to prove that the bug is specific someone’s fault. But that doesn’t matter really, is it?

If the organization looks to blame someone, it will find someone to blame. “It wasn’t me” is defensive for a reason, a safety-less culture. Bugs can come from systemic failure. The excuse is just a symptom.

Let’s carry on to James’ second contribution:

Again, another symptom. My guess it wasn’t a typo.

If it wasn’t, why would he say that? Feeling no safety to take responsibility, acknowledge a mistake, and learn from it – this is probably not a specific someone’s issue. It’s an organizational issue. People tend to cover up. if they are feeling they are going to be persecuted and judged. If it was a typo, using “only” to diminish the problem, gives us a hint on how the programmer might have felt.

The next one I got actually leading to the next post.

Was it really a prototype?
Was there ever a situation where testing (at all, not any more testing) was not required?
Was there ever a first anything that doesn’t need testing?

That’s culture related as well, but needs more digging. In the meantime? Leave some more excuses in the comments. We love excuses.

Where Do Bugs Come From? Part I

Gil Zilberfeld rants on bugs and the excuses we make up for them
This series is about the origin of bugs. Although they did not come from an apocalypse, they are sure leading us towards it.
Part IPart IIPart III
Part IV
Part V

“What do you mean?

When a mommy-bug and a daddy-bug (or any other gender bug) love each other very much…”

Well, that would explain how they multiply. But seriously, what gives? It’s 2019 (I’m pretty sure in ten years time it will be the same). How come we are still crashing systems, inviting hackers in and miscalculating money exchanges? Shouldn’t have all of those supposed to go away?

So here’s my rant, starting with a couple of excuses I hear.

“The things we build are complex”

That is true. I think it touches on the root cause, which I’ll talk about later. Yet, we also built software that took people to space and beyond in the 60s and 70s with stone age tools and with no debuggers. From the outset of computing we’ve been building complex software. Why is it only now we need so much testing power, and it falls so desperately short of the actual quality we hope for?

“We don’t have time to test”

That is true. We don’t have enough time to code too. We just hack things together, because… because the business says we need it, now, pronto. And the business takes risks, like releasing too early, without testing. So are the business people to blame? The markets? The global economy?
“No time” really means mismanaged time. Or mismanaged priorities. How much code do you produce? Now, how much of it is in use? Wouldn’t it be wiser to focus on building things that work, (as in test them, really test them) rather than twice as much code that only half works? Wouldn’t it make sense to write lean, clean code that does what we need now, rather than prepare it for features that may never come? Features that won’t be used?
We may not have time, but the truth is we don’t really use the time we have as we should.

“We don’t know everything”

That is true. Spoiler alert: We never will. What we learn tomorrow, will contradict what we built yesterday. Then, at the time we’ve learned of the discrepancy, yeah, there is a “bug” there. It gets fixed immediately, because it’s important, and suddenly there is no bug, right? Funny isn’t it, that what we perceive as a bug has a life expectancy. Only the non-important ones get to live longer.
However, most of them are not “it should not behave like this” kind, rather “it just doesn’t work”. A lot of the bugs are not a requirement surprise, they are mostly quality surprises. Yes, we should explore more. We should also validate and test more.

“The requirements change all the time”.

This is the child of “We don’t know everything” and “We don’t have time” arguments. This doesn’t explain bugs, it just gives them an excuse to exist. We still need to test.

“We don’t have enough testers”

Let me translate it for you: “We have so much code that goes untested”. Or “we don’t know what our programmers are doing”. Or “we don’t understand economics”. It has a ring of true, though. If producing code is a linear-order process, testing everything is exponential. Obviously, we need more testers.

(Maybe instead write more code that actually works? You know, automated tests, TDD, clean code? And maybe do some design reviews and code reviews? Sorry, my inner agile just reared its ugly head.)

The argument is really economic in nature. Developers cost more than testers. So getting a 3 devs  to 1 tester ratio may seem economically viable. As viable as thinking developers producing more code equals product success. Makes sense on a piece of paper. The code quantity, however big, still you know, should work, or it’s a waste of precious developer money. And there are ways to do that. (TDD, clean code, automation, reviews. Sorry, that inner agile again).

All the above things almost don’t really explain bugs. Except for the complexity one. But how does complexity breeds bugs exactly?

I’ll continue next time.

Let’s Test 2019: Bringing Test Magic to South Africa


Here’s a bit of news: I’m going to Let’s Test in November!

I’m really excited, for a couple of reasons.

The first is – it’s Let’s Test, baby! I’ve been to the last couple of Let’s Test event in Sweden, and if you haven’t been – that’s a very special event. It’s non-stop hands-on testing. This year, we’re starting at Sunday afternoon, going through the evening (my workshop is at 7pm), and then continue this way until Tuesday afternoon. There’s always something going on, and the community is awesome, receptive, eager to learn and teach.

My workshop is “Zen and the art of Test Maintenance”. It’s going to be shorter than the Test Bash version (2 hours), but awesome in the same way. If you’ve collected, dozens, hundreds and thousands of tests, you feel the maintenance pain. The Workshop teaches how to deal with that pain.

What else am I excited about? It’s going to be my first time in South Africa. I’m hoping to see things in Cape Town, and maybe around it. Hopefully go to a testing meetup. I also plan to visit our local karate dojo, and return a favor after so many years of hosting their visits here.

The final thing is that in Cape Town I’m going to run a new public workshop. It’s intended for developers who want to write better code, and for testers who want to help developers write better code. Details coming soon.

“Spock” Talk at ExpoQA 2019, Madrid

Gil Zilberfeld describes his upcoming talk "Spock" on the unit testing framework that allows clean code and readable tests.

“Why do we need another testing framework”?

Next week, I’m giving a brand new talk at the expoQA conference in Madrid. It’s on Spock – the unit testing framework, not the Starfleet commander. The first question I need to answer is – isn’t JUnit enough?

Sure, there’s TestNG, but other than that – why do we need another unit test framework in the Java world?

The simple answer is – you probably don’t. Spock doesn’t do much beyond JUnit. Actually behind the facade, it does everything that JUnit + Mockito do.

But if we take a step back, we can ask – why do we need other languages on the JVM on top of Java?

When you take a look at Groovy (or Kotlin), you start seeing a difference between how code is written and can be read. You write less code for your program to work, and the language makes the code more readable, and therefore easier to understand and maintain. It’s clean code 101, but it starts even before you write a single line.

Let’s take it back to JUnit and Spock. Can we write readable JUnit tests? Sure, but it requires some extra boiler plate code we need to hide, and a a whole lot of discipline. Spock tests, written in Groovy, are already lighter in code, but also have the label keywords (given, when, then, expect) to make the tests more readable.

Yes, we still need to invest in good names and abstractions. This doesn’t go away. But the experience is more fluid.

Here’s an example of the Spock tests I’m going to show at expoQA.

See, Avengers (and starfleet) make everything cooler.

See you in Madrid!

“Dependency Injection” Talk – The Slides

Gil Zilberfeld explains how testability is impacted by developer decisions like dependency injection

Had a great fun at the meetup, as always. And the fun part was that my message resonated a lot stronger after the lightning talk before mine, where the speaker talked about how the developers chose a technique that made testing hard, because of un-observable and uncontrollable components. So dependency injection is part of clean code, and testability and all that. But there are a lot more decisions, on architecture design and coding, that affect testers, users and other stakeholders.

Remember kids: You maybe “just testers”, but you need to be part of the development conversation. Code is too important to leave to developers.

Here are the slides:

Dependency Injection Talk at the Test.IL Meetup

Gil Zilberfeld is talking about Clean Code principle dependency injection in the TestIL meetup
Gil Zilberfeld is talking about Clean Code principle dependency injection in the TestIL meetup

Next Wednesday, 22 May ’19, I’m giving a lightning talk about a very important topic: Dependency Injection.

Most developers know what it is, and now it’s time for testers to learn about it too – And that’s why this talk is at the Test-IL meetup.

Dependency injection is a wide subject, from frameworks to principles. How it is a direct descendant of the SOLID principles (and therefore how using it as part of clean code principles). How using it in TDD, unit testing and integration testing allows us to replace or mock different parts of the system and check their consumers in isolation.

But there’s a deeper insight when talking about testability which doesn’t even concern code. And I’m going to reveal it in the talk.

Of course don’t miss the other great talks as well.
You can register to the meetup here.