tags:

views:

411

answers:

9

A number of developers are designing their applications using Test Driven Development (TDD) but I would like to know at which stage should I incorporate TDD into my projects? Should I first design my classes, do some unit tests and determine what methods are needed or design methods first and then do some unit tests after?

What is the best way to go about this?

+13  A: 

The point of it being test driven is that the tests drive the design as well as the implementation.

In some cases that's not appropriate - it may be blatantly obvious what the design should look like, especially if it's implementing an existing interface (or some similarly restricted choice) but when you've got a large "design space" TDD encourages you to writes tests demonstrating how you want to be able to use the class, rather than starting off with you how you think you want to implement it.

Generally if something is easy to test, it will be easy to use.

Jon Skeet
A: 

Please look at

http://en.wikipedia.org/wiki/Test-driven_development

They have stated a high level tasks

lakshmanaraj
+5  A: 

The mantra for test driven design:

  • create the test.
  • compile test (and verify that it fails)
  • write the interface
  • compile test (it should compile now)
  • run test (it should fail now)
  • write the code
  • compile/run test (it should do both now)

Repeat for each item.

Gamecat
Final steps: refactor the code; rerun the tests; refactor the tests; run the tests.
John Saunders
@John - Agreed; you're missing the biggest step in there Gamecat!
Gavin Miller
I left refactoring out of the mantra, just to emphasize the steps. But you are right. (And I still leave it out ;-) )
Gamecat
A: 

TDD ensures that developers give equal importance to test cases as compared to their business logic. I followed it in my project and i could see the advantages: Since i started with writing my test cases first, i ensured that my test cases handle all the possible coverages of a business logic, thereby catching/reducing the number of bugs. Some times its not practical since it requires enough time to write these test cases. The bottom line is you need to unit test your code really well.So either you start with implementation and then ensure that there are enough test cases for all the scenarios (Most people dont hence this practice has emerged.) or write the test methods do a dry run and then write your implementation. Your implementation is said to be complete only when all your testcases pass successfully.

Cshah
A: 

You should listen to stack overflow podcast 41 where they talk about TTD. It's hard to say everybody is using TDD and it would be take a lot of time and resources to have a high code coverage percentage. Unit testing could effectively double the development time if you write tests for all of your code.

One of the points from the podcast is that your time and resources could be better used doing other tasks such as usability and new features.

jimiyash
+2  A: 

I'm very skeptical about writing unit tests before implementation. Maybe it would be efficient if you had a good idea about the exact design about the classes and methods required but generally at the start of a new project you don't.

My preferred approach is to acknowledge that the start of a new project can be a bit of organised chaos. One part of the design process is writing code to validate certain ideas or to find the best way. A lot of time the code hits a dead end and gets thrown away and any unit tests written for it would have been a waste of time.

Don't get me wrong I'm all for well designed software and at a certain point it's essential that the organised chaos morphes into a well understood design. At that point the class structure and UML diagrams start to solidify. This is the point TDD becomes important to me. Every class should be able to be tested in isolation. If the design is good with the right degree of decoupling that is easy to achieve usually with a sprinkling of mock objects around the place. If the design is bad testing becomes a real nightmare and consequently gets ignored.

At the end of the day it's high quality productive code that you're after. Unit tests are one of the best tools to help achieve that but they shouldn't take on a life of their own and become more important than the code they are testing which you sometimes get the feeling of from the TDD mantra.

sipwiz
+2  A: 

Start small

a) The next time you add a method to a Utility class, write the tests first for the method. Methods that do string handerling are a good place to start, as they tend to have lot of bugs, but are don’t need complex dataset to test them.

b) Then once you get confidant with writing unit tests, move on the classes that don’t touch UI and don’t talk directly or indirectly to the database.

c) You have then got to decide if you will design your application to make unit testing easier. E.g

  • it is hard to test UI code so look at MVP etc,
  • it is head to test code that access the database, so separate your logic into method that don’t need to access the database to run.

a) and b) has a big payback without having to change how you design the overall system. You have to consider if c) is worth the cost.... (I think it is, but a lot of people don't and often you can't control the overall system design.)

Ian Ringrose
+1  A: 

Ideally you will start to apply TDD when you begin coding. Think about your design first, you can draw diagrams on paper ; no need to use CASE tool, just envision the main classes and their interactions, pick one, write a first simple test, write the code to make it pass, write another test, make it pass, refactor ...

If your process mandates documenting and reviewing the design before the coding stage, then you cannot follow TDD and let your design emerge. You can however make your design first, and then do the implementation test-first. You'll get unit-tests as if you applied TDD, but still applying your process.

Keep your design as hi-level as possible, so that you can let the low-level details of the design emerge.

philippe
+10  A: 

TDD is a coding and design-in-the-small technique. It is not a big-picture envisioning technique. If you starting to write an application, you want to do some storyboards, or wireframes, or even some simple sketches. You should have an idea about the larger-scale design i.e. the classes and relationships in your system. Before you get to the point where you'd start to do interaction design (e.g. methods and arguments) you start doing TDD.

The wireframes you have done will give you an idea of how the system should appear. The large scale design will give you an idea of what classes to create. However, none of these models should be considered correct or permanent. As you write tests, you'll find better design ideas that will change your high-level design, and even your wireframe design.

Uncle Bob
Why is this answer being voted down? If you vote down, could you at least be good enough to leave an explanation of why you feel it's not a good answer?
Limbic System
+1 to combat the haters
Joseph Silvashy