4 ms·
It seems author misses the point of TDD: TDD is a methodology that allows you to write unit-testable code. Writing unit tests after you write code is a very ha
by necovek 6y ago
It seems author misses the point of TDD: TDD is a methodology that allows you to write unit-testable code.
Writing unit tests after you write code is a very hard, an almost impossible problem (you either refactor everything, or you end up with some "lower level" of integration testing everything, or you end up mocking everything — unless you refactor, your code is unlikely to be unit-testable). Though with practice, one can learn to write mostly side-effect free unit-testable code, but to a non-TDD-enlightened person, that code will look "too convoluted" with simplistic "unneeded" functions. TDD is generally very "functional" in spirit (so for pure unit-testing, no mocks).
Production-level applications do get by with integration and system tests, and infrequently, that's good enough (other than slow test suite run times). But unit tests allow for speedy test suite on top! Unit tests, by definition, do not cover stuff that proper QA would cover: they only ensure that smallest units of work (functions/methods/classes) do what they are supposed to.
One of the common pitfalls with TDD and unit-testing is that you end up having a function that's sufficiently well covered with unit tests, but as it evolves into something more complex, you are lazy or lack the time to properly split unit tests as you split your original function. Then you end up with what I called "lower-level integration testing" above: a bunch of tests testing a single complex function instead of individual units of work.
The biggest advantage of unit tests is that you cover every integration point with only a single integration test (eg. between two classes interacting), and all the edge cases on either side with unit tests. This leads to fast test times that do not test everything for every single combination of arguments.
Replacement for QA are instead system tests. They should neither test all the combinations of system conditions, but should ensure that a couple of critical, common paths through the system are working.
QA teams today, when present, are in charge of managing and writing system tests, but if they are not part of the development team, there's a lot of tension and wasted hours in keeping things up to date.
- lowbloodsugar 6y agoWith some experience, I find it impossible to write code using TDD that is difficult to refactor. Good code, that scores well on SOLID metrics, is easy to refactor, because individual pieces are already split out into multiple classes, rather than living as a series of statements in a single method in a single class. >One of the common pitfalls with TDD and unit-testing is that you end up having a function that's sufficiently well covered with unit tests, but as it evolves into something more complex, A function should not evolve into something more complex. It should be split out into multiple functions, each of which is simple. In addition to being far easier to test individually, you will find that when you need to change it, only some parts will need to be discarded.
- necovek 6y agoI was exactly referring to a function that's split up into multiple simple functions where tests aren't. I agree, it's not a pitfall of TDD, but rather of doing it, then not doing it.