| I'm not sure if I go even further or not, but I'm perfectly happy to write code first and then write tests. And I will sometimes not write tests until I start debugging code and start thinking to myself "is it a buggy bit of this function I haven't tested yet?" and so I'll write the test to prove it isn't that bit. With code I'm getting paid for I'll write more tests up front and won't skip that step, but for code I'm playing with then as long as I'm just enjoying myself writing code I'll write zero tests for awhile and just code. Then as I hit the debugging/refactoring step I'll do the backfilling as a form of debugging. Often I'll write the code that fixes the bug, then write the test, then quickly and temporarily revert just the code to ensure that the tests fail and then proceed. That gets you the same safety check as doing it the test-driven way to validate your test actually tested the right thing. I really tend to hate "thou shalt start by writing tests" as some kind of immutable golden rule. It does always feel good to me when I just naturally wind up doing it, but forcing myself to do it every single time just isn't any fun at all. At the same time tests are absolutely essential when it comes to refactoring and debugging. When you get too far out ahead of yourself with code then you start needing to shore up the foundations and use tests to eliminate bugs in the code that you've already written. Some code though is obviously correct enough that in personal hobby projects I won't ever code tests for them (unless I do hit the point where I start to doubt their correctness due to some funny bug at which point the situation has changed so I add some tests to prove it one way or the other). The whole point of this though is that the tests are always serving me and they aren't in the drivers seat quite the way that all the TDD 101 blog posts like to ram down your throat and which I suspect turns people off from that approach so much. The end result is also that you'll tend to wind up with the tests that are actually useful, covering the code that is particularly hairy or essential and the edge conditions that you really need to make sure to get correct, and you wind up having a test suite which is composed mostly of useful tests instead of all the largely useless ones that infect codebases. I'll also happily omit tests on lower level functions that are well tested at the level above them, because I don't need to test the same thing at 18 different levels (again, for professional use I'm more likely to include tests at every level if they're fairly mechanical to produce). I also have a flexible definition of what the system under test is, which often encompasses more than just the immediate object that I'm testing and I don't bother wasting mental effort thinking about how to mock the whole world. I don't know what kind of TXX that is. I still wind up with tests, they're legitimately essential to have, I just don't get there via some prescriptive route. I wind up with good code coverage, but I don't necessarily wind up with it looking as comprehensive as rotely banging out lots of unit test. I typically wind up with tests that I know are useful because they were produced by hitting actual bugs or where I had real questions about the behavior of the code and needed to assert some invariants and prove the code worked. |