Would Heu-risk it? Part 9: Beyond the Border

Picture of a fantasy style map

Today we have another weapon coming up, meaning we are looking at a point of attack. I have some good examples for this one so let us get right into the rhyme:

“When you think the program is done
But the loop makes another run
Crashing and spoiling all the fun
Maybe there’s a variable, off-by-one”

So, what does it mean?

OOOOH I love this one! So, there are a bunch of reasons for this! We all know it: The risk for bugs is way, WAY, higher around the edges. Right?
Have you considered why?

I can think of a few reasons. Some are related to coding errors and some are related to communication/human errors.

1: Start counting at zero
In a lot of programming languages, we start counting from zero. Most of the rest of the world starts at one.
If you are counting something seven times, say when cooking, you would go “1, 2, 3, 4, 5, 6, 7” = seven iterations.
But, if you are writing a loop, or searching for something in a list, you would probably go
“0, 1, 2, 3, 4, 5, 6” = seven iterations.
But, our brain knows it is looking for the 7th thing so it is very common that we mistakenly go for an eight iteration “0, 1, 2, 3, 4, 5, 6, 7
Or we are running through a list of 7 things from start (0) to number-of-items-in-this-thing(7). Which causes an error because the last index (the 7th item) is actually 6, since we started at 0.
And yes, just to complicate things, some programming languages start from 1. (Usually math languages like Fortran, MatLab, SmallTalk, Erlang)

2: Comparison and logical operators
So, we compare a lot in programming. “Do this as long as x is bigger than y”, “Do this while my age is below 50”, “If Anna has more money than Elsa, do this”.
There are a bunch of comparison and logical operators and it is very easy to make mistakes with them. I will just describe a few, there are lots of resources out there to explain how this works in any particular language, I’d advice you to read up on the languages used in your particular stack. Such an easy way of levelling up your tech skills!
> bigger than vs >= bigger than or equal to
< smaller than vs <= smaller than or equal to
I can’t tell you how often I find bugs that simply are using the wrong operator.

3: Ambiguous rules
And also: it is not always obvious how the edges should actually work. Especially since people are so bad at using actual examples when describing how something is supposed to act.
3+ or+3, does that mean 3 and more or does it mean more than 3?
I am certain there is a “correct answer” but I also know for a fact that people use it differently.
Start and end dates are not always obvious. Sometimes rules should include them, sometimes they should not. )
Any time people state rules like “X should work from the n:th day”, I promise there are at least 3 different ways people interpret what date it should start working.
Again: it does not matter if there is a “right way”, people will still interpret it in different ways.
And, of course, there might be different dates that could as “the first day”, depending on context. I have worked with insurances that some things counted from the day someone injured themself, some counted from the date they reported the injury, some counted from the first sick day, some counted from the first day you went to the doctor… all in the same insurance. Of course people make mistakes!

Story time

In Sweden we have a system where, when you get sick, you have 1 day without pay (waiting period), then your employer pays for a while and then the social insurance system takes over after two weeks.
I worked on a system that was supposed to only let you report your sick leave when you had been sick long enough for the social insurance system to kick in. This was implemented in order to avoid getting a bunch of applications with illness that was too short to be covered anyway. Because these messed with out statistics and it was unnecessary work for our users, both internal and external.

During my time in that company I believe we changed that algorithm three times, and I am sure we closed at least as many bugs as “as designed”. Nowadays the rules are explained more clearly, with more of an example-style, but for a long time the requirement/insurance rules were so ambiguous that there were at least three different interpretations.
And of course, it was easy to make mistakes while testing, counting a day too much or too little to see when the field should get enabled or stay disabled.

It was amazing to see people try to figure it out and listen to them argue on what the correct date actually was. A lot of counting on fingers!

Quote of the day

“There are only two hard things in Computer Science:
cache invalidation, naming things,
and off-by-one errors.”

Martin Fowler, Leon Bambrick

Reading suggestions

Off-by-one-errors – Wikipedia
Why are off by one errors so common and.. – Software eng. stack exchange
Boundary value analysis – Evil Tester
Boundary value analysis in real life – Evil Tester
Uncovering hidden boundary values in testing – John Ruberto

Previous posts in the series

Title and linkCategory
Part 1: IntroductionNone
Part 2: Mischievous MisconceptionsTrap
Part 3: The RiftWeapon
Part 4: The FascadeTool
Part 5: The Temptress’ TrailsTrap
Part 6: AlliesWeapon
Part 7: Don’t turn backTool
Part 8: The GluttonTrap
One Comment

Add a Comment