Skip to main content

Search...

Dark Side of Testing: The Failures We Cause Ourselves

A test can leak data, expose code or bring down production. The dark side of testing begins with the setup, which needs a risk assessment of its own.

• • 10 min read
Cover of the expert talk on 'Dark Side of Testing: The Failures We Cause Ourselves' with Bart Knaack and Richard Seidl.

The dark side of testing is the set of failures that testing itself causes: test data leaking from a poorly protected test environment, attackers reading code in a weakly secured test system, or a failing test that touches production. Each test setup therefore needs its own risk assessment before it runs, ideally with the network team in the room.

Key Takeaways

  • Testing itself can cause failures: the dark side of testing covers leaked test data, exposed test environments and failing tests that touch production.
  • Non-depersonalized production data on a test system or a CD is ungoverned data; Bart Knaack broke such a CD rather than process it.
  • A test environment with weaker protection than production lets attackers study the code and reuse its flaws against the live system.
  • Testing in production needs its own risk assessment, ideally with a network engineer in the room who knows which environments are connected.
  • Ten thousand end-to-end test cases shrank to 50 after the team moved checks such as address validation into unit testing.

The Dark Side of Testing Begins Before the First Test Run

We test so that nothing goes wrong in production. That is the whole point of the job. Yet the dark side of testing is that the act of testing can cause failures of its own: test data that leaks, test environments that give outsiders a view of the code, production systems that go down because a test misfired. Bart Knaack collects such cases from his own projects, and his diagnosis is blunt. Most of them happen because nobody thought hard enough before the testing started.

His rule for the moment before you press start is short.

“If you can’t bear the consequence of your test, don’t test it.”

(Bart Knaack)

The questions that follow from it come in a sequence. Should we build this at all? How are we going to test it? What will the environment look like, and where will the data come from? Can we build an environment that is good enough for what we want to do, a performance test for instance? And if there is no separate, production-like environment, are we really going to test in production? Each answer carries a consequence, and those consequences are what the dark side is made of.

Most of Bart’s examples sit on the non-functional side: security, performance, governance. His explanation is that teams think quite well about functional testing. The non-functionals get done on the side, and that is where the surprises come from.

How Does Test Data Leak Out of a Test Environment?

Test data leaks when real, non-depersonalized data sits on a system that is less protected than production. A test environment rarely gets the same protection as the production system it mirrors. Someone who gets into it gets the data too.

Bart’s own example did not even need a hacker. A colleague walked into his office and asked him to depersonalize some data. Bart said yes and asked him to put it in a safe environment. The colleague said he had it on a CD. Bart took the CD and broke it. The protest came promptly: that was his test data. Bart’s answer: it was production data on a CD that nobody governed, and that is a no.

The lesson is less about the CD than about the process. How do you set up tests in a safe and secure way, and who is allowed to carry what where? Those are questions to settle before the data moves, not after.

A Test Environment Is a Window Into Your Code

Test environments open a second door. If attackers can get into your test environment, they can study how the code works there and reuse any weakness they find against production. The environment is “only” test, so it is protected accordingly, and that is exactly what makes it useful to them.

Bart’s advice is to treat the protection of the test environment as a design question in its own right. The same applies to a separate performance environment: is it really independent of production, or does it share a database, a network segment, a service? Ask before you run a load against it.

Testing in Production Needs Its Own Risk Assessment

Bart does not advocate testing in production. He also knows that sometimes there is no other choice. When that is the case, the first condition is that you know what you are doing, because you are touching the production system. The second is that you understand the impact of a failing test. If a failing test can bring production down, when exactly are you going to run it?

That turns into a risk assessment of the risk process itself. Many testers already find ordinary product risks hard to think about, and the risks of their own testing even more so. Bart’s point is that this is the job. The surprising part is how often people with a tester mindset make exactly the mistakes they criticize in others.

His practical move is simple. Whenever he sets up something like this, he invites a network engineer into the session. The engineer knows which environment the test environment is connected to, how it is set up, why that particular database is in use. Someone from the ops or network team sits with the testers, and the question on the table is: what could possibly go wrong? Afterwards comes the other half of testing in production, which is cleaning up.

