I'm in agreement with you on what TDD means (at least
that's what it means to me). I start systems with a bit
of a design. Whether it's something in my head (if I'm
the driver in a pair in which I'll communicate the
design through tests to my pair) or something on a
whiteboard, cocktail napkin or notes jotted down in a
text file. As for TDD being bad, I suppose that's true
if you're purely driving a design out of tests and you
couldn't architect yourself out of a paper bag. For the
rest of us, I think it's a fabulous tool for
communication, collaboration, and evolution of a design.
Related (possibly identical) to #2 is Test-conscious
design and architecture => Every design and
architecture should have testability as one of the
fundamental requirements. This applies to
Alpha-architects and as-you-go-Architects equally. In
its full form, it should realy be *-conscious-design,
where * =
Testability
Security
Performance
Scalability
Maintainability
Simplicity
A related term (possible identical) to #1 is
Test-driven-Programming. This is not 'design' although
it might have a flow-back effect as syntax etc
crystalises while coding. This is where I personally
feel that TDD actually works. For this, the idea is
1. you have a solid architecture/design in mind
2. you have a reasonable idea of the type of code you
are about to produce (rough form, syntax, hierarchies,
core fragments), but its not a formal UML or anything
crazy.
3. you have an overriding desire to not produce any
lines of code that are not unit-tested, either due to
philosophy, or awareness that your planned code is
risky/complex/likely to have issues.
If all of 1,2,3 are true, then TDP is great. you write
tests, you write code, you get green lights, you get
near-100% coverage and its all happy and well-behaved.
Refactoring during TDP s truly refactoring rather than
'wow I had no idea I was going about this backwards, I
better rewrite everything', which is clearly not normal
refactoring.
I personally do not like the concept of TDD meaning
test-driven-DESIGN where, for some reason, the
syntactical form of a unit test is supposed to pre-date
thinking about the problem.
Hi Roy,
I think one of the issues with Agile is that a lot of
people do not have experience of using waterfall via a
methodology, like SSADM, and thus do not understand what
agile was reacting against. Instead they compare agile's
statements to some ersatz, light weight, in-house agile
methodology (which is, in a sense where agile grew
from).
I think this problem is as prevalent in the agile
community as outside it.
So when XP talks about not doing 'big-design up front'
it is reacting to the multi-month design phases that
characterized waterfall where in a 9 month project, the
first 3 months would be spent doing design.
I do not believe that Agile intends that you do not have
an idea of where you are heading with your design.
Crystal expects there to be a design produced from its
Exploratory 360 phase. I think that XP expects there to
be an idea of design, because I think that the reason
for whole team involvement in the Planning Game is to
have a design conversation amidst the team while they
begin implementing.
But with Agile these activities take hours or perhaps
days, not months. We learn about our destination, and
some key way markers on the journey, but we don't
necessarily know the whole route.
The problem is that we have lost the context in which
Agile was formed, and many exponents are mouthing the
mantras, without understanding the reason for them. That
lack of understanding is, I think, damaging to Agile,
and people need to step back and ask why more often.
In turn, I think you'd have to define design. To me,
design is thought and collaboration - not a piece of
paper. As you hint, you can start coding with a design
solely in your head. But the point is the design is
there, even if not physically manifested.
But people who start a development without any thought
or collaboration (design) deserve all the pain they get.
TDD does not a *substitute* for design, it is a tool
that can be used to *aid* design. That brings us full
circle back to Jim's statement about it deteriorating
design. I would also love to read the cited papers.
A TDD approach to evolving design from scratch is a
demanding exercise in OO design skills. It is a hard
thing to do without the proper requisite knowledge in
recognizing code smells and how to refactor to better
solutions.
However, it is also one of the best ways I have
encountered to sharpen those skills. Studying design
patterns and refactorings builds up the potential for
design improvement and TDD instills it into practice.
Doing one without the other is ineffective.
For developers without a high level of skill in these
areas, I would question how effective prescribed designs
are really going to be anyway. Perhaps TDD will
deteriorate your design in these cases, but thats likely
a symptom of poor design in the first place.
Excellent post. I'm a bit horrified that someone
speaking as an authority would lay out a blanket
statement like "don't do TDD".
I guess I hadn't really thought of what TDD means to me,
but I'd say #3 or #4 is probably accurate. And I
completely, 100% disagree with Jim's view. There is zero
doubt in my mind that TDD has made me a better, more
productive developer and has improved the design of my
projects.
I agree with you that TDD means that you write tests
first, and evolve your design as you go. I find that
this works well. I may have to change my design as the
application grows, but that's expected, and refactoring
the code to fit the new design is never a big deal. That
said, sometimes I design the whole thing on paper before
writing any code --- I like to have some idea where I'm
going, even if the destination changes on the way, as I
spot improvements during development.
In my experience, TDD certainly doesn't kill my designs
--- TDD makes my designs better.
PS. Ron will be upset that you added an extra "e" in the
middle of his surname.
Hi
According to what many are talking about, many say that
BDD or Behavior Driven Development is more reliable than
TDD and gives better production and code, you´re
basically giving people what they want. If you have a
good time again you can blog about that too, would be
fun to see the results and comparison of the two
I think one thing missing from the discussion is the
granularity or degree of TDD.
In SQL, we all know that 5th NF is better than 3rd NF.
But 5th is rarely practical.
I think you have good test in place "just "before or
"just" after a design and get the benifiets.
Also TDD'ing database and GUI can be impracticle. Stick
to TDD'ing the unique code you wrote.