Any time we notice something being dependent on something else, or we hear the word if in a description of a function/feature – our next steps can be to explore the conditions and consequences.
The more ifs we hear, the more likely we are to find a problem.
I identified this microheuristic while doing a pairing session with a tester from one of our projects. Working in this mode gives me a great way of using my experience of testing coupled with the domain knowledge of the tester. It also gives me the perspective of being able to more easily analyse how my brain is working while testing – since I have very little domain knowledge and therefore must rely on heuristics and experience.
What is an if?
I know enough about programming to know about if-statements. Logical chunks of software that make decisions based on parameters. For example: if I am older than 18 (in the UK), I can buy alcohol. If not, I can’t.
Envisaging the white box
Knowing this, I often find myself being curious (or even making some assumptions) about how a certain feature might be implemented. If I know that the business logic contains such decisions, then I have a good feeling that there are going to be (at the very least) if-statements that perform this logic. The model I have in my head of the software may be wrong, but I can adjust it and modify it over the course of my exploratory testing.
When ifs can be iffy
One of the basic techniques we learn when we do testing theory is equivalence classes and boundary analysis. Examples might be “the insurance company covers people between the ages of 18 and 25”. Knowing what I know about code, and using the experience I have – I can make an assumption that somewhere the decision is made whether a person is insurable or not.
Even if we’re only dealing with a simple if-then-else (like the drinking age example), there are already classic cases that we can consider. If the age calculation uses “is greater than” instead of “is greater than or equal to”, then we may already have the problem that actually only 19 year olds can order a drink.
Software logic isn’t usually that easy though. The example with the insurance company could potentially involve a more complicated if-statement, or even multiple statements. This also increases the chance that somewhere, a mistake might have been made.
Once we start looking at particularly complicated (or convoluted) domain logic, then we can follow this train of thought and assume (at least to start with) that there may be multiple, nested, and complicated if-statements. They may be dependent on multiple factors. The potential for problems is high.
I have two good examples where this heuristic led me to further test ideas (and to finding an issue, in one case). The first example is the gilded rose kata from Emily Bache. Based on the description of the feature, my first thought was “please don’t let this be implemented with multiple complicated if-statements”. It was. And I’m reasonably sure that that feeling would have led me to test various possibilities.
The second example was in a piece of software I was pair testing with a tester from the team. Based on his explanation of a feature, I said “that sounds like there’s a lot of decisions that need to be made in the background. Let’s explore how they work”. We found an error – because we recognised that there might be logical decisions being made, and that those decisions might not always be unproblematic. We were right.
So here’s the heuristic: ifs are iffy. If (haha) you can recognise that decisions are being made, then explore around those decisions.
|I observe||That the domain logic has dependencies (if this … then that)|
|I think||This is likely represented in the code with if-statements. The more complex they are, the more likely I will find problems|
|My next step||Try to follow the logical paths – paying particular attention to “else”s and combinations of conditions that may be ill-defined.|