views:

223

answers:

8

When I get excited about a new feature I'm just about to implement or about a bug that I've just "understood", there is the urge to just jump into the code and get hacking. It takes some effort to stop myself from doing that and to write the corresponding test first. Later the test often turns out to be trivial 4-liner, but before writing it still there's the thought in back of a head, "maybe I can skip this one, this one time?" Ideally I'd like to get an urge to write test, and only then, perhaps, the code :)

What method (or way of thinking or mind trick or self-reward policy or whatever) do you use to help maintain the discipline? Or do you just practice it until it feels natural?

+2  A: 

wear a green wristband

OTisler
+2  A: 

1) You pair with somebody else in your team. One person writes the test, the other implements.

It's called "ping-pong" pairing.

Doing this will force you to discuss design and work out what to do.

Having this discussion also makes it easier to see what tests you're going to need.

2) When I'm working on my own, I like to try out chunks of code interactively. I just type them in at the ruby prompt. When I'm experimenting like this I often need to set up some data for experimenting with, and some printout statements to see what the result is.

These little, self-contained throwaway experiments are usually:

  • a quick way to establish the feasibility of an implementation, and
  • good place to start formalising into a test.
cartoonfox
That's great if you actually have a team. How would you go about maintaining a "test first" mentality if you are the sole developer on a project?
Richard J Foster
If I'm soloing, I write the test and the implementation on different days. Sleep helps take out the trash in my mind.
Mike DeSimone
I've been doing TDD for about 10 years now. I'm still learning every day. Getting better at object-oriented programming has helped me - specifically the "responsibility-driven design" school of thinking.
cartoonfox
+6  A: 

I like the instant feedback from the test, that's reward enough for me. If I can reproduce a bug in a test that's a good feeling, I know I'm headed in the right direction as opposed to guessing and possibly wasting my time.

I like working Test-First because I feel like it keeps me more in tune with what the code is actually doing as opposed to guessing based on a possibly inaccurate mental model. Being able to confirm my assumptions iteratively is a big payoff for me.

Nathan Hughes
+4  A: 

I find that writing tests helps me to sketch out my approach to the problem at hand. Often, if you can't write a good test, it means you haven't necessarily thought enough about what it is that you're supposed to be doing. The satisfaction of being confident that I know how to tackle the problem once the tests are written is rather useful.

John Feminella
Yes, very true, writing tests force you to think what exactly the code will be doing. That's probably part of the discipline problem, that thinking about tests first is harder than just starting to type away the details you already know how to do.
Pēteris Caune
+2  A: 

I'll let you know when I find a method that works. :-)

But seriously, I think your "practice until it feels natural" comment pretty much hits the nail on the head. A 4 line test may appear trivial, but as long as what you are testing represents a real failure point then it is worth doing.

One thing I have found to be helpful is to include code coverage validation as part of the build process. If I fail to write tests, the build will complain at me. If I continue failing to write tests, the continuous integration build will "error out" and everyone nearby will hear the sound I have wired to the "broken build" notification. After a few weeks of "Good grief... You broke it again?", and similar comments, I soon started writing more tests to avoid embarrassment.

One other thing (which only occurred to me after I had submitted the answer the first time) is that once I really got into the habit of writing tests first, I got great positive reinforcement from the fact that I could deliver bug-fixes and additional features with much greater confidence than I could in my pre-automated-test days.

Richard J Foster
+1  A: 

I think the important part of keeping yourself in check as far as TDD is concerned is to have the test project set up properly. That way adding a trivial test case is indeed trivial.

If to add a test you need to first create a test project, then work out how isolate components, when to mock things, etc, etc it gees into too hard basket.

So I guess it comes back to having unit tests fully integrated into your development process.

Igor Zevaka
+1  A: 

When I first started doing TDD around 2000, it felt very unnatural. Then came the first version of .net and the JUnit port of NUnit, and I started practice TDD at the Shu level (of Shu-Ha-Ri), which meant test (first) everything, with the same questions as yours.

A few years later, at another workplace, together with a very dedicated, competent senior developer, we took the steps necessary to reach the Ha level. This meant for example, not blindly starring at the coverage report, but question "is this kind of test really useful, and does it add more value than it costs?".

Now, at another workplace, together with yet another great colleague, I feel that we're taking our first steps towards the Ri level. For us that currently means a great focus on BDD/executable stories. With those in place verifying the requirements at a higher level, I feel more productive, since I don't need to (re-)write a bunch of unit tests each time a class' public interface needs to change, replace a static call with an extension method, and so on.

Don't get me wrong, the usual TDD class tests still is used and provides great value for us. It's hard to put in words, but we're just so much better at "feeling" and "sensing" what tests makes sense, and how to design our software, than I was capable of ten years ago.

Martin R-L
+2  A: 

Easiest way I've found is to just use TDD a lot. At some point, writing code without unit tests becomes a very, very nervous activity.

Also, try to focus on interaction or behavioral testing rather than state-based testing.

kyoryu