No one I know can operate at their peak performance all the time. How do we know how hard to work on quality? Same way you get to Carnegie Hall.
I don’t TDD everything I code, and I hope I’m not the only one. In particular, I don’t even know how to TDD my occasional Second Life code that moves physical objects around. I do know how to TDD complex functions that compute values going into the physics calls, and I do often TDD those. Sometimes I automate the tests. Sometimes I test them in a more ad hoc way, checking output values and such through what amounts to console writes.
Even in SL, though, I am very focused on writing small, self-contained, expressive functions for anything of substance. And, if it’s a little script just to find out how something works, or create a demo for someone, sure, I’ll just type it in. Usually I get away with it.
I’ve been working on programming for nearly a half century, and I’ve paid rather a lot of attention as I went along. I’ve noticed when things went well, and when they didn’t. I’ve related those experiences back to what I did, and what my teams did, as best I can. I learned quite a while back (unfortunately not a half-century back) that as good as I may be, I am no match for my own ability to make mistakes, and that I need to work in ways that protect me from myself.
So I use the best judgment I have at any given time. Well, I try to. It’s not uncommon for me to have the feeling that I ought to test something better, or clean it up more, but hey, it looks pretty good, let’s just go with it.
Sometimes that works. That tells me that my judgment is pretty good, right? Well, except that sometimes it doesn’t work. And when it doesn’t work, I find that I am in for some really strange results, a lot of trouble trying to figure out what has gone wrong, and long sessions debugging something that I could have tested well enough to have prevented those long sessions.
That tells me that my judgment isn’t as good as I’d like, because for the life of me I can’t tell the difference between when I felt like slacking and got away with it, and when I felt like slacking and fell into the pit.
It's Not Just Bad Luck
I don’t subscribe to the notion that bugs just happen, that bad things happen to good people, even in programming. Bugs get installed by programmers’ fingers, due to mistakes in programmers’ thinking. My thinking.
Every time I don’t like the results I get, I have the absolute certainty that I could have done better. The universe does not screw me over when I’m programming: I screw myself over.
I believe it’s the same for you. Your results depend essentially entirely on what you, and your colleagues, do.
My Personal Results
In my work, I’ve never seriously regretted writing another test. Sometimes I’ve written a redundant test. Sometimes I even write tests for fun. (Did you know that any bowling game that alternates strikes and spares will have a score of 200? I like to test that one.) But the moments writing those tests have never caused me to miss a deadline, or even a bus.
I’ve never regretted pushing a bit to make the code more clean. Another few moments extracting a function or giving something a reasonable name, or making the code express my ideas better have never caused me to miss a deadline, or even lunch.
OK, I admit it, I have deferred lunch sometimes. To look at me, perhaps not often enough.
I have often, while debugging some piece of crap that Evil Ron wrote, regretted not testing, regretted not making the code more clear.
I have never regretted pushing a little harder toward clean, well-tested code. I have often regretted not pushing enough.
Maybe that’s just me. I rather doubt it.
What Has Helped Me
I have practiced TDD, refactoring, the rules of simple code, for years. However good I may be, it is practice that has done it.
In my chosen work, I’ve been able to to a lot of that practicing in my own free time, and I have enjoyed doing it. If I were working full time, I am sure that at the end of most days, I would not be inclined to go home and program for fun.
I used to program after work for fun. During my first marriage, I had a KSR-33 Teletype in my bedroom. I emphasize "first marriage".
Many people have lives. If you have one, you are fortunate, and I hope you preserve it. So you may not be as inclined as some to practice programming at home. But practice is how we get good. What are you to do?
I think you have to practice on the job. To be good, really good at what you do, you need to practice TDD, refactoring, expressive code, and all the rest, in the code you write day in and day out. You will learn in proportion to the time you spend outside your normal comfort zone. You don’t need to go all the way out into space, but you do need to push beyond your normal level, as much as you can.
What happens when we do that is that our normal level rises. We become quicker at writing tests; we choose better tests to write; we write our code more clearly the first time. All these things reduce the time we need to spend reworking the code to work, to be tested, to be clean.
I really don’t believe that you can go faster to a working, viable product, over any period longer than a few days, by cutting back on test or code quality.
I know for certain that you can go faster over any period of time larger than a few weeks, by upping your game, by writing a few more tests, improving your code a bit, every day.
What happens in between those few days and those few weeks? That’s up to you. If you practice, I think you’ll go faster. If you don’t, when the few weeks are up you’ll be just the same in capability, but surrounded by more bad code. Is that going to make you happy?
You get to choose how you work. Choose, pay attention, and choose again tomorrow, next week, next month, forever.