Friday, May 27, 2016

Testing? We don't need no stinkin' testing!

Today's post is twofold. Let me start with a story.

I was filling out an application online for a service, and the provider wanted my address. Although I'm unclear as to why it was required, it seemed reasonable enough. I was given a simple form with space for a street address, extended address, locality, region, and postal code - all easy enough. As I filled in the street address, the address verification started. As I continued typing, the address verification service displayed matching addresses in a drop-down list directly below the street address. When my address appeared in the list, I clicked it...and a message displayed that the address could not be retrieved. "OK", I thought, "I'll just add the locality, region, and postal code on my own"...but those fields had been disabled by JavaScript.

First, let me offer a few observations about the interface. To begin, I'm giving a +5 bonus on the Craft: Webpage check to the engineers who built the form because they tried to use Progressive Enhancement. If they hadn't, I would likely have been hopelessly stuck. As it was, I was able to turn off JavaScript (I highly recommend the Toggle JavaScript plugin for Chrome, by the way) and complete the form. Next, I'm given a -10 bonus on the Craft: Webpage check for requiring JavaScript to submit the form. Seriously?! Just make the submit button a submit button.

Also, I get why they wanted to turn off the Chrome address autofill - if there's a bad address in the cache it will get propagated to their system of record - but that assumes the person using the computer is less trustworthy than the system validating the address, and that's not always a good thing. Yes, users make mistakes, but that's why we do things like label our inputs and use skeumorphic (or otherwise familiar) design patterns. I would even go so far as to say that if your users are making a lot of "mistakes", like pulling on door handles when they should be pushing, your design needs to change...and there are a lot of examples of everyday things that are poorly designed, just take a look at some of the examples at baddesign.com, so you're not alone.

Addresses, however, are a special challenge. Why? Well, first because if you're doing anything internationally there are several different formats for addresses (luckily for you, http://prototypes.cathmhaol.com/hcard/ has most of them identified by the areas that use them) - there is a significant degree of ambiguity to address. Second, there has been a validation issue for a long time, which is why so many services have popped up to validate both foreign and domestic addresses. This is especially critical for online properties, because delivery is an issue that someone coming into a brick and mortar store does not face. In short, the technical and functional skills required to build a well-performing address component are not insignificant.

As I said earlier, this post is twofold. First, there are issues surrounding the address entry experience in my story. Yes, many of them were eased by the use of Progressive Enhancement - and that is a very important lesson here, because - and here's the second part - stuff breaks. We even have a saying that "complex systems break in complex ways"...and I can tell you based on my experience in the tech industry that it's not a matter of "if" but "when" and it will most likely be at the worst possible time. It will be in the last step of a multi-part process that makes customers so angry that not only will they not return, they'll tell 10 other people about their bad experience and soon you'll have a crowd of people who "know a guy".

So, let's look at what it would have taken to improve this experience - it's actually a pretty minor improvement. You'll notice from the story that there were two responses from the service. One was a response that included a matching address (that I clicked) and one was a response that the address could not be retrieved. Using simple logic we know that the user identified a verified address (so we don't really have to worry about a 'wrong' address) and that there was some sort of error during retrieval. Had the failure (error) case on the retrieval action enabled the fields that were disabled earlier, my work around would not have been necessary.

In order to have the best user experience you're going to want things like validation, autofills, animation, bells, whistles, and even the machine that goes "ping"...but all that complexity comes at a price...and that price is enhanced fault tolerance, error handling, and recovery...and testing...lots and lots of testing. All of that especially comes into play in data validation. In this specific case the engineers didn't need to worry so much about fault tolerance (we know the address is valid), but the error handling could use work. In cases where the fault tolerance or error handling is incomplete, or the testing of those two features is incomplete, you're often better off not having the functionality. Never assume something won't happen, because it will...and because assumptions are not a good thing (Robert's Rule #12). Consider this - "corner cases" and "outliers" exist often enough that we've named them...and if they've earned a name, they've earned our attention.

Now, go give the engineer who tests your code some pizza...or a donut...or a beer - something that says you appreciate them and how often they've saved you by identifying a corner case you missed.

Happy coding.

No comments:

Post a Comment