What is TDD (Test Driven Development)

Please include both benefits and drawbacks, as well as tools for your taste.

+21  A: 

TDD is the practice of writing your unit tests before the code to ensure

  • No dead code
  • Good code coverage
  • Better design (you think about the client of the method before the implementation details)

That's most of the obvious pros. Some cons include:

  • Takes time to get used to
  • Can be painful, especially if you're doing it in a legacy code base and have to "mock up the world" to get the test done
  • You're very likely going to have trouble making the rest of the team do it too.

Even with the cons, I believe TDD is hands down the most important change to my programming style so far. Highly recommended. :)

edit: The tools.

When doing .NET: For the tests themselves, I use NUnit. For mocks, I lean towards Rhino.Mocks. I use the built-in test runner of ReSharper to run the tests in Visual Studio.

When doing Java: JUnit, JMock and the built-in runner of Eclipse.

You missed IMHO the most obvious con: - You need to write and maintain a lot of code (the tests themselves) which isn't used in productionMost everybody who uses TDD doesn't see this as a net negative, but it does take a bunch of energy. Without the tests a comparable amount of energy would go into maintaining and debugging the production code.
+5  A: 

A main advantage of TDD is that it lets you focus on your codes behavior (TDD generally leads quickly to BDD). TDD isn't so much about testing code, as it is about functionality and emergent design.

Karl Seguin

I'm not quite TDD - I can't seemingly get the hang of writing tests up front.

I write a test, write the code, do another helper function, and maybe another then go back and write the tests. Also sometimes I miss edge cases in the test code. But the important thing is that the tests help highlight these instances and once you do notice them they can be tested for easily.

Some things are very hard to test (threaded code, gui, legacy-code) but with a few rules you can work around it.

+1  A: 

TDD stands for test driven development. this is where by the whole development process is targeted toward passing tests setup beforehand. someone put it better saying you follow the following three rules:

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

sorry i can't recall who wrote the above but they sum up the whole spirit of TDD imho

+1  A: 

There's loads of tool support for TDD, which is part of the thing that makes it desirable. Depending on language, you will need to change your test-write-build-deploy strategy, and some of these can help.


If you're having trouble with the idea of writing tests up front, I highly recommend Specter, if you're working in .NET/Mono - it's an extension of the Boo compiler chain, so is quick to prototype (in Boo, but you can obviously use any .NET language if it suits your fancy better), but focuses more on Behavior-Driven-Design, and has a runner similar to the NUnit one, and it integrates with the NUnit tools. In essence with BDD, you are writing functional specs for your code, in code, and your implementation process is simply filling out that spec coverage, with the advantage that you need not even have specified the subjects before your specs can be compiled and run.

Matt Enright
+7  A: 

TDD is a simple ruleset for writing code. You write a failing test (red), write just enough code to make it pass (green) and then refactor any duplication (refactor).

One of the keys is to think about TDD from a design perspective. You are writing your application by thinking about how someone would be using the next method or functionality you are working on. You verify that you are writing the correct code by your test passing when it is done.

Since most people are dealing with codebases not written using TDD, I'd highly recommend the book Working Effectively with Legacy Code by Michael Feathers. I'd also recommend the TDD list -

As far as tools - it depends on the language. .NET has NUnit, xUnit.NET, MbUnit, and the tools in Visual Studio. I've used all of them except MbUnit, and I do some work on the NUnit project. For Java, I've primarily used JUnit. There are libraries for other languages - Ruby, Javascript, Python, etc.

The pros are that you are writing your code knowing that something is interacting with your class. Also, as you write your code, your tests become a safety net to work with. You can feel more confident in making changes to the code base - I know I certainly do.

The drawbacks are initially the learning curve. TDD is a new design and development technique. So one feels like they are going slower for the first little bit. However, with practice, it's a pretty easy curve to get over. Some of the other drawbacks are tests that are too slow (because they are coupled to things like databases or file systems) or tests that are too brittle (typically because of the same thing). In addition, sometimes when you are working on a heavily changing code base, you end up having to change the tests along with it.

In addition to the unit testing tools, I also use other tools to augment - things like FitNesse for automated acceptance testing. Being disciplined about keeping the automated unit tests (especially as defined by Feathers) separate from integration and acceptance tests will keep you and your fellow developers from chucking all of the unit tests out the window.

Cory Foy
+1  A: 

tdd on wikipedia


An article on Test Driven Development / TDD


I'm a big fan of TDD.

For mocking, I recomend MOQ.


It has become debatable whether TDD should be better considered Test Driven Design rather than Test Driven Development since it is really a technique that emphasizes design by forcing the developer to define the desired behavior (through a unit test) before coding the actual implementation. This also helps keeps the developer focused on the single goal of the method and helps resist 'functionality creep' where methods can end up trying to do way more than they were meant to and become more difficult to debug and more likely to fail.

Jim Anderson