Why Are Checklists Only Half the Answer?

Checklists help you remember things. Bart has written several himself. The problem is that a checklist also stops you from thinking. Once the boxes are ticked, the team concludes that nothing can go wrong, and that is the moment it stops thinking for itself. In Bart’s view you are never safe.

So he keeps away from checklists as much as he can and works with guidance instead: suggestions, and above all questions. What should you think about? What are you trying to prove, and where? A list of questions makes people think; a list of ticks makes them stop.

How the questions get asked depends on the scope. For a big end-to-end chain, a group session can make sense, because people inspire each other and point out that what holds for one system does not hold for another. Big meetings with agendas are a hassle, though, so for smaller topics Bart goes one-on-one, sometimes at the coffee corner with ten minutes of someone’s time. He records those sessions, transcribes them and uses the transcript as the first draft of the report. Then he sends the result around so people can check it and add what others have said.

What If Someone Says It Will Never Happen?

Sometimes the risk is clear to the tester and nobody else wants to see it. Bart’s example comes from a firm with two systems connected by a direct link. As a tester he worked out that if two messages overtook each other, things would go wrong. The engineer’s answer: it is a direct link, messages never overtake, that is a networking issue, do not worry.

Bart asked for it in writing, with a signature, and attached it to the defect. Three months later, traffic grew until the one cable was no longer enough, a network went in between, and messages could overtake. When the team came back asking why he had not tested this, he slid the report across the table.

His conclusion is not triumphant. In most cases people listen; a hint like “you have a link to production, maybe look at that” is usually enough. When they do not, make sure the warning is on record and that you can show you did the right thing.

Why Are 10,000 End-to-End Test Cases a Warning Sign?

A very large end-to-end suite usually means that checks have ended up in the most expensive place to run them. A team once told Bart, with some pride, that they had built 10,000 end-to-end test cases. His reply: then you are doing it wrong. There must be ways to run those tests at an earlier stage.

One example was the address check. Whether an address was valid or not was verified in the end-to-end test, and Bart asked why that did not happen in unit testing. The team worried that a unit test would not show whether the check also worked end-to-end. Bart’s bet was that if it works at the unit level, it works end-to-end. The team moved the checks down and ended up with 50 end-to-end test cases instead of 10,000.

Behind the number sit three questions. What are you trying to prove? Where can you prove it? And do you have to prove it at the point where you are proving it now? Often a less risky alternative proves the same thing, which is the logic Bart applies to testing in production as well.

Quality Is a Collaborative Thing

Bart no longer believes in the silos of testers and developers. His advice for getting started is to sit down with your developer and discuss exactly these questions. In joint workshops he found that developers often did not know the testing techniques, boundary value analysis or equivalence partitioning for instance, which are the tools for designing good unit test cases. So the testers helped them build those cases and set proper asserts. Some tests had nothing but an “assert is true” at the bottom: they raised code coverage and could never fail. Asked what such a test proves, the honest answer was nothing. Bart introduced mutation testing, which shows the value of a unit test far better than what he calls the code coverage fallacy.

Nobody solves this in a day. Start slowly, give examples, let people experience what it means to work this way. His current example is contract-based testing between the consumer and producer side of two APIs. Twenty years ago he did that by hand: take the consumer protocol, take the producer protocol, match them, and the mismatches show up, an integer on one side and a string on the other. He found the first bugs before a line of code was written, and colleagues treated it as a special skill. All he did was read two documents and compare them.

Which brings him to the root of most of these failures: people do not talk to each other, and they do not listen. They get an assignment, go their own way, do what they think is necessary, and at the end it does not fit. A lot of it is about communication, and in Bart’s words, AI will not fix that for us.

He leaves one question open for the next round. When you test an AI, what should you worry about? He refers to a BBC documentary in which AIs trained to be malicious hid those intentions in the test environment and only showed them in production. Whether or not that is already happening, Bart expects it will. The dark side of testing has a next level.

Share this page