> I am amazed that people took this comment seriously. It was clearly
> a joke. He was poking fun at TDD. The fact that people took it
> seriously indicates that someone (me) should make a more direct
> attack on
TDD.
I don't see how this follows, Ralph.
What I see is a communication problem. I see it frequently enough that I
am now able to describe it. Here it goes.
1. Someone (re)discovers Test-Driven Development, uses it and it helps
that person write better code and generally be more successful at his job.
2. In his haste and excitement, he says, "TDD makes me a better
programmer." He probably means "TDD brings out in me the natural
qualities I already have that make me a good programmer and amplifies
them. I fail much less often when I do TDD."
3. He naturally assumes, as all people do, that what works for him can
work for others.
4. He writes a book, explaining how to do TDD as well as he can. He
hopes that other people will find that TDD helps them as it does him.
5. Since TDD is an idea, necessarily some people think it's a bad idea.
6. TDD's detractors misconstrue our Author's "I think TDD is great and
you should try it too" as "TDD is The Way and if you don't do it you're
an idiot". They do this because it fits with their notion that TDD
doesn't work and that makes them feel better.
Now substitute in place of TDD (and the corresponding comments) XP,
Scrum, RUP, UP, CMM, CMMI, and all that other crap.
Round and round we go... how boring.
Just because I think something is great and recommend that everyone else
try it doesn't mean I think it's a Silver Bullet. It just means that I
think it's a great idea. Is that so wrong?
Just because There Is No Silver Bullet, that doesn't mean that There Are
No Good Ideas!
JBRainsberger
I admit this is a self-serving comment, but I think TDD and developers
writing tests in general is in a different category from some of the other
"good ideas" and that is why I bought www.testdriven.com some time ago and
Sequoia VCs invested in Agitar
http://www.agitar.com/company/2003-000008-sequoia.html .
From my point of view, not doing TDD is like for a surgeon not to wash her
hands before an operation - the risk is just too great. Every developer
should be able to do some TDD, not every developer is going to understand or
master DDD.
Regards,
DavidVydra
To bring this back on-topic, I'll ask a question. How does TDD enhance DDD?
I can think of a few ways. (Some I mentioned in my book.)
1. Assertions are a key part of a model, and can be expressed in the form of
tests (Chapter 10).
2. Test writing puts you in client mode, so you end up devising an interface
that is much more supple for the client developer (chapter 10).
3. Tests should express the goals of the application in the ubiquitous
language. They are excellent vehicles to iron out that intersection between
the model and the requirements.
4. Both 2 and 3 are great opportunities to make the language flow.
Comments? Other observations about
TDD/
DDD? DDDDDDDDDDDDDDDDDDDDDDDDD?
EricEvans
TDD by itself doesn't make point 2 necessarily true. TDD puts you into design mode and it helps you think about the responsibilities objects should have but it doesn't necessarily drive you to create a better domain model or make you think about a clients concerns. As part of TDD you consider DDD concepts then yes TDD does enhance DDD.
or as I tend to think of it
DDD enhances TDD
working knowledge of Patterns enhances TDD
object oriented design enhances TDD
In XP the following helps DDD
Having the customer onsite and availble is really the key to helping drive a good model into place.
Writing / Discussing story cards
Creating Acceptance tests
Metaphor
Point 3 is partly unit tests and a lot acceptance tests. In fact having your acceptance tests expressed in ubiquitous language would be the Mecca of acceptance tests.
Regards,
KeithNicholas
IMHO, TDD is great for the micro level coding and might be all you
need for smaller projects like a bowling game. I think I have done
TDD since I was 13 and first learning C++ spending far to much time
writing assertions and test cases for every thing I wrote. It was
much less formal then TDD but for the same purpose and I often
discarded my tests after I was sure of something (but TDD
enlightened me how useful these are to keep). I used to think I
could take the parts I do understand implement those then when I
have some objects to work with I can start peicing them together. I
found though as my programs got larger in size things my wonderfully
bullet proof objects I spent so much time developing and testing
were worthless and didn't fit the model or needed to be
significantly changed to fit the bigger picture, this can be very
disheartening but as projects grew in size, in the end, I threw out
more then twice as much code as what remained in the end result.
I've learned that it is necessary to see the big picture before you
dive into coding the details of something you don't fully understand
yet. One project in particular where I learned this lesson was an
interface between MS Project and JDEdwards Job Cost I wrote a simple
VB com object that added menu's to MS Project started with the
import features mainly a simple transaction script pattern as it
seemed the easiest I coded what was needed to connect to JDE api in
ATL com objects to make them easy to access from VB and a few weeks
later I had imported and tested all the import features, way to
go!... Then my boss starts asking for export features I start
coding them using simalar transaction script style and tried to pull
out some of the reusable code. I started finding a lot of code was
reusable and that was all well and good and another week or two I
had that developed. We present it to some potential customers and
they were impressed but their was a problem... they used jde html
and don't have fat client installed on thier machine any more (its
about 3GB) so all the jde calls need to be sent to a remote machine
and processed there. Well the easiest thing was to just take these
ATL objects put them on the server and enable DCOM. Authentication
and security became to be an issue, I couldn't display a sign on
screen on the remote computer. The ATL objects were mainly low
level code to call specific jde functions. But the objects that
knew what functions to call also had dependancies on MSProject would
present to much reverse trafic if the client machine even allowed
the server to connect to the object. I had to do some major
refactoring to seperate the components and once they were seperated
I was able to move the objects to the server. But it was slow,
workable but slow. The project became very interesting to some
bigger customers who wanted to know if it would integrate with
Project Server or work with World (older jde version). At this
point my MS Project components were useless they depended to much on
MSProject.Task etc.. my jde server components depended to much on
the OW api and wouldn't support a multi user environment. I didn't
have an ounce of salvagable code. The entire project is a rewrite.
As I started design for the next version of the project I started
thinking about what is the "core domain" both World and OneWorld
share a common domain language so does MSProject and Project
Server. My application was a transalation layer between those 2
domains, my prior application had no real need to explicitly express
the seperate domains mainly they were just parameters to jde bsfn
functions and field values of the project tasks. To begin with my
project was quickly implemented with TDD but as it grew and the need
to explicitly express the domain things began to break far to many
functions needed and tests just added to the list of functions
needing changed before I could even get the program to compile.
Tests needed to be rewritten many became somewhat pointless. I began
to find however that many of my tests were no longer needed, with
the right abstractions the domain objects expressed far better the
constraints and the compiler enforced them, it was no longer
possible to pass in an invaid value... strings are very flexible ya
know but types are strictly checked. In the end I realized TDD has
its place at the micro level... but at the macro level nothing is
better then a well designed domain object.
KurtHarriger
>I found though as my programs got larger in size things my wonderfully
>bullet proof objects I spent so much time developing and testing were
>worthless and didn't fit the model or needed to be significantly
>changed to fit the bigger picture, this can be very disheartening but
>as projects grew in size, in the end, I threw out more then twice as
>much code as what remained in the end result.
If you only have to do something three times to figure it out, you are doing well.
I remember when someone on a conference panel said "Good ideas don't necessarily scale up." Someone responded, "So, does that mean we should only scale up bad ideas?" We scale up good ideas until we find out that they don't work. The only way to find out they don't work is to try.
There really isn't any other way. This is the main idea that Henry Petroski teaches in books like "To Engineer is Human". Of course, we can learn from other people's mistakes, not just our own. But we aren't going to figure out the proper big picture just by thinking hard. We might be able to do it by talking with people who have figured it out already, or we can figure it out the hard way.
When I solve a simple problem in a simple way, usually I never look at it again. Sometimes it scales. More often, it doesn't need to scale. When it doesn't scale, I understand the problem better than I did originally.
>I've learned that it is necessary to see the big picture before you
>dive into coding the details of something you don't fully understand
>yet.
Yes, but you learn what is wrong with your big picture by trying to implement it. Coding without thinking is wrong. Thinking without experimenting is wrong.
Design is a cycle of thinking and doing. You never fully understand until you have been through the cycle a few times. (Well, we never fully understand, we just get to the point where we don't have any
questions.) So, it is wrong to say "don't code until you fully understand".
If you never code, you'll never fully understand.
I think you are doing better than you think.
RalphJohnson
Hi,
Being somewhat new to formal DDD, and working on my first IXP project, something that keeps coming to mind as I read this thread is storytest-driven development.
On our project, we have customers who are domain experts write executable story tests in the natural language of the domain, and we create fixtures to run these tests using the FIT framework. We let the story test, along with constant customer contact, drive the creation of domain classes, and we use the natural language of the domain to name the classes (ubiquitous language). Once the programmer team can describe the domain model, and the customer team can look at it and say that it makes sense to them, we know we are on the right track.
When story tests 'run green', we know we have customer acceptance.
This is slightly different than TDD with csUnit, nUnit, or any of the other xUnit frameworks. We use TDD and unit tests to cover things like algorithm development, technical classes outside of the domain (like storage access, security, etc), and anything else that is not covered by the domain.
My two cents,
ChrisWheeler
> IMHO, TDD is great for the micro level coding and might be all you
> need for smaller projects like a bowling game.
Nobody anywhere (with a mind, that is) is claiming that TDD is a sufficient condition for success.
JBRainsberger
YetMoreSilverBulletNonsense is mentioned on: ThreadView