I often get into a debate with people about the type and the extent of testing that has to be done for software. One of the key arguments I hear is that developers should focus on creating only the happy path and leave the rest to the testers to find or have SDETs write extensive automated tests while developers can skip unit tests and focus only on writing useful code.
I have used the swiss cheese model to explain to people about the need for layered coverage instead of concentrating all the effort onto one layer. I first heard this term while watching an air crash investigation episode in nat geo. The narrator explains that though there are millions of parts in commercial airliners, the chance of getting into an accident is far lesser than motorcycles.
How an aircraft with millions of parts is able to get back on to the sky within a few hours after landing from a long trip? The answer lies in layered testing. The pilot has a pre-flight checklist, the ground staff do a routine check for visible damages, the maintenance crew notice the hours of usage and do preventive maintenance, there is a strong network of weather monitoring and routing, ATCs manned with trained staff and modern radars, aircrafts fitted with collision avoidance systems, a long series of protocols for ground and sky movements etc.
It is the same across many engineering and medical disciplines. The risk of something slipping through all the layers of test is very rare and if it happens then it is immediately plugged. In software engineering it is a combination of static checks, unit tests, integration tests, automated ui tests, heuristics & exploratory tests, performance tests etc. No one type of test can be removed altogether and replaced by another. We need the layers to move fast and yet deliver what is required.
Image courtesy: Davidmack, Swiss cheese model of accident causation, CC BY-SA 3.0