3 ms·
"The cross product of those paths with the possible state configurations of all global data (including instance data which, from a method scope, are global)
by ed-209 7y ago
"The cross product of those
paths with the possible state configurations of all global data
(including instance data which, from a method scope, are
global) and formal parameters is indeed very large. And the
cross product of that number with the possible sequencing of
methods within a class is countably infinite."
Sounds more like a condemnation of OOP than of unit testing, and I do genuinely feel sorry for the unit testing, OOP purists out there. I prefer to design more functional methods, which operate on parameters and injected config instead of instance state and/or globals (cringe). Incidently, this approach makes full coverage attainable.
"Large functions for which 80% coverage was
impossible were broken down into many small functions for
which 80% coverage was trivial. ... Of course, this also
meant that functions no longer encapsulated algorithms. It was
no longer possible to reason about the execution context of a
line of code in terms of the lines that precede and follow it in
execution"
I can reason about such an implentation MUCH more effectively by glancing at the small bit of higher level code which integrates everything (and as mentioned above by foresaking instance state and polymorphism). This strikes me as a bit like advocating a flat directory structure cause it's important to be able to see all your files at once.
- ereyes01 7y agoYeah a lot of the 90s/early 2000s OOP stuff I learned in school seemed to always result in really tightly coupled systems and bespoke webs of tests and fixtures that strung along weird dependency chains in unwieldy spaghetti piles that did no good. Following TDD has helped me land at decoupled functional interfaces like the ones you've described, and it all scales and composes so nicely, yet stays very tractable. Robert Martin sketched 2 diagrams in [1] that elegantly illustrate these two different design patterns and how testable usually means composable and more tractable: [1] http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Ar...
- MetalGuru 7y agoI wish he gave actual examples to illustrate what he was talking about. So you have an additional API layer the tests hit to call the functions you’re testing? Do endpoints map to classes? Modules? So aren’t you just tightly coupling this API to your service? When the service changes, you still have to update the API. Can you explain to me how this solves the problem?