Sunday, May 29, 2016
Test-driven development: Get done on time with confidence
Test-driven development in its original extreme form is very hard to sell to developers, because it feels like it's slower than traditional style developing.
It's not. It's way faster.
The problem is, that doesn't show up on the first couple hours, it takes a couple of weeks for it to start taking hold.
Now, this probably sounds too good to be true. Kind of like when people say that programming in a functional language without variables is more productive and satisfying - you don't believe it until you give it an honest try, and an honest try requires overcoming some pretty deep-seated habits.
However, you also don't have to go all the way to "write a test first for every feature and run the test to prove it fails when you haven't even written the code to implement the feature it tests". You can make it a little less uncomfortable if you write your first test at the point where you would normally be testing your freshly minted code to make sure you did everything right.
And that's where the big gain starts to appear. Every job requirement for a developer contains a phrase like "very detail-oriented". What that really means is "ery, very careful to not write stuff that won't work correctly the first time". Nonetheless, most of us don't get code that works perfectly the first time even 50% of the times we try, because it's terribly hard. There are so many things that can go wrong.
So if you write a test for each basic functional requirement of the code you're writing, that runs fast and reports sensibly, so you can run it after every time you save a file on disk, you get something you didn't really think about: confidence without that stress of trying to be perfect in your first draft coding. A huge source of stress is disarmed!
Think about it. We all know that the Waterfall method doesn't work, and has never worked, because there is no such thing as a perfect specification - you will discover half the true spec during the project, always. Well, that also applies to coding. You take a good shot at it, and then you test it until it's solid when tested against whatever you can think of that may throw it off.
Now extend this over the period of a project. The old fashioned way, your confidence follows a pattern like this:
You start out with however much confidence you naturally have in your first draft, but since testing is a long time down the schedule, your confidence will erode steadily over time, especially as the specs become more clear and you go back to rewrite portions that were written under the original wrong assumptions. Then, way later, you throw the thing over the wall to QA and start to feel a little confident.
QA sends back a raft of bug reports and the causes of the bugs may be buried very deep in the code you wrote a long time ago, and may be subtle side effects of very basic classes in your design. Troubleshooting and unearthing the root causes is a long, hard, subtle process that takes a long time and is not certain to be completely successful.
Now let's compare that with your confidence when the functionality of your classes is tested every few minutes while you're developing:
Here you start with higher confidence because you don't write as much before you start having automated, repeatable, lightning-fast testing to use every time you touch anything, and every change you make from then on can be run through it again. Now you have no deeply rooted mistakes causing trouble in later times, because you see every error immediately, while it's still fresh in your mind.
QA can take this code and test for functionality and integration and Acceptance and performance as soon as there is enough function to make any given path work, and if you find a design problem, you can change the tests to reflect what you learned too, and make sure design changes go in exactly the right place and don't have any unexpected side-effects, which is a common problem in projects done the old way.
So bottom line: if you want to get done on time, and sleep well at night, and be proud of your work, you write tests along with the basic classes and all the later stages as well, and run them constantly, so you don't have to be perfect. Instead, you can just be productive.
Yeah, this is theoretical, and your mileage may vary, but once you try using detail testing early and often in your cycle, you'll never go back. It would be too scary.