This story is about testing, to be more specific the right mindset for testing systems and it is about an analogy for testing. It is not about code or testing software. However there are some important aspects in there that also apply to software development.
The broken washing machine
Let me state this first: I am not a technician for washing machines. I use them regularly and trust that they do their job. And i feel uncomfortable when i have to dive into the machines inner workings, because i do not understand them as well as code - and i guess it is the other way around for non-code people when they see what is going on under the hood of there beloved everyday software.
So our washing machine was acting up. The result of washing was less than satisfying the last few weeks and it got worse. After the washing procedure the cloth were very wet and kind of stinky - not what we are used to and what one would expect. So today i decided to have a look at it, before we call a technician or buy a new one. I opened the little front panel and started my examination, which led to a very obvious result after a few minutes: The water pump was blocked. So it started to pull out all kind of things that blocked the flow - coins, plastic parts, hair and a sock (this is the place where socks go to die). And i guess this solved the problem.
Now the next few steps where nobrainers to me, i just did this without questioning why. First i got in there with my gloved fingers and touched every reachable part to make sure that there is no further blockage, that every part that should move was movable and that any part that should not move was fixed. This took one to two minutes. And i was confident to proceed to the next check. Second i manually filled the washing machine with a suitable amount of water from the tap, closed it and told the machine to pump. Afterwards i checked that the water was gone. I did this twice to be sure that the observed result was not a side effect of me emptying all the pipes before. This little test took around five minutes and was successful. So i had confidence to proceed to the final test, the real thing. I put some cloth in the machine - even some renegade socks - and i let it run a whole washing procedure. This took a little bit more than an hour and the result was satisfying.
I guess a professional technician would have done some things differently, but she would probably have followed a similar approach to verify that everything is in order or detect that there are still faults in the system.
What i did there was testing on the three commonly cited levels.
- Unit testing: Test the small parts individually. In this case the parts of the pump that should move, the parts that should not and the adjacent pipes.
- Integration testing: Test that the small parts work together correctly to provide a system functionality. In the case of the washing machine, that water from the inside of the machine gets pumped to the sink.
- System testing: Test that the complete system works together to provide a use case. In the case of the washing machine, that cloth after the washing are clean, stink-free and not completely wet.
And every level helped me to build confidence that the product / machine will work as expected. Of course i could have also jumped directly to the system test, but what information would i get from a failing system test? Only that something is wrong. I would have to start all over again, checking the pump again and any other part of the system that might be involved. On the other hand, if the system test fails after the previous steps, i am sure that another part of the system is also broken, but i would not go into the pump again, to search for fixes. So the lesson here is: Get feedback on your changes to the system at the smallest detail level possible first and then progress to the next higher detail level.
I also get feedback much faster. A system test takes more than a hour in this scenario, while the previous test steps are done within just a few minutes. If one of the earlier tests fails, i can immediately act on this failure and build suitable fixes. If i only run the big system test, i get my feedback after an hour and could then start reacting to that failure. So the obvious lesson here is: Get your feedback as early as possible.
The two lessons from above are actually common sense and should be followed in every software system.
As i have written: The steps of verification kinda were obvious to me at the moment when i had to do them. Unit test, integration test and system test. However there was a time when i did not think that way and those were the dark unprofessional times of my career. Many many new developers and even some senior developers are also at this stage. Having a story like this at hand, that shows how to debug a system that is unfamiliar to you with the help of the right mindset, can facilitate a deeper understanding of testing. This analogy has of course some shortcomings - as is the fate of every other analogy - when applied to the big picture of testing (like manual testing after fixing the problem), but it is still a pretty good relatable starting point. Therefore i like to tell this story and will keep it at hand when i am introducing automatic software testing to novice of the craft, with the hope that someday this mindset will become their second nature.