What do you think is the most frequent cause of defects? In a moment, I’ll tell you what it has been for my team.
- It is not our occasional lapses in the employment of Test-Driven Development.
- It is not rickety architecture or spaghetti code.
- It is not the failure to consider boundary conditions or edge cases.
Here is a true story that illustrates this defect cause at work. See if you can spot where the bug occurs.
My wife works as a cashier in a very busy grocery store. Of course, the checkout process is largely automated with scanning and credit-card processing. Here’s how it goes from the point that a customer arrives at the register.
- The credit card reader displays a message that invites her to insert her card.
- The cashier unloads the groceries, scanning those that have barcodes and keying in the codes for those that don’t.
- At any time during the process, the customer may insert her credit card. To reduce the likelihood that she leaves her card behind, the system allows her to withdraw her card immediately (before all the groceries are scanned).
- When the cashier is done, she presses a button on the register to indicate that the order is done and send the charge to the credit card company.
- The credit card reader says the transaction is approved.
- Repeat from step 1 for the next customer.
What could possibly go wrong?
Well, many customers, especially the older ones, were complaining of extra charges on their credit cards. “I live alone. How could I possibly have bought $215 worth of groceries on August 21?”
Do you see why?
These unhappy customers had failed to see that their transactions were approved in step 5. The “Approved” message stayed on the screen for a short time, but they were probably fumbling around in their purses and didn’t notice. Often being older, they moved slower and their eyesight wasn’t terribly acute. By the time they looked at the reader again, it was inviting the next customer to insert their card. The slow-moving customer thought her transaction had not gone through, so she inserted and withdrew her card again. The cashier didn’t notice all this and wished her on her way. Meanwhile, the second customer’s groceries were about to be charged to the first customer’s card!
In my last post, I said that failing to consider obvious user-interface issues was the most frequent cause of defects. Within that category, the largest sub-category was failing to think of the user interface from the user’s point of view.
In the grocery-store example, the programmer probably thought she (I happen to know she was a she) had done customers a favor by allowing them to insert and withdraw their card at any point in the process. But had she thought of the process in detail from the point of view of a user who was not paying close attention, she would have designed the user interface differently.
Incidentally, once the problem came to light, the fix was simple. A customer can now insert their credit card only after the first item in their order is scanned.
So how can we help developers to consider the user interface from the user’s point of view?
First of all, developers must disabuse themselves of the notion that they can think like users. Most of us are smart and logical, but as often as not that gets in the way of designing software for a messy and less-than-logical world where, for example, shoppers rummage around in their purses at the critical moment and have trouble seeing the display.
If we are not going to rely on ourselves, we must rely on our users! In our case, we thought we were doing so because we had a sprint review every two weeks where user-representatives could see the brand-new feature we had just written for them.
However, the new feature had to share the stage with several other new features in a time-limited meeting. The users had no chance to think about any features in depth.
Our remedy will be to foster communication between developers and users from an earlier stage by choosing a user representative to work with the developer on each feature and setting the expectation that they meet early and often. This, of course, is how Agile Development is supposed to work: daily communication among all stakeholders. In practice, stakeholders who are not developers have other things to do with their time besides help the developers and we have had to compromise. Turns out we were compromising too much.