Sunday, May 31, 2009

Test-driven development and its flavors

Someone asked me on some of my agile courses months ago that what is the difference between test-driven development and test-first programming. I guess I answered right away without much thought that these terms refer to exactly same practice. Later on I've been experimenting with different ways to do TDD and suddenly found out that there really are different flavours of TDD. These all also have their own value and purpose in sw development.

Test-driven vs. Test-first

Test-driven is the traditional strict and very disciplined approach to development. Basically it means the RED-GREEN-REFACTOR cycle where tests are written one test at a time, the simplest possible solution to make that test is implemented and finally the code is refatored.

Test-first gives us means to make some more planning and test design before implementing the solution. We might e.g. write some high-level acceptance tests, integration tests and a bunch of unit tests to see how few tightly coupled classes work. After this the production code is written in order to make those tests pass. This approach might give us an opportunity to look at a broader picture in cases where it is needed.

Development vs. Design vs. Programming

What comes to test-driven development/design/programming I feel that the development is a bit more like an umbrella term. The terms design and programming have more interesting distinction.

Test-driven design is again the more XP way to implement software. We approach the whole design by writing tests that drive our design to certain way. After each test implemented we step back and look at the design and refactor in order to improve it.

However test-driven programming is highly popular approach throughout agile community. Design can be developed in front of whiteboard with few fellow team members and after the design seems suitable for the task at hand we'll move to implementation phase. The programming is done in test-driven/-first manner but with keeping the design in mind.

Well, this is how I see it. How about you? Any thoughts on this?

2 comments:

  1. We use Test Driven Development in our projects.
    We drive our design with the tests. The tests often lead to braking a single class into several smaller classes (Single Responsibility Principle) due to easier testability; or to eliminating classes beause they do not incorporate any real behaviour.

    But, we do design up-front. If you do not make a coarse design before writing your first test then where do you start? You have to think of at least one interface before you are ebale to write the first test.

    While driving the development with tests, this "up-front" design is probably changed and refined. However, I think it is important to always have the coarse design in mind, otherwise it is likely that the code you just developed is clean and working but does not fit with the code your team mate wrote and that they cannot be integrated.

    Therefore, it is important to find the balance between desing up-front (we call that architecture) and driving the details of the design.

    Happy test-driving
    Urs

    ReplyDelete
  2. Good point Urs. Maybe the distinction between the desing and programming that I was looking for was something like this:

    In test-driven design we might have the architecture and an own idea on how to implement that. Then we let the tests drive our class design, design pattern usage etc.

    In test-driven programming we have created as a team or a workgroup a closer class design that fits our architecture but which is more through thought. Of course test driving this might and probably will affect the design.

    Naturally the design should be always on developers mind and in fact I think that TDD requires better design skills from developers. Fortunately it also teaches them in quite fun way.

    Br,
    Tomi

    ReplyDelete