Roman Suzi
2 min readJul 22, 2019

--

After many years not mastering TDD, I came to a conclusion, that TDD (or is it even TDD — tests, written before code maybe?) helps only in the cases of logic-rich low-level functions, where specifications is easier to write in a declarative way as input-output “pairs”. So what I am doing is basically coming up with inputs and expected outputs, trying to have typical and rare variations and border cases. Then I write a function, which satisfied more and more tests (at the same time, from many examples I already have good idea which patterns in the inputs to expect). Sometimes code of the implementation suggests more tests, sometimes new input-output ideas come later. I use this more not even for individual functions, but for syntactic expectations of a mini-framework features, for example, to play around new shiny sequence type and ways to access and modify it. So there may be several different actions in one test: creating sequence, adding elements to it, etc, deleting elements, deleting sequence — all that serving as a usage example.

Unfortunately, it is not efficient to apply TDD to everything. For example, some functions in a framework need a lot of fixtures and mocks to test, while the whole logic of the function is some kind of Transaction Script, which does A, B, C in that order, making calls to different modules. Just figuring out how mock data structures, provided by framework, to reconstruct in test, can be big loss to productivity. It’s way faster to just write the function, run it to see some realistic input (for example, from remote call), and then build code and tests around that understanding.

--

--

No responses yet