tags:

views:

244

answers:

5

This has been on my mind lately as I can clearly see the benefits of TDD. I can very easily see how tests could drive a good design if the developer has an idea of what the functionality should be. This may be an overly simplistic statement, but from everything that I’ve read, TDD advocates that you have no design beyond your project architecture and framework choices. That being said, I’d have to guess that even the most hardcore TDDers don’t have a completely blank mental design slate when they start working

My question is this: Can TDD be used in an environment where a senior programmer/designer/architect does a class and/or component design and then hands that design off to a junior developer to implement? In this case the tests would not be the primary driver of the design. I suppose the implementing programmer could implement that design using a test first approach. In that case is it still TDD, or is it something that would be better called Test Driven Implementation? Would something like this work in the real world, or do you think you'd end up with the worst parts of TDD and design up front?

UPDATE:

I came across Roy Osherove's blog describing the various meanings of TDD:

What are the possible meanings of TDD?

  1. Test Driven Development: the idea of writing your code in a test first manner. You may already have an existing design in place.
  2. Test Oriented Development: Having unit tests of integration tests in your code and write them out either before or after our write the code. Your code has lots of tests. You recognize the value of tests but you don't necessarily write them before you write the code. Design probably exists before you write the code
  3. Test Driven Design(the eXtreme Programming way): The idea of using a test-first approach as a fully fledged design technique, where tests are a bonus but the idea is to drive full design from little to no design whatsoever. You design as you go.
  4. Test Driven Development and Design: using the test-first technique to drive new code and changes, while also allowing it to change and evolve your design as an added bonus. You may already have some design in place before starting to code, but it could very well change because the tests point out various smells.

After reading that, it is fairly clear that the Test Driven Design flavor of TDD probably isn't the best fit in this environment, but the Test Driven Development flavor would probably fit.

+1  A: 

"TDD advocates that you have no design beyond your project architecture and framework choices

TDD definately does not advocate what you describe above.

UPDATED: I feel it is worth editing this answer due to the updates to the question.

TDD is a more of a design philosophy than it is a testing strategy.

I think this needs to be restated.. TDD is not about testing nor about "test first" development. TDD is about driving out behaviour based on functional & business requirements, some call this evolutionary design.

However, there is nothing to stop design being "shaped" by the your architects plan, so long as it loosely coupled design with testability in mind. As I am sure there have been many non-functional requirements factored into the architect's design.

I would definitely ask the question as to why there is a need to "plan" the entire design up front? Is it a lack of trust in the development team? There are much better ways to share knowledge & design with juniors, than by dictating a complete code solution.. Pair programming with senior developers for example.

More often than not I have seen, this scenario fail. The architects vision, will be over-engineered, un-testable, not widely understood and slowly rot over time as scores of developers/contractors touch the code base not understanding the vision and no tests to fall back on.

Xian
This goes to show how much I do not grok TDD even after much reading and experimenting. Many examples I have seen defer things as simple as class discovery to be test driven. Those examples have had virtually no design up front. Your comment implies that is not a tenant of TDD. Good to know!
Daniel Auger
Well, those examples were "more correct" than you might believe after having read this answer...
Ilja Preuß
I tend to agree with Ilja Preuß at this point. Plenty of people advocate class discovery to be test driven if you are doing Test driven design (not test driven development).
Daniel Auger
+1  A: 

I am not sure that your understanding of what TDD is about is in line with the commonly definition of it, so maybe some reading on the subject could be helpful.

Test Driven Development is primarily about using your test cases as acceptance criteria for your code. I.e. simply you write a test case first and do the testing later. Doing this in short iterations helps and is highly recommended but for me it is not the core of the matter.

The classical cycle of repeat:(add a test->write code to satisfy test criteria)* lives together quite well with other practices such as doing the overall project design done by the architect. The developer's job of write appropriate tests is made much easier if he can use a design document in a same way as writing a functional test case is much easier if you already have a detailed Use Case.

* shortened for convenience
Ilya Kochetov
+1  A: 

In this environment I think it is better to use a contract driven approach.

The architect describes the contract that a class or interface is to implement. The developer then produces the test cases to exercise the contract and the code to implement it.

For example, take a look at Martin Fowler's article on Consuder Driven Contracts, which describes how this approach works with web services: http://martinfowler.com/articles/consumerDrivenContracts.html

Ged Byrne
+1  A: 

We have a design process very similar to your question. In fact we have broken the gap between analisys and implementation with this process. And the designer has unit tests on his design.

Mariano
+1  A: 

TDD is primarily a design strategy. That is, writing the tests first is used to drive the design of the production code, yes.

That does not mean that you don't do any upfront design. Almost anyone I know already has some kind of design in his head when he starts the TDD cycle. After all you need to have at least an idea of where to start, for which class to write a test. Especially if you are practicing pair programming, too, it is recommended to have a short design session up front.

To get the full benefits of TDD, on the other hand, you need to be able to listen to the feedback the tests are giving you about the design, and to incorporate it into your refactoring steps to adapt the design accordingly. And to the amount that you are doing it, you might find that some of the upfront design was wasted, if not harmful because it set you up in a suboptimal direction. Which can especially get you into trouble when someone else came up with the design and - lacking the feedback you got from the tests - disagrees.

So, I'd say that it's not impossible to do TDD in your situation, but that I'd look out for some trouble.

Regardless of whether you are adopting TDD or not, I'd add that your approach seems to smell a bit of the Architects Don't Code anti pattern. I'd think about having the senior developers pair program with the junior members, at least partially. That would mentor the juniors, give the seniors valuable feedback on their design decisions, and reduce frictions that might otherwise appear between those two roles.

Ilja Preuß