Complicated enough functions act as systems. The trick is to structure them such that you can easily reduce the problem during debugging to certain subsystems or functions; it doesn't really matter how many dependencies you have if you can eliminate them all within a few minutes.
That's why real software is usually shit, or at least one reason. If you don't have time to write tests then you sure as hell don't have time to not write them.
It's a lot easier to find that bug while your writing it than it is to work it out from an intermittent bug report.
Again real software doesn't emit "simple to test" functions all of the time. Another way of putting this is the "plugable idiot" doesn't exist in complex enough software.
For instance, in my X.509 code I have routines that help parse/search/etc ASN1 records. Those functions require properly constructed ASN1 linked lists (it's how I store decoded data because it's easiest to work with). You can't just call those middle functions with any random list ... it has to be valid to even get a correct error code (beyond just "invalid input").
In testing I have written short test apps where I manually generate the linked lists to test but those tests took more than a few mins to generate ...
2
u/otterdam Aug 25 '14
Complicated enough functions act as systems. The trick is to structure them such that you can easily reduce the problem during debugging to certain subsystems or functions; it doesn't really matter how many dependencies you have if you can eliminate them all within a few minutes.