Today, I was chatting with some coworkers over tea. We were talking about testing software, and I mentioned that I love testing. One coworker looked at me as if I were unhinged stating, "but everybody hates testing". I realised that at some point in the last 2 years I had completely changed the way I feel about testing.
As a Field Applications Engineer I build proof-of-concepts and demos, some of which can get quite comprehensive/complex and even evolve into part of the production system.
Being part of the sales team, I'm far less insulated from the customer's opinion than I have been in more typical, programming roles. I also have far more involvement in getting the specification together and helping the customer figure out what they want.
When what I produce is not working, I really, really want to know.
But what do I mean by 'not working'?
I don't mean that my code throws NPEs or segfaults, has race conditions, or posts your password to reddit.
I don't mean that any single part of the product isn't functioning as such a part should, according to best practices, or even the specification that the customer provided.
What I mean is that it's 'not working' for the customer.
Quite often, the software may be doing exactly as the customer asked; this fact alone is unfortunately not all that important to the business.
So here are some reasons it might not be working for the customer:
- The customer is actually satisfied, but pretending to not be as a bargaining tactic - this isn't my problem
- The code is actually broken
- I've misunderstood the requirements
- There are communication problems between companies, perhaps the project management strategy needs some love
- The customer has misunderstood their own requirements
- The customer has changed their mind (scope creep)
Out of these choices, only the first permits any kind of non-action.
In a typical programming role I found it's very easy fall into the pattern of defending a piece of work, even if it does something the customer doesn't like, or doesn't do everything the customer was expecting.
One can say things like, "it passes the unit tests" or, "it's written according to best practices". Perhaps, "but that's what they asked for".
These claims may be completely correct, and are sometimes even valuable as bargaining chips from a commercial point of view.
But for an effective engineer, these things are an easy distraction from finishing off what you set out to do - to make something that someone else wants.
The customer is disappointed and they want something different; that's the important point.
So when something gets passed back to you as not working, even if the code is correct:
- Try not to automatically argue
- Forget about the code, why do they have a problem
- Try to see what has happened and exactly what disagreement has occurred
- Seek a resolution, obviously
Of course for all the listening you can do and interest you can show, it can still be embarrassing and in some cases, commercially damaging to give the customer something which doesn't work for them.
That is where testing comes in! Testing is like a customer that you can upset as much as you want. They're like the 'compile' button in your programming environment, except rather than looking for syntax and type errors, they can help you zero in on issues in the management of your project or the communication of the requirements.
Issues which if unnoticed, can cause much bigger problems for the project than a lack of unit tests.
To make the most of testing:
- Ensure test engineers are educated about the customer's business, so they can better represent the customer
- Empower test engineers to do more than just tick a 'verified' box; use their unique perspective to help you work with the customer and deliver something they will actually want
Disliking testing is like disliking the compiler because it gives you errors when you forget brackets.
Most programmers have been there, but hopefully outgrow this way of thinking by the time they go to work.
You wouldn't want to send the customer something which might throw a runtime error as soon as they open it; why is it any more okay for it to throw the CustomerDisappointedException?
Sure, it gets the job off of your desk and perhaps onto someone else's after a while, but if that's how you presently spend your 40 hours a week as a programmer, maybe you're in the wrong job.