View Full Version : A Challenge for all TDD programmers, ICFP
Uncle Bob (Robert C. Martin)
06-23-2003, 05:39 PM
"John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> might
(or might not) have written this on (or about) Mon, 23 Jun 2003
08:40:30 +0100, :
Is TDD an appropriate technique for a project such as this contest where:1. the requirements are fully known and fixed2. the duration of the project will be very short, ie 3 days2. there is no maintenance phase
Yes, it's a very applicable approach for a task with those three
attributes. Programmers write the tests to make sure that their code
works as expected. (Frankly it's astounding to me that anyone would
argue against such a policy.) Programmers write tests *first* to make
sure that they know what the code they are about to write is supposed
to do.
The main benefit of TDD, so I am told, is to produce code that can be moreeasily maintained/refactored? Hence its use in Agile methodologies that areaimed at projects with uncertain or changing requirements.
That's one reason, but there are others. Writing tests first can be a
good way to sneak up on a simpler solution than one had anticipated.
Writing tests first is a good way to make sure you know precisely what
you are about to write. Writing tests first is also a very technique
for supporting changes to the code, even when the requirements don't
change.
Robert C. Martin | "Uncle Bob"
Object Mentor Inc.| unclebob @ objectmentor . com
PO Box 5757 | Tel: (800) 338-6716
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python |
Uncle Bob (Robert C. Martin)
06-24-2003, 04:53 PM
"John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> might
(or might not) have written this on (or about) Tue, 24 Jun 2003
12:17:24 +0100, :
"Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote inmessage news:7daffvs64o2trpm9qb8h6iuj57opepbusv@4ax.com... "John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> might (or might not) have written this on (or about) Mon, 23 Jun 2003 08:40:30 +0100, :Is TDD an appropriate technique for a project such as this contest where:1. the requirements are fully known and fixed2. the duration of the project will be very short, ie 3 days2. there is no maintenance phase Yes, it's a very applicable approach for a task with those three attributes. Programmers write the tests to make sure that their code works as expected. (Frankly it's astounding to me that anyone would argue against such a policy.)I do not think you should be astounded if someone queries the applicabilityof TDD to all circumstances.(I guess you would be justifed in being astounded if someone argued againsttests in general, needless to say this is not the case.)
I think it *is* the case. Tests written after the fact are polluted
by the preconceptions of the author of the code. Tests written before
the fact are much purer tests of what must be accomplished. This fact
has been driven home to me over and over again as I employ TDD and
compare it to the post-testing I used to employ.The main benefit of TDD, so I am told, is to produce code that can bemoreeasily maintained/refactored? Hence its use in Agile methodologies thatareaimed at projects with uncertain or changing requirements. That's one reason, but there are others. Writing tests first can be a good way to sneak up on a simpler solution than one had anticipated. Writing tests first is a good way to make sure you know precisely what you are about to write. Writing tests first is also a very technique for supporting changes to the code, even when the requirements don't change.Writing tests for every class, as per TDD, will probably double the totalamount of code.
Probably *more* than double.
This is a big overhead.
Yes, it is. But compare it to the overhead of debugging. When you
practice TDD the time you spend in a debugger shrinks by several
orders of magnitude. I know this because I haven't used a debugger
myself in years. And my average time between test executions is a
matter of minutes. Yes, there are times when a bug slips through, but
they are extraordinarily rare.
Moreover TDD is not needed to ensurethat code works as expected. Module test or automated functional test can dothe job more cost effectively.
Perhaps, but I have never seen tests as complete as those that are
produced by TDD. When testing is left to the end, it suffers the fate
of all things that are left to the end, it doesn't get finished.Agreed that TDD can:1. Help you know precisely what you are about to write.2. Support changes even if the requirements don't change.But s/w engineering practices such as these, and language constructs such asthose that support polymorphism, encapsulation etc, are of most use in largeprojects. In very small projects such as this contest their use is not soclear cut. This is demonstrated by the team that came second last year. Theywrote in C!
I quite agree. TDD is not the technique to use to win a silly
programming contest, just as sterile procedure is not the technique to
use to win a "who can amputate an arm fastest and have the patient
live for two weeks" contest. TDD os a technique to employ for long
lived projects that have to survive lots of requirements change.
Robert C. Martin | "Uncle Bob"
Object Mentor Inc.| unclebob @ objectmentor . com
PO Box 5757 | Tel: (800) 338-6716
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python |
Costin Cozianu
06-24-2003, 05:25 PM
>>Agreed that TDD can:1. Help you know precisely what you are about to write.2. Support changes even if the requirements don't change.But s/w engineering practices such as these, and language constructs such asthose that support polymorphism, encapsulation etc, are of most use in largeprojects. In very small projects such as this contest their use is not soclear cut. This is demonstrated by the team that came second last year. Theywrote in C! I quite agree. TDD is not the technique to use to win a silly programming contest, just as sterile procedure is not the technique to use to win a "who can amputate an arm fastest and have the patient live for two weeks" contest. TDD os a technique to employ for long lived projects that have to survive lots of requirements change.
Actually, the programming contest is very smart, it's not at all a silly
programming contest.
If nothing else, than for the fact that grand master programmers
regularly participate. Simon Peyton Jones , Xavier Leroy, you know
people that actually have advanced the state of the art in software and
computer science.
If top notch programmers are able to solve programming tasks and write
correct programs in 36 hours that a typical team of industry people
would take at least 1 month to compete, then the logical conclusion is
industry people should try to learn and emulate the methods and
technologies used by the top programmers.
Aren't XP-ers able to come up with anything but lame excuses ?
At least, rather than denigrate it is much more honourable to just shut up.
Tom Plunket
06-24-2003, 11:32 PM
Costin Cozianu wrote:
If top notch programmers are able to solve programming tasks and write correct programs in 36 hours that a typical team of industry people would take at least 1 month to compete, then the logical conclusion is industry people should try to learn and emulate the methods and technologies used by the top programmers. Aren't XP-ers able to come up with anything but lame excuses ?
I always love logical fallacies being used to prove a point.
Most entertaining, especially in a newsgroup where the posters
presumably write software.
-tom!
David Lightstone
06-25-2003, 03:24 AM
"John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> wrote in
message news:1056524163.538459@ananke.eclipse.net.uk... "Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote in message news:8pghfv4qju7f5f1o0uv1n24dntfs0fpvpu@4ax.com...> "John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> might> (or might not) have written this on (or about) Mon, 23 Jun 2003> 08:40:30 +0100, :>> >Is TDD an appropriate technique for a project such as this contest where:> >> >1. the requirements are fully known and fixed> >2. the duration of the project will be very short, ie 3 days> >2. there is no maintenance phase [snip]Agreed that TDD can:1. Help you know precisely what you are about to write.2. Support changes even if the requirements don't change.But s/w engineering practices such as these, and language constructs
such asthose that support polymorphism, encapsulation etc, are of most use in largeprojects. In very small projects such as this contest their use is not
soclear cut. This is demonstrated by the team that came second last year. Theywrote in C! I quite agree. TDD is not the technique to use to win a silly programming contest, just as sterile procedure is not the technique to use to win a "who can amputate an arm fastest and have the patient live for two weeks" contest. TDD os a technique to employ for long lived projects that have to survive lots of requirements change. This was my impression. I thought that Thaddeus's challenge, ie to prove
the benefit of TDD by competing in this contest, was not well founded since
the *main* benefits of TDD could not be demonstrated in such a context.
Having established that the *main* benifits can not be demonstrated, which
benifits can? (ie are there any benifits other than the *main* benifits?)
John
John W. Wilkinson
06-25-2003, 04:51 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message
news:5EfKa.863$S_5.392@newssvr17.news.prodigy.com... "John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> wrote in message news:1056524163.538459@ananke.eclipse.net.uk... "Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote
in message news:8pghfv4qju7f5f1o0uv1n24dntfs0fpvpu@4ax.com... >> "John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com>
might >> (or might not) have written this on (or about) Mon, 23 Jun 2003 >> 08:40:30 +0100, : >> >> >Is TDD an appropriate technique for a project such as this contest where: >> > >> >1. the requirements are fully known and fixed >> >2. the duration of the project will be very short, ie 3 days >> >2. there is no maintenance phase [snip] >Agreed that TDD can: >1. Help you know precisely what you are about to write. >2. Support changes even if the requirements don't change. > >But s/w engineering practices such as these, and language constructs such as >those that support polymorphism, encapsulation etc, are of most use
in large >projects. In very small projects such as this contest their use is
not so >clear cut. This is demonstrated by the team that came second last
year. They >wrote in C! I quite agree. TDD is not the technique to use to win a silly programming contest, just as sterile procedure is not the technique to use to win a "who can amputate an arm fastest and have the patient live for two weeks" contest. TDD os a technique to employ for long lived projects that have to survive lots of requirements change. This was my impression. I thought that Thaddeus's challenge, ie to prove the benefit of TDD by competing in this contest, was not well founded since the *main* benefits of TDD could not be demonstrated in such a context. Having established that the *main* benifits can not be demonstrated, which benifits can? (ie are there any benifits other than the *main* benifits?)
Perhaps, however what I meant was that the main *effects* of the benefits
could not be demonstrated. I did not meant to imply that there were also
minor benefits, although this may be the case.
John
Costin Cozianu
06-25-2003, 05:04 AM
Tom Plunket wrote: Costin Cozianu wrote:If top notch programmers are able to solve programming tasks and writecorrect programs in 36 hours that a typical team of industry peoplewould take at least 1 month to compete, then the logical conclusion isindustry people should try to learn and emulate the methods andtechnologies used by the top programmers.Aren't XP-ers able to come up with anything but lame excuses ? I always love logical fallacies being used to prove a point. Most entertaining, especially in a newsgroup where the posters presumably write software. -tom!
More lame excuses.
David Lightstone
06-25-2003, 05:36 AM
"John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> wrote in
message news:1056545640.197320@ananke.eclipse.net.uk... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message news:5EfKa.863$S_5.392@newssvr17.news.prodigy.com... "John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> wrote in message news:1056524163.538459@ananke.eclipse.net.uk... "Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com>
wrote in message news:8pghfv4qju7f5f1o0uv1n24dntfs0fpvpu@4ax.com... > >> "John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> might > >> (or might not) have written this on (or about) Mon, 23 Jun 2003 > >> 08:40:30 +0100, : > >> > >> >Is TDD an appropriate technique for a project such as this
contest where: > >> > > >> >1. the requirements are fully known and fixed > >> >2. the duration of the project will be very short, ie 3 days > >> >2. there is no maintenance phase [snip] > >Agreed that TDD can: > >1. Help you know precisely what you are about to write. > >2. Support changes even if the requirements don't change. > > > >But s/w engineering practices such as these, and language
constructs such as > >those that support polymorphism, encapsulation etc, are of most use in large > >projects. In very small projects such as this contest their use is not so > >clear cut. This is demonstrated by the team that came second last year. They > >wrote in C! > > I quite agree. TDD is not the technique to use to win a silly > programming contest, just as sterile procedure is not the technique
to > use to win a "who can amputate an arm fastest and have the patient > live for two weeks" contest. TDD os a technique to employ for long > lived projects that have to survive lots of requirements change. This was my impression. I thought that Thaddeus's challenge, ie to
prove the benefit of TDD by competing in this contest, was not well founded
since the *main* benefits of TDD could not be demonstrated in such a context. Having established that the *main* benifits can not be demonstrated,
which benifits can? (ie are there any benifits other than the *main*
benifits?) Perhaps, however what I meant was that the main *effects* of the benefits could not be demonstrated. I did not meant to imply that there were also minor benefits, although this may be the case.
I only inquired, because you seem to have implied that there were other
possible benifits. (ie benifits other than the *main* benifits)
John
Jeff Grigg
06-25-2003, 05:55 AM
Costin Cozianu <c_cozianu@hotmail.com> wrote... Actually, the programming contest is very smart, it's not at all a silly programming contest.
It's a silly contest done by smart people. ;->
(Actually, I think it's a well designed interesting and challenging
contest, from what I've seen.)
If nothing else, than for the fact that grand master programmers regularly participate. Simon Peyton Jones , Xavier Leroy, you know people that actually have advanced the state of the art in software and computer science.
You expect me to pit the loser CowOrders I work with against "the
masters?" (And highly motivated college students with too much free
time and not much need for sleep! ;-) What, you think I'm NUTS?!?
If top notch programmers are able to solve programming tasks and write correct programs in 36 hours that a typical team of industry people would take at least 1 month to compete, then the logical conclusion is industry people should try to learn and emulate the methods and technologies used by the top programmers.
Maybe. The techniques may not be scalable much past 36 hours. And
business requirements tend to be boringly unchallenging -- and yet
high volume (lots of 'em).
Aren't XP-ers able to come up with anything but lame excuses ? At least, rather than denigrate it is much more honorable to just shut up.
If I were to enter the contest, I would certainly use Test Driven
Development. I'm convinced that doing so would improve one's chances
of winning.
But I happen to be planning on going on the "Foot High Pie Ride" (a
bicycle ride) this Sunday, and to work on Monday. The contest doesn't
particularly excite me, personally.
Costin Cozianu wrote:
If top notch programmers are able to solve programming tasks and write correct programs in 36 hours that a typical team of industry people would take at least 1 month to compete, then the logical conclusion is industry people should try to learn and emulate the methods and technologies used by the top programmers.
Usually in these contest the skills tested are much different that
skills needed by usual business application:
contests:
- requirements are clear
- algorithms are usually complex
- integration is not a problem
- politic is not a problem
- math is usually important
- can reasonably be done by one or two programmers
real life - business apps:
- requirements change continuosly
- algorithms are usually simple
- integration with legacy is a problem
- politic is a problem
- no math needed
- usually need a team of (often) distributed programmers
It appears to me that these contests test the geekness of a programmer,
but real business problems are usually communication ones.
"top-notch programmers" in a contest *could* also be completey useless
in a professional team
uL (who - many years ago - participated in similar challenges in
mathematics)
Costin Cozianu
06-25-2003, 09:50 AM
ugo wrote: Costin Cozianu wrote: If top notch programmers are able to solve programming tasks and write correct programs in 36 hours that a typical team of industry people would take at least 1 month to compete, then the logical conclusion is industry people should try to learn and emulate the methods and technologies used by the top programmers. Usually in these contest the skills tested are much different that skills needed by usual business application:
I don't think at a close analysis this assertion holds. And by the way,
typical "industry programmers" don't get to do only "ususal business
applications".
contests: - requirements are clear - algorithms are usually complex - integration is not a problem - politic is not a problem - math is usually important - can reasonably be done by one or two programmers
I had almost the same discussion in comp.database.object, after they
started whining when I presented them with the challenge to build one of
the most basic object models I can think of. Vendors don't have this
feature or that feature, or the problem is not complex enough to show
their advantages, yet is simple enough to show their disadvantages
There's this grand self-delusion if you will, that you have a method
that cannot deal with simple problems but it will scale almost
miraculously when you deal with very complex problem.
My limited life experience, as well as many accounts from the greatest
programmers and mathematicians (Dijkstra comes to mind), tells me that
if you can't deal with simple things elegantly and effectively, there's
no way to scale up to complex things.
real life - business apps: - requirements change continuosly
Or do they ? In some cases the may, but in many cases people are very
much unskilled and unread in requirements engineering.
Haim Kilov will be organizing yet another workshop this year at OOPSLA :)
- algorithms are usually simple
And people get them wrong. Whenever a slightly more complicated
algorithm is called for, they fall in their face.
There are more than enough programming problems in the "industry" or
"professional" settings that call for non-trivial algorithm.
- integration with legacy is a problem
Because legacy was built with the same nasty habits.
- politic is a problem - no math needed
The same illusion recurring over and over again.
- usually need a team of (often) distributed programmers
Usually too many programmers doing too little, too slow. Wasting much of
their time fighting with arcane languages that suffer from accidental
complexity, complex libraries, unreliable implementation, poor
documentation.
Also reinventing things because they don't know things exists, and they
have little curiosity to find out.
It appears to me that these contests test the geekness of a programmer, but real business problems are usually communication ones.
That's a commonly recurring myth. Communication is *one* of the many
problems. Solve the communication, and you're still left with many more.
You just need to look at SAP or Oracle Financials database schema for a
little bit. You have to hear a boss scared to death that a little change
in the business model (as simple as another payment or invoice method)
might cost tons of money (hundreds of thousands easily) in
"customization", on top of already paid millions of dollars for licenses
and roll-out costs.
Then maybe you'll agree with me that "real business software" suffer
from many more problems, not just the mythical "communication problem".
"top-notch programmers" in a contest *could* also be completey useless in a professional team
I rather doubt that assertion.
As a matter of fact some of their work is publicly available and is more
professional than many "professional".
Should we take the ones I mentioned above. Let's then compare the
quality of design and implementation between
- Haskell (ghc, hugs) ( Peyton-Jones a major contributor, also
participated in ICFP contest -- I think his team got 2nd)
- Ocaml ( Xavier Leroy the brain behind it and the main executor)
- Java (I saw your sun.com email :) )
An objective comparison will show that Ocaml and Haskell, have way
better design, better engineering, better basic libraries, lower defect
rates. Arguably the 2 languages do a lot more and are more complex to
implement than Java. The 2 language/platforms are developped and
maintained with an order of magnitude or more lower budget.
So it's not like in industry we develop business application only. And
even for those business app that we do, after seeing a few, and doing a
few, I come to doubt the quality of our current technologies and
engineering practices.
One thing I know for sure: more "math", more geekness, and top notch
designs will seriously improve the quality. That's why I think that any
programmer that calls huimself professional, should at least follow on
this contest, and study the most interesting programs.
There's a lot that you can learn from some of the best programmers in
the world.
uL (who - many years ago - participated in similar challenges in mathematics)
The bottom line that I wanted to suggest is that this "slight of hand"
dismissal of objectively good results with excuses like "it doesn't
apply", "it doesn't scale", it's not "professional" or "production"
code, etc, etc, is typically without merit.
Uncle Bob would better recognize the quality of programming practices,
and the mastery of "the art of computer programming" exhibited in these
contests, or if he thinks he can do better with TDD or UML for Java
(have you noticed that absolutely nobody uses UML in these contests?)
he's free to compete, or another good option is just to shut up about it.
Denigrating is pretty much as lame as you can get.
Costin
Dirk Thierbach
06-25-2003, 02:15 PM
"Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote: I quite agree. TDD is not the technique to use to win a silly programming contest,
The "silly" aside, I am not so sure. The ICFP contest usually focusses
on correctness first, and TDD should help there. Performance becomes
only important after the incorrect (buggy) programs have been thrown
out. (Well, there must be some way to find a "winner").
TDD os a technique to employ for long lived projects that have to survive lots of requirements change.
While I agree, I'd still say that the contest mirrors some of the
issues of "real" projects. You have to write a lot of code in a
very short time. While the requirements themselves don't change,
there may be "stages" in the task. And usually it is not obvious
which approach works best, so you try different algorithms -- so
you change the implementation (though this is not forced by a
requirements change).
And of course this contest doesn't "prove" anything -- and it is not
meant to prove anything: The main aim is to have fun solving an
interesting problem over the weekend. (Or, for the "lightning"
category, in only one day). At most, it gives you "bragging rights"
for your favorite language, if you're so inclined :-)
But still it is often interesting to look at the results.
- Dirk
[F'up to c.s.e-p]
Tom Plunket
06-25-2003, 02:59 PM
Costin Cozianu wrote:
I always love logical fallacies being used to prove a point. Most entertaining, especially in a newsgroup where the posters presumably write software. More lame excuses.
Please enumerate the excuses in the above post.
Thank you,
-tom!
Phlip
06-25-2003, 06:49 PM
Tom Plunket wrote:
Costin Cozianu wrote: I always love logical fallacies being used to prove a point. Most entertaining, especially in a newsgroup where the posters presumably write software. More lame excuses. Please enumerate the excuses in the above post.
Your excuses are called "lame", not because they are, but because they
support a system the poster has never tried. But he thinks he knows
enough about such a system to flame anyone attempting to describe it.
This is what real zealotry looks like, Tom.
--
Phlip
Uncle Bob (Robert C. Martin)
06-25-2003, 06:50 PM
Costin Cozianu <c_cozianu@hotmail.com> might (or might not) have
written this on (or about) Tue, 24 Jun 2003 18:25:38 -0700, :
Agreed that TDD can:1. Help you know precisely what you are about to write.2. Support changes even if the requirements don't change.But s/w engineering practices such as these, and language constructs such asthose that support polymorphism, encapsulation etc, are of most use in largeprojects. In very small projects such as this contest their use is not soclear cut. This is demonstrated by the team that came second last year. Theywrote in C! I quite agree. TDD is not the technique to use to win a silly programming contest, just as sterile procedure is not the technique to use to win a "who can amputate an arm fastest and have the patient live for two weeks" contest. TDD os a technique to employ for long lived projects that have to survive lots of requirements change.Actually, the programming contest is very smart, it's not at all a sillyprogramming contest.
The word "silly" was inappropriate. I apologize. It was not my
intent to ridicule the contest.At least, rather than denigrate it is much more honourable to just shut up.
Excellent advice!
Robert C. Martin | "Uncle Bob"
Object Mentor Inc.| unclebob @ objectmentor . com
PO Box 5757 | Tel: (800) 338-6716
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python |
Uncle Bob (Robert C. Martin)
06-25-2003, 06:50 PM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> might (or
might not) have written this on (or about) Wed, 25 Jun 2003 11:24:49
GMT, :
"John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> wrote inmessage news:1056524163.538459@ananke.eclipse.net.uk...
This was my impression. I thought that Thaddeus's challenge, ie to prove the benefit of TDD by competing in this contest, was not well founded since the *main* benefits of TDD could not be demonstrated in such a context.
Having established that the *main* benifits can not be demonstrated, whichbenifits can? (ie are there any benifits other than the *main* benifits?)
The code in a programming contest has a short lifetime. Once the
judges are done with it, the code is dead. What's more the judges may
not look at the code at all. They may simply look at the results.
Clearly this is not similar to a real development project. Clearly
the way you would write a program in order to win a contest like this
would be different from the way you would write a program that had to
survive years of changing requirements.
While TDD helps us create code that behaves properly, it also helps us
create code with a good internal structure. The tests also provide a
lot of documentation about the design and implementation of the
system. These benefits might not be apparent in a contest that
measures only performance and time to completion.
Robert C. Martin | "Uncle Bob"
Object Mentor Inc.| unclebob @ objectmentor . com
PO Box 5757 | Tel: (800) 338-6716
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python |
David Lightstone
06-26-2003, 04:05 AM
"Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote in
message news:1evjfv46jmi7oapqpqeg68kqfdhd1t21t4@4ax.com... "David Lightstone" <david._NoSpamlightstone@prodigy.net> might (or might not) have written this on (or about) Wed, 25 Jun 2003 11:24:49 GMT, :"John W. Wilkinson" <john.wilkinson@spirentcom_removethis.com> wrote inmessage news:1056524163.538459@ananke.eclipse.net.uk... This was my impression. I thought that Thaddeus's challenge, ie to
prove the benefit of TDD by competing in this contest, was not well founded since
the *main* benefits of TDD could not be demonstrated in such a context.Having established that the *main* benifits can not be demonstrated,
whichbenifits can? (ie are there any benifits other than the *main* benifits?) The code in a programming contest has a short lifetime. Once the judges are done with it, the code is dead. What's more the judges may not look at the code at all. They may simply look at the results. Clearly this is not similar to a real development project. Clearly the way you would write a program in order to win a contest like this would be different from the way you would write a program that had to survive years of changing requirements. While TDD helps us create code that behaves properly, it also helps us create code with a good internal structure.
Kind of pushing the envelope here Bob. Can you describe the relationship
between writting a test (first or otherwise) and the structure of the code?
Yes you can refactor (after a test fails) to improve the structure. But you
can refactor before the test fails also, so the structure is independed of
writting the tests (first or otherwise)
The tests also provide a lot of documentation about the design and implementation of the system.
I thought that red herring was resolved a long time ago. Only if the tests
themselves are documented or understandable. Is documenting tests one of the
things done? (before or after writting them? If before would you call that
Documentation Driven Test Driven Development, DDTDD or put more simply
waterfall? If after pick your own term)
These benefits might not be apparent in a contest that measures only performance and time to completion.
I guess you have a different preception of benefit than I. IF you can't
draw the relatuionship between both an observable and a control, and the
alledged benifit, its just doubletalk.
Robert C. Martin | "Uncle Bob" Object Mentor Inc.| unclebob @ objectmentor . com PO Box 5757 | Tel: (800) 338-6716 565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com Suite 135 | | www.XProgramming.com Vernon Hills, IL, | Training and Mentoring | www.junit.org 60061 | OO, XP, Java, C++, Python |
Robert Oliver
06-26-2003, 04:28 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message
news:jkBKa.5184$S13.3272@newssvr32.news.prodigy.com... "Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote in
.... While TDD helps us create code that behaves properly, it also helps us create code with a good internal structure. Kind of pushing the envelope here Bob. Can you describe the relationship between writting a test (first or otherwise) and the structure of the
code? Yes you can refactor (after a test fails) to improve the structure. But
you can refactor before the test fails also, so the structure is independed of writting the tests (first or otherwise)
Test Driven Development (TDD) is a lot more than Test First. However, if
you want to explore the relative timing issues, here is what I have observed
in my code:
Writing the test first means I actually have a test for each feature. When
I write a test after the code, even if it is done quickly afterward, I think
I do a poorer job at it and sometimes test less in an effort to move on to
the next feature.
Writing the test first focuses my effort on features rather than
implementation for much of the coding cycle. When I focus on
implementation, I tend to become absorbed in how to do things rather than
what needs to be done and the program nearly always gets more complicated
than it needs to be.
Tests support refactoring. When I skip to refactoring without a complete
suite of passing tests, I can make errors that are not detected until later.
TDD clearly doesn't automatically lead to a good design, but I find it helps
me a great deal. I always go into a session with some idea of how to
implement some feature. Often, TDD leads to a surprisingly more simple
solution than I would have implemented with upfront design.
YMMV. Do your TDD experiences lead you to conclude something else?
Regards,
Bob Oliver
David Lightstone
06-26-2003, 04:48 AM
"Robert Oliver" <oliverb@hfl.tc.faa.gov> wrote in message
news:bdeoiv$ict$1@faatcrl.tc.faa.gov... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message news:jkBKa.5184$S13.3272@newssvr32.news.prodigy.com... "Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote
in ... While TDD helps us create code that behaves properly, it also helps us create code with a good internal structure. Kind of pushing the envelope here Bob. Can you describe the relationship between writting a test (first or otherwise) and the structure of the code? Yes you can refactor (after a test fails) to improve the structure. But you can refactor before the test fails also, so the structure is independed
of writting the tests (first or otherwise) Test Driven Development (TDD) is a lot more than Test First.
My intent was to indicate the TDD does not provide code structure as a
benifit. Because you can inmprove the code structure of the code independent
of TDD. (test first or otherwise)
However, if you want to explore the relative timing issues, here is what I have
observed in my code: Writing the test first means I actually have a test for each feature.
When I write a test after the code, even if it is done quickly afterward, I
think I do a poorer job at it and sometimes test less in an effort to move on to the next feature.
Conduct a gadenken experiment. Write the code first, then pertend you are
doing TDD. Will you still do a poor job?
YMMV. Do your TDD experiences lead you to conclude something else?
My experiences lead me to belief that TDD is no better than anything else.
Sorry, but the application development subjects me to non-disclosure of
methods and practices specific to the organization
Uncle Bob (Robert C. Martin)
06-26-2003, 05:40 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> might (or
might not) have written this on (or about) Thu, 26 Jun 2003 12:05:35
GMT, :
"Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote inmessage news:1evjfv46jmi7oapqpqeg68kqfdhd1t21t4@4ax.com...
While TDD helps us create code that behaves properly, it also helps us create code with a good internal structure.Kind of pushing the envelope here Bob. Can you describe the relationshipbetween writting a test (first or otherwise) and the structure of the code?
By writing a test first, we are designing the shape of the production
code that we are about to write. By definition, we are designing that
shape to be testable. One of the criteria for being testable is being
isolatable. We can't test something if we can't isolate it. Thus, by
writing tests first we are driven to design the production code to be
decoupled.
In OO languages this manifests itself as simple interfaces that
surround the production code. The tests implement those interfaces,
supplying the services that the production code needs under control of
the tests.
Thus, we test GUI control code without the GUI. We test database
access code without the database. We test hardware control code
without the hardware. We have decoupled the system.
Yes you can refactor (after a test fails) to improve the structure.
A failing test does not usually tell us that our structure is bad. It
tells us that we have solved the wrong problem. Once the tests all
pass, *then* we can restructure the code while keeping the tests
passing.
The tests make it much easier to restructure the code since we can
make small changes without fearing that we will break things.
The tests also provide a lot of documentation about the design and implementation of the system.I thought that red herring was resolved a long time ago. Only if the teststhemselves are documented or understandable.
And the documents are only understandable if they are documented and
understandable. I hate to be facetious here, but at some point
somebody has to take responsibility for writing things that people can
understand. Why not the programmers? Why not the tests?
In any case, reading a test can tell you a *lot* about the
expectations of the programmers who wrote it.
Is documenting tests one of thethings done? (before or after writting them? If before would you call thatDocumentation Driven Test Driven Development, DDTDD or put more simplywaterfall? If after pick your own term)
Consider the following test (drawn from a real project I am involved
in):
public void testWikiWordRegexp() throws Exception
{
checkWord(true, "SimpleWikiWord", "WikiWord");
checkWord(true, "ThreeWordWikiWord", "WordWordWord");
checkWord(false, "DoubleCapitals", "HelloDDouble");
checkWord(true, "Initials", "RcM");
checkWord(false, "Hello", "Hello");
checkWord(true, "many words", "WikiWordWithManyWords");
checkWord(true, "dot seperated", "WidgetRoot.ChildPage");
checkWord(true, "three level", "GrandPa.FatheR.SoN");
checkWord(true, "Dot at start", ".RootPage.ChildPage");
checkWord(false, "Lower case at start", "lowerCaseAtStart");
checkWord(true, "SubPage", "^SubPage");
checkWord(true, "SubPage Multiple", "^SubPage.SubPage");
}
OK, now you don't know anything about the program it is testing, and
you don't know anything at all about the structure of the code. What
can you tell from this test -- anyone?These benefits might not be apparent in a contest that measures only performance and time to completion.I guess you have a different preception of benefit than I. IF you can'tdraw the relatuionship between both an observable and a control, and thealledged benifit, its just doubletalk.
I didn't understand that paragraph.
Robert C. Martin | "Uncle Bob"
Object Mentor Inc.| unclebob @ objectmentor . com
PO Box 5757 | Tel: (800) 338-6716
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python |
Phlip
06-26-2003, 06:21 AM
Uncle Bob (Robert C. Martin) wrote:
checkWord(true, "dot seperated", "WidgetRoot.ChildPage"); checkWord(true, "three level", "GrandPa.FatheR.SoN"); checkWord(true, "Dot at start", ".RootPage.ChildPage"); checkWord(false, "Lower case at start", "lowerCaseAtStart"); checkWord(true, "SubPage", "^SubPage"); checkWord(true, "SubPage Multiple", "^SubPage.SubPage"); } OK, now you don't know anything about the program it is testing, and you don't know anything at all about the structure of the code. What can you tell from this test -- anyone?
Ooh ooh, I know!
At fault time, the diagnostic message itself (displayed in the test runner)
will document what code ability just broke.
If the programmer broke a behavior, the diagnostic itself will describe the
conceptual significance of the failure. The programmer has the option
(subject to review, of course) of changing the test data to match the code's
new behavior.
Further, because the behavior >must< have broke due to the most recent edit,
following the rules, the programmer also has the option of rolling back that
edit and starting again. Only 1 to 10 changed lines could possibly have been
affected.
(Reading the test is fun too, but I would have put everything in columns, in
a mono font:
public void testWikiWordRegexp() throws Exception
{
// expect sample concept
checkWord(true , "WikiWord" "SimpleWikiWord" );
checkWord(true , "WordWordWord", "ThreeWordWikiWord");
checkWord(false, "HelloDDouble", "DoubleCapitals" );
checkWord(true , "PcP", "Initials" );
checkWord(false, "Hello", "Hello", );
checkWord(true , "WikiWordWithManyWords", "many words", );
checkWord(true , "WidgetRoot.ChildPage", "dot seperated", );
...
}
And note if you have clean columns, you can comment all of them with a
header row at the top.)
--
Phlip
Michael Feathers
06-26-2003, 06:51 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote "Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote By writing a test first, we are designing the shape of the production code that we are about to write. By definition, we are designing that shape to be testable. One of the criteria for being testable is being isolatable. We can't test something if we can't isolate it. Thus, by writing tests first we are driven to design the production code to be decoupled. In OO languages this manifests itself as simple interfaces that surround the production code. The tests implement those interfaces, supplying the services that the production code needs under control of the tests. Thus, we test GUI control code without the GUI. We test database access code without the database. We test hardware control code without the hardware. We have decoupled the system. Are not all those attributes the characteristics of "good" design? These characteristics are all achievable without TDD and may (not) even be achievable with TDD. (You can't call it a benifit if it can't be achieved)
They are achievable in theory, but hardly ever in practice. I've seen some
code in the field that I like, and would qualify as "good design" by most
industry measures, but nonetheless hides too much and makes it hard to write
the tests you'd like to write as you modify it.
Too often, textbook "good design" does things like make public methods
non-virtual, declare classes or methods final, use mutable statics
prolifically, etc. Lots of things look good if you never try to test
something. Often people who attempt to do a "good design" try to use
language features to make bad things impossible to do. The sad thing is
that they make many good things impossible as well. You can usually expose
this sort of over-engineering by trying to compile and run classes in a
separate program, a test harness. If a class can only work in the program
it was designed in, and you can't extend it to test what you need to, it
isn't very good design.
Michael Feathers
www.objectmentor.com
Michael Feathers
06-26-2003, 07:05 AM
"Jeff Grigg" <jgrigg@mo.net> wrote Costin Cozianu <c_cozianu@hotmail.com> wrote... Actually, the programming contest is very smart, it's not at all a silly programming contest. It's a silly contest done by smart people. ;->
It is a neat contest. Years ago I thought it would be cool to have a
contest where people were locked in separate rooms with a bar of soap and a
computer containing only the DOS debug utility. Whoever walks out after a
week with the coolest program wins.
Come to think of it, if the contestants were paired off it would be a good
reality TV show :-)
Michael Feathers
www.objectmentor.com
..
David Lightstone
06-26-2003, 08:23 AM
"Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote in message
news:bdf1ah$cud$1@slb2.atl.mindspring.net... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote "Uncle Bob (Robert C. Martin)" <u.n.c.l.e.b.o.b@objectmentor.com> wrote By writing a test first, we are designing the shape of the production code that we are about to write. By definition, we are designing that shape to be testable. One of the criteria for being testable is being isolatable. We can't test something if we can't isolate it. Thus, by writing tests first we are driven to design the production code to be decoupled. In OO languages this manifests itself as simple interfaces that surround the production code. The tests implement those interfaces, supplying the services that the production code needs under control of the tests. Thus, we test GUI control code without the GUI. We test database access code without the database. We test hardware control code without the hardware. We have decoupled the system. Are not all those attributes the characteristics of "good" design? These characteristics are all achievable without TDD and may (not) even be achievable with TDD. (You can't call it a benifit if it can't be
achieved) They are achievable in theory, but hardly ever in practice. I've seen
some code in the field that I like, and would qualify as "good design" by most industry measures, but nonetheless hides too much and makes it hard to
write the tests you'd like to write as you modify it.
Everything you stated applies to TDD. The "good design" criteria to which
you refer obviously exclude testability. I would not consider it to be a
good criteria
Too often, textbook "good design" does things like make public methods non-virtual, declare classes or methods final, use mutable statics prolifically, etc. Lots of things look good if you never try to test something. Often people who attempt to do a "good design" try to use language features to make bad things impossible to do. The sad thing is that they make many good things impossible as well. You can usually
expose this sort of over-engineering by trying to compile and run classes in a separate program, a test harness. If a class can only work in the program it was designed in, and you can't extend it to test what you need to, it isn't very good design.
I suspect that you have cooked the argument a bit by using design criteria
examples that I less than "good".
No debate from me on the testability related issues. Without observables,
you can't control or debug. It would be nice if the observable was readily
at hand
Michael Feathers www.objectmentor.com
Robert Oliver
06-26-2003, 09:10 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message
news:bYBKa.5192$5J3.255@newssvr32.news.prodigy.com... My intent was to indicate the TDD does not provide code structure as a benifit. Because you can inmprove the code structure of the code
independent of TDD. (test first or otherwise)
The claim was that TDD helps. I gave you a few examples of how I think it
helps me.
In addition to other things, I wrote: Writing the test first means I actually have a test for each feature. When I write a test after the code, even if it is done quickly
afterward, I think I do a poorer job... Conduct a gadenken experiment. Write the code first, then pertend you are doing TDD. Will you still do a poor[er] job?
You may notice upon rereading what I wrote, that I was reporting on my
experience with coding first vs. testing first. I was probably not clear
that this is basically the only part of the process that changed. It was
not Big Design Up Front or Waterfall, or anything else. So consider the
experiment conducted. I think I do a better job Test First.
I noticed you changed poorer to poor in your request. I changed it back
because I think its closer to what I wanted to say.
YMMV. Do your TDD experiences lead you to conclude something else? My experiences lead me to belief that TDD is no better than anything else. Sorry, but the application development subjects me to non-disclosure of methods and practices specific to the organization
Well, I wouldn't want you to provide sensitive information or violate
agreements. I was just wondering if you have contrary TDD experience or if
your other experiences lead you to avoid trying TDD.
Regards,
Bob Oliver
David Lightstone
06-26-2003, 10:10 AM
"Robert Oliver" <oliverb@hfl.tc.faa.gov> wrote in message
news:bdf928$p24$1@faatcrl.tc.faa.gov... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message news:bYBKa.5192$5J3.255@newssvr32.news.prodigy.com... My intent was to indicate the TDD does not provide code structure as a benifit. Because you can inmprove the code structure of the code independent of TDD. (test first or otherwise) The claim was that TDD helps. I gave you a few examples of how I think it helps me.
Your claim is that TDD helps. My reply is within the context of the original
question about the BENIFITS of TDD (are there any other that the one which
can't be exhibited by the challenge). Something that helps is not a benifit.
There are simply so many things that can help. As a ludicreous example
consider eating a good meal when you are hungary and have to pump out some
code
In addition to other things, I wrote: Writing the test first means I actually have a test for each feature.
I guess this really depends upon what you mean by test each feature. I see
that you are at the FAA. When you complete the tests does the FAA flight
Certify the software upon which you are working, or do you just believe that
you have tested each feature?
When I write a test after the code, even if it is done quickly afterward, I think I do a poorer job... Conduct a gadenken experiment. Write the code first, then pertend you
are doing TDD. Will you still do a poor[er] job? You may notice upon rereading what I wrote, that I was reporting on my experience with coding first vs. testing first. I was probably not clear that this is basically the only part of the process that changed. It was not Big Design Up Front or Waterfall, or anything else. So consider the experiment conducted. I think I do a better job Test First. I noticed you changed poorer to poor in your request. I changed it back because I think its closer to what I wanted to say.
My error
YMMV. Do your TDD experiences lead you to conclude something else? My experiences lead me to belief that TDD is no better than anything
else. Sorry, but the application development subjects me to non-disclosure of methods and practices specific to the organization Well, I wouldn't want you to provide sensitive information or violate agreements. I was just wondering if you have contrary TDD experience or
if your other experiences lead you to avoid trying TDD.
I have been doing TDD in one form or another (different names for the same
strategy) since 1967. In the good old days of punch cards it was called desk
checking. (because turn around time was so poor, you had to simulate the
example test data thru the algorithms. Examples just don't pop out of thin
air).
Current work is just not subject to open discussion
Regards, Bob Oliver
Costin Cozianu
06-26-2003, 12:03 PM
> I was just wondering if you have contrary TDD experience or if your other experiences lead you to avoid trying TDD.
I would reverse that question.
Why do *you* think XP/TDD is worth a try ?
I am unconvinced if it's worth a try or not. There are lots of things we
could and sometimes we should try, but life's too short; a newbie has to
be convinced that somehow XP is special and is worth the risk of trying.
For example I might try a new formal methods approach, learn a beter
programming language, new libraries, even tinker with some experimental
kernel on my home pc, read that book on the foundations of mathematics I
was planning long time ago. Why should I try XP/TDD instead ?
See also my response to PhlIp.
Regards, Bob Oliver
Best regards,
Costin Cozianu
Michael Feathers
06-26-2003, 02:22 PM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote I have been doing TDD in one form or another (different names for the same strategy) since 1967. In the good old days of punch cards it was called
desk checking. (because turn around time was so poor, you had to simulate the example test data thru the algorithms. Examples just don't pop out of thin air).
Well, I guess you could do TDD via desk checking, but it would probably be
far slower than what you did.
Michael Feathers
www.objectmentor.com
David Lightstone
06-27-2003, 03:10 AM
"Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote in message
news:bdfrqn$ikt$1@slb5.atl.mindspring.net... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote I have been doing TDD in one form or another (different names for the
same strategy) since 1967. In the good old days of punch cards it was called desk checking. (because turn around time was so poor, you had to simulate the example test data thru the algorithms. Examples just don't pop out of
thin air). Well, I guess you could do TDD via desk checking, but it would probably be far slower than what you did.
The hedge is one form or another. Clearly there was no extensive "small"
increment cycle. Clearly there was no 30 second (do you really believe that
is possible?) compile and retest cycle. You really did have to think about
your test cases very carefully and if you were smart about it you thought
about them before you started to code.
I'm sure your will recognize the mantra
Michael Feathers www.objectmentor.com
Robert Oliver
06-27-2003, 05:26 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message
news:jGGKa.5249$rJ6.2163@newssvr32.news.prodigy.com... "Robert Oliver" <oliverb@hfl.tc.faa.gov> wrote in message news:bdf928$p24$1@faatcrl.tc.faa.gov... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in
message news:bYBKa.5192$5J3.255@newssvr32.news.prodigy.com... My intent was to indicate the TDD does not provide code structure as a benifit. Because you can inmprove the code structure of the code independent of TDD. (test first or otherwise) The claim was that TDD helps. I gave you a few examples of how I think
it helps me. Your claim is that TDD helps. My reply is within the context of the
original question about the BENIFITS of TDD (are there any other that the one which can't be exhibited by the challenge). Something that helps is not a
benifit. There are simply so many things that can help. As a ludicreous example consider eating a good meal when you are hungary and have to pump out some code
Something that helps _is_ a benifit. See:
http://dictionary.reference.com/search?q=benefit
I don't understand what you are getting at here?
<snip> In addition to other things, I wrote: > > Writing the test first means I actually have a test for each
feature. I guess this really depends upon what you mean by test each feature. I see that you are at the FAA. When you complete the tests does the FAA flight Certify the software upon which you are working, or do you just believe
that you have tested each feature?
What I meant was: when doing test first, each thing I want the code to do is
tested because I write the test first. When I defer the tests, I tend to
miss things.
The software I write is not directly used for flight or airtraffic control
hence the FAA does not "Certify" it. In the FAA the word "Certification"
has significant legal implications and it does not apply to any software I
or my team writes.
My software is used for Human Factors Experimentation. Prior to running a
live experiment, my customers run a thorough shakedown to make sure the
software meets their needs. We frequently demo features and some, but not
all, of our functional testing is automated.
<snip>
I have been doing TDD in one form or another (different names for the same strategy) since 1967. In the good old days of punch cards it was called
desk checking. (because turn around time was so poor, you had to simulate the example test data thru the algorithms. Examples just don't pop out of thin air).
Well, when you submit your cards one day and pick up the results the next,
desk checking makes a lot of sense. It's still quite different from TDD.
Regards
Bob Oliver
Robert Oliver
06-27-2003, 05:47 AM
"Costin Cozianu" <c_cozianu@hotmail.com> wrote in message
news:bdfjf7$s2cmg$2@ID-152540.news.dfncis.de... I was just wondering if you have contrary TDD experience or if your other experiences lead you to avoid trying TDD. I would reverse that question. Why do *you* think XP/TDD is worth a try?
I read the literature and thought it made sense. I tried it and liked it.
For me it was a good choice. I don't know if it would be a good choice for
you.
I am unconvinced if it's worth a try or not. There are lots of things we could and sometimes we should try, but life's too short; a newbie has to be convinced that somehow XP is special and is worth the risk of trying.
I suppose it's riskier for some than others. For me, it posed almost no
risk at all.
For example I might try a new formal methods approach, learn a beter programming language, new libraries, even tinker with some experimental kernel on my home pc, read that book on the foundations of mathematics I was planning long time ago. Why should I try XP/TDD instead?
You should do what you think will be of most benefit to you.
Regards,
Bob Oliver
David Lightstone
06-27-2003, 06:22 AM
"Robert Oliver" <oliverb@hfl.tc.faa.gov> wrote in message
news:bdhgbb$k5v$1@faatcrl.tc.faa.gov... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message news:jGGKa.5249$rJ6.2163@newssvr32.news.prodigy.com... "Robert Oliver" <oliverb@hfl.tc.faa.gov> wrote in message news:bdf928$p24$1@faatcrl.tc.faa.gov... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message news:bYBKa.5192$5J3.255@newssvr32.news.prodigy.com... > > My intent was to indicate the TDD does not provide code structure as
a > benifit. Because you can inmprove the code structure of the code independent > of TDD. (test first or otherwise) The claim was that TDD helps. I gave you a few examples of how I
think it helps me. Your claim is that TDD helps. My reply is within the context of the original question about the BENIFITS of TDD (are there any other that the one
which can't be exhibited by the challenge). Something that helps is not a benifit. There are simply so many things that can help. As a ludicreous example consider eating a good meal when you are hungary and have to pump out
some code Something that helps _is_ a benifit. See: http://dictionary.reference.com/search?q=benefit I don't understand what you are getting at here?
A dictionary definition is of course correct (I did not examine it, I take
it as an act of faith that you did). Within the context of the challenge
there is an implied cost / benifit analysis. There is also a implied
observability criteria (otherwise why claim that the challenge is not
suitable for purposes of exhibiting the benifits). Some benifits justify the
expense others simply do not. When technology is adopted . Clearly having a
good meal when you are hungary benifits a development. Rarely, however, will
an employer foot the bill.
You have indicated something helpsand consider that to be a benifit, who am
I to say you do not consider it as a benifit that serves to justify the
adoption of such an approach.
<snip> In addition to other things, I wrote: > > > > Writing the test first means I actually have a test for each feature. I guess this really depends upon what you mean by test each feature. I
see that you are at the FAA. When you complete the tests does the FAA flight Certify the software upon which you are working, or do you just believe that you have tested each feature? What I meant was: when doing test first, each thing I want the code to do
is tested because I write the test first. When I defer the tests, I tend to miss things.
What you are really stateing is that diligence is necessary when software is
developed. You in particular find that TDD imposes such diligence. That is
not disputed. That it occurs does not make it a benifit. Any disciplined
development aproach will achieve the same affect
The software I write is not directly used for flight or airtraffic control hence the FAA does not "Certify" it. In the FAA the word "Certification" has significant legal implications and it does not apply to any software I or my team writes.
Yes I know, I was just checking to see whether you were attempting to use it
on a safety critical application
My software is used for Human Factors Experimentation. Prior to running a live experiment, my customers run a thorough shakedown to make sure the software meets their needs. We frequently demo features and some, but not all, of our functional testing is automated. <snip> I have been doing TDD in one form or another (different names for the
same strategy) since 1967. In the good old days of punch cards it was called desk checking. (because turn around time was so poor, you had to simulate the example test data thru the algorithms. Examples just don't pop out of
thin air). Well, when you submit your cards one day and pick up the results the next, desk checking makes a lot of sense. It's still quite different from TDD.
The hedge is one form or another. Clearly in 1967 there were a lot of things
which were impractical. The issue of concern is careful analysis and test
data preparation. This being done in preparation for programming. No doubt
you will see that as the initial aspect of TDD.
Regards Bob Oliver
William Tanksley Google
06-27-2003, 01:41 PM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote:"Robert Oliver" <oliverb@hfl.tc.faa.gov> wrote:My intent was to indicate the TDD does not provide code structure as
abenifit. Because you can inmprove the code structure of the code
independentof TDD. (test first or otherwise)
You *can* improve the code structure independant of TDD, and you can
draw straight lines freehand. Many people find it pleasant and
convenient to do so. But that doesn't mean that straightedges don't
provide line structure, nor that TDD doesn't provide code structure.
While you're using a straightedge it's hard to get away from drawing a
straight line; when you're using TDD it's hard to get away from
writing cohesive modules which are loosely coupled.
Conduct a gadenken experiment. Write the code first, then pertend you
aredoing TDD. Will you still do a poor job?
Terrible -- the tests won't be able to access the things they need,
and there'll be bugs in primitives, and debugging will require that I
assume that the bug could be hiding /anywhere/, and normal common
sense won't serve as a reliable guide of when I can stop testing
(because I don't have any way of enumerating the tests I'll need).
I've done this before.
-Billy
William Tanksley Google
06-27-2003, 01:58 PM
Costin Cozianu <c_cozianu@hotmail.com> wrote:I was just wondering if you have contrary TDD experience or ifyour other experiences lead you to avoid trying TDD.
I would reverse that question.Why do *you* think XP/TDD is worth a try ?
Because I've tried it, and I've tried not doing it; I've studied it
and gained an understanding; I've studied the solid, tried and true
methodologies and seen how they work with it; and I've studied the
arguments against and decided they lack weight.
I am unconvinced if it's worth a try or not. There are lots of things
wecould and sometimes we should try, but life's too short; a newbie has
tobe convinced that somehow XP is special and is worth the risk of
trying.
Then why are you wasting our time posing as an expert on Usenet? If
you're not even going to put any effort into understanding TDD, your
opinion is far from special.
Simply because TDD is new doesn't mean it's a fad. I see a lot of
people adopting TDD, and I see a lot of people bashing it. Many of
both sides are just joining in on a fad. I don't really know whether
TDD will fade away; I do know that using has changed how I program,
very suddenly and with very good results.
Costin Cozianu
-Billy
Richard MacDonald
06-27-2003, 07:40 PM
phlip_cpp@yahoo.com (Phlip) wrote in news:63604d2.0306271628.52fe7f37
@posting.google.com:
You're in the wrong business :-)
David Lightstone
06-28-2003, 03:17 AM
"William Tanksley Google" <wtanksleyjr@cox.net> wrote in message
news:9576bbf1.0306271341.1025b8a1@posting.google.com... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote:"Robert Oliver" <oliverb@hfl.tc.faa.gov> wrote:My intent was to indicate the TDD does not provide code structure as abenifit. Because you can inmprove the code structure of the code independentof TDD. (test first or otherwise) You *can* improve the code structure independant of TDD, and you can draw straight lines freehand. Many people find it pleasant and convenient to do so. But that doesn't mean that straightedges don't provide line structure, nor that TDD doesn't provide code structure. While you're using a straightedge it's hard to get away from drawing a straight line; when you're using TDD it's hard to get away from writing cohesive modules which are loosely coupled.
Interesting analogy. I don't like it however, I use a CAD package when I
need to draw up a blueprint, and a table saw to cut the straight line. Now
those curved ones, they are a little more difficult aren't they.
Obtaining cohesive and loosely coupled is of course the holy grail in
software development. There is no doubt about it. I take it you wish to
imply that the holy grail of software development is a benifit of TDD. I
guess if you refactor enough you can obtain the holy grail.
Conduct a gadenken experiment. Write the code first, then pertend you aredoing TDD. Will you still do a poor job? Terrible -- the tests won't be able to access the things they need, and there'll be bugs in primitives, and debugging will require that I assume that the bug could be hiding /anywhere/, and normal common sense won't serve as a reliable guide of when I can stop testing (because I don't have any way of enumerating the tests I'll need).
You have made a few assumptions here as to the nature of the initially
produced code. Most important of which are:
(1) Poor cohesion
(2) Excessive coupling
(3) Lack of observability (so that testing is relatively painless)
To me that means the code was thrown together without much thought for
architecture and/or design (ie spagetti or macaroni type code)
So lets apply some sort of reasonibility criteria. Did you write this
proverbial code?
If you must assume the quality of the initial code which you write is that
poor, perhaps it should be rewritten/ refactored (depending upon your
prefered buzz word) before you start testing.
I've done this before. -Billy
"Phlip" <phlipcpp@yahoo.com> wrote in message
news:TjDKa.428$w91.42@newssvr31.news.prodigy.com... Uncle Bob (Robert C. Martin) wrote: checkWord(true, "dot seperated", "WidgetRoot.ChildPage"); checkWord(true, "three level", "GrandPa.FatheR.SoN"); checkWord(true, "Dot at start", ".RootPage.ChildPage");
OK, now you don't know anything about the program it is testing, and you don't know anything at all about the structure of the code. What can you tell from this test -- anyone?
Sorry but it's a lot more interesting to ask
what you *can't* tell from this test.
For example: Is a 3-level case allowed
to have a dot in front? If not, where is it
documented in the above tests? If yes,
why don't you have a test for that?
Turn it the other way: Any clue from
the above tests as to "Will the dot in
front allow more than two dots?"
Finally, but perhaps most important:
What exactly did you mean by
"dot separated" ? Perhaps there is
a definition somewhere outside the
tests?
Michael Feathers
06-29-2003, 03:41 AM
"AG" <ang@xtra.co.nz> wrote in message
news:aixLa.57558$JA5.1020367@news.xtra.co.nz... "Phlip" <phlipcpp@yahoo.com> wrote in message news:TjDKa.428$w91.42@newssvr31.news.prodigy.com... Uncle Bob (Robert C. Martin) wrote: checkWord(true, "dot seperated", "WidgetRoot.ChildPage"); checkWord(true, "three level", "GrandPa.FatheR.SoN"); checkWord(true, "Dot at start", ".RootPage.ChildPage"); OK, now you don't know anything about the program it is testing, and you don't know anything at all about the structure of the code. What can you tell from this test -- anyone? Sorry but it's a lot more interesting to ask what you *can't* tell from this test. For example: Is a 3-level case allowed to have a dot in front? If not, where is it documented in the above tests? If yes, why don't you have a test for that?
If you are really curious, you just type this in:
checkWord(true, "three level", ".GrandPa.FatheR.SoN");
Unlike traditional documents, tests are living documents. You can ask them
questions like:
checkWord(true, "three level", ".GrandPa.FatheR.SoN");
Turn it the other way: Any clue from the above tests as to "Will the dot in front allow more than two dots?"
Type: checkWord(true, "three level", "..GrandPa.FatheR.SoN");
It's funny how this works... if you have only a traditional document, like a
little writeup of a class, and it is silent on whether you can have dots at
the front, well, you get to curse the documentation writer, but that doesn't
really help you figure out the answer. If you have a set of tests, you can
find out quickly. It is a better form of documentation for existing
behavior.
Finally, but perhaps most important: What exactly did you mean by "dot separated" ? Perhaps there is a definition somewhere outside the tests?
I suspect the answer is in checkWord.
Michael Feathers
www.objectmentor.com
Hoff, Todd
06-29-2003, 01:55 PM
"Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote: It's funny how this works... if you have only a traditional document, like a little writeup of a class, and it is silent on whether you can have dots at the front, well, you get to curse the documentation writer, but that doesn't really help you figure out the answer. If you have a set of tests, you can find out quickly. It is a better form of documentation for existing behavior.
I was thinking something like a EBNF description would have been
far clearer. If your implementation was based on the same EBNF
then all the better. Trying to deduce rules from a list of examples
is extremely tedious and error prone. As the test writer who
developed the code it's highly unlikely you will select a set
of tests that builds up my mental model of the feature. Requiring
developers to look at the source implies all one needs to understand
something is the source, which makes tests an unecessary form
of documentation or specification.
--
Do a caterpillar and butterfly speak the same language?
Michael Feathers
06-29-2003, 02:56 PM
"Hoff, Todd" <todd@possibility.com> wrote in message
news:20030629175542.180$0I@newsreader.com... "Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote: It's funny how this works... if you have only a traditional document, like a little writeup of a class, and it is silent on whether you can have dots at the front, well, you get to curse the documentation writer, but that doesn't really help you figure out the answer. If you have a set of tests, you can find out quickly. It is a better form of documentation for existing behavior. I was thinking something like a EBNF description would have been far clearer. If your implementation was based on the same EBNF then all the better. Trying to deduce rules from a list of examples is extremely tedious and error prone. As the test writer who developed the code it's highly unlikely you will select a set of tests that builds up my mental model of the feature.
EBNF would be fine (this example is only an RL) but it has some pitfalls.
The main one is that you'll tend to believe the grammar. If the grammar
matches the implementation, then that is great, but how do you know?
The nice thing about doing TDD is that you build up these suites that are
powerful not just because of the tests you have in them, but also because it
is easy to add more tests to figure something out. In static languages it
is like having an "interactive top-level" like you have in Smalltalk or
Lisp. If you have some grammar or spec and you don't have the tests, then
you can hope that the implementation matches the spec well enough for what
you want to do, or pray, whatever. If you have the test rig, you can find
out for certain. Quickly.
Mental models can be helpful, but they can be a burden. How often have you
helped someone debug something and found that it was their mental model that
was in error? Often the best thing that we can do is make sure that there
is some quick way to find out what will really happen under certain
conditions. Often enough that can be scanning a set of test cases for one
that covers the behavior or writing a new one.
Requiring developers to look at the source implies all one needs to understand something is the source, which makes tests an unecessary form of documentation or specification.
Source is one view. Tests make behavior concrete because you can see the
data. Debuggers allow this too, but unfortunately all of that data goes
away when you exit.
Michael Feathers
www.objectmentor.com
Hoff, Todd
06-29-2003, 06:36 PM
"Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote: EBNF would be fine (this example is only an RL) but it has some pitfalls. The main one is that you'll tend to believe the grammar. If the grammar matches the implementation, then that is great, but how do you know?
The "how do you know" card is usually played by the static type DBCers
plus TDD like me :-) The dynamic type no-precondition TDD-is-good-enough
kind of people are usually comfortable with leaving it up to the skill
of the programmers. There is no guarantee when viewing tests that they
test anything interesting at all. There is no gurantee that the tests
are not buggy. There is not guarantee of decent coverage. To ask for
guarantees now seems an inconsistent line of argument. I would say
that my chance of being correct starting with an EBNF is near 100%.
Mental models can be helpful, but they can be a burden. How often have you helped someone debug something and found that it was their mental model that was in error?
It would be difficult to know if anything was an error without
a mental model, as our minds seem to be how we understand
things.
Often the best thing that we can do is make sure that there is some quick way to find out what will really happen under certain conditions.
Often we can do considerably better.
Often enough that can be scanning a set of test cases for one that covers the behavior or writing a new one.
Without knowing what something is supposed to do i find it difficult
to write tests. In your example, without a grammer, i have no idea
what pattern of dots would be ok. And looking at the code wouldn't
tell me that because it may have a bug. As your tests were very
incomplete, i would conclude quite wrongly that many different
patterns that aren't ok, are ok. I have no reason to suspect the
tests aren't correct and because a case is not in there, it should
be ok.
There's kind of closed system of thinking going on here. Use the tests
as the specification. If the tests aren't complete make up more tests.
How do i know what tests to make up? Look at the source code. Is the source
code ok? Look at the tests. If things get ugly say that it's better to
design code so it doesn't need X (preconditions or whatever).
--
Do a caterpillar and butterfly speak the same language?
Chris Dollin
06-29-2003, 11:40 PM
Hoff, Todd wrote:
I was thinking something like a EBNF description would have been far clearer. If your implementation was based on the same EBNF then all the better. Trying to deduce rules from a list of examples is extremely tedious and error prone.
In my experience, trying to deduce examples from a list of rules is
also error-prone. One wants both.
--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html
Michael Feathers
06-30-2003, 03:30 AM
"Hoff, Todd" <todd@possibility.com> wrote in message
news:20030629223646.769$lK@newsreader.com... "Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote: EBNF would be fine (this example is only an RL) but it has some
pitfalls. The main one is that you'll tend to believe the grammar. If the grammar matches the implementation, then that is great, but how do you know? The "how do you know" card is usually played by the static type DBCers plus TDD like me :-) The dynamic type no-precondition TDD-is-good-enough kind of people are usually comfortable with leaving it up to the skill of the programmers. There is no guarantee when viewing tests that they test anything interesting at all. There is no gurantee that the tests are not buggy. There is not guarantee of decent coverage. To ask for guarantees now seems an inconsistent line of argument. I would say that my chance of being correct starting with an EBNF is near 100%.
Nobody was arguing against using EBNF during development. We were talking
about using it as documentation.
Mental models can be helpful, but they can be a burden. How often have you helped someone debug something and found that it was their mental model that was in error? It would be difficult to know if anything was an error without a mental model, as our minds seem to be how we understand things.Often the best thing that we can do is make sure that there is some quick way to find out what will really happen under certain conditions. Often we can do considerably better.Often enough that can be scanning a set of test cases for one that covers the behavior or writing a new one. Without knowing what something is supposed to do i find it difficult to write tests. In your example, without a grammer, i have no idea what pattern of dots would be ok. And looking at the code wouldn't tell me that because it may have a bug. As your tests were very incomplete, i would conclude quite wrongly that many different patterns that aren't ok, are ok. I have no reason to suspect the tests aren't correct and because a case is not in there, it should be ok.
Figuring out what something is supposed to do is a whole other process. The
code and unit tests aren't going to tell you. Customer and acceptance tests
will. At the unit test level, if I have a question about what something
does and the tests don't answer it, I write another. If the patterns in the
tests were misleading, then someone will beef them up. It is a
self-correcting process.
There's kind of closed system of thinking going on here. Use the tests as the specification. If the tests aren't complete make up more tests. How do i know what tests to make up? Look at the source code. Is the
source code ok? Look at the tests. If things get ugly say that it's better to design code so it doesn't need X (preconditions or whatever).
I think we're looking at two different things here. I don't look at unit
tests to see what a system is "supposed to do." "Supposed to do" is
something I ask the customer about. Unit tests tell me what a class
"actually does."
Michael Feathers
www.objectmentor.com
Greg Bacon
06-30-2003, 07:38 AM
In article <20030629175542.180$0I@newsreader.com>,
Hoff, Todd <todd@possibility.com> wrote:
: [...] Trying to deduce rules from a list of examples is extremely
: tedious and error prone. [...]
Isn't this undecidable in the general case?
Greg
--
We all do no end of feeling, and we mistake it for thinking.
-- Mark Twain
William Tanksley Google
06-30-2003, 09:54 AM
todd@possibility.com (Hoff, Todd) wrote:"Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote:guarantees now seems an inconsistent line of argument. I would saythat my chance of being correct starting with an EBNF is near 100%.
Funny that my compilers class (back when) actually asked students to
turn in their EBNFs for their Oberon compilers -- by your theory, they
should have all just gotten automatic As, since they handed in EBNFs
which were therefore almost 100% certain to be correct.
Mental models can be helpful, but they can be a burden. How often
haveyou helped someone debug something and found that it was their
mentalmodel that was in error?It would be difficult to know if anything was an error withouta mental model, as our minds seem to be how we understandthings.
Mental models are hard to communicate, though. Specific examples are
easy, and can result in cognitive dissonance that tells you when
mental models aren't matching.
If you're about to use a function someone else wrote, and you look at
their tests but don't see anything that's close to your planned use,
write a new test which IS close. If it fails, you have a new use; go
ahead and try a rewrite. If you do that and their old tests fail,
you've discovered a mental model mismatch: their code was intended for
some purpose you don't realise. If they pass, you've matched mental
models.
I have no reason to suspect the tests aren't correct and because a
caseis not in there, it should be ok.
Ah, but what you CAN suspect is that because the test's not there, the
author didn't expect the pattern. So go ahead and check!
There's kind of closed system of thinking going on here. Use the
testsas the specification.
No, the user stories/use cases are the specification.
If the tests aren't complete make up more tests.
No, if you have something you need the code to do but the tests don't
cover, add a test that covers it.
How do i know what tests to make up? Look at the source code.
NO! Never. Look at the specifications (even if they're only in your
head).
Is the source code ok? Look at the tests.
This is right, though. :-)
If things get ugly say that it's better todesign code so it doesn't need X (preconditions or whatever).
Um?
-Billy
David Lightstone
06-30-2003, 11:05 AM
"William Tanksley Google" <wtanksleyjr@cox.net> wrote in message
news:9576bbf1.0306300958.2350ca80@posting.google.com... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote:"William Tanksley Google" <wtanksleyjr@cox.net> wrote:"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote:>My intent was to indicate the TDD does not provide code structure>as a benifit. Because you can inmprove the code structure of the>code independent of TDD. (test first or otherwise)You *can* improve the code structure independant of TDD, and you candraw straight lines freehand. Many people find it pleasant andconvenient to do so. But that doesn't mean that straightedges don'tprovide line structure, nor that TDD doesn't provide code structure.While you're using a straightedge it's hard to get away from drawing astraight line; when you're using TDD it's hard to get away fromwriting cohesive modules which are loosely coupled.Interesting analogy. Thank you.I don't like it however, I use a CAD package when Ineed to draw up a blueprint, and a table saw to cut the straight line. Nowthose curved ones, they are a little more difficult aren't they. I'd like to know a little more about why you bring up curved lines; I can see that you're extending my analogy, but I don't see what the extension is illustrating.
You are comparing a very simple tool (a straight edge), to one which some
claim to be sophisticated. A more appropraite comparison would be to
something more sophisticated. Something that can readily produce a curve. In
Euclidean Geometry there is no such thing as a curve line. Non-Euclidean
geometry is another story
My analogy, like all analogies, is for illustration, not proof. Also like all analogies, it can be extended, and the extension can be made to fit or not fit the illustration, at the will of the extender. Unless you care to _illustrate_, your analogy is simply another demonstration that all analogies can be stretched to the point of implausibility.
On this we agree.
Obtaining cohesive and loosely coupled is of course the holy grail insoftware development. There is no doubt about it. I take it you wish toimply that the holy grail of software development is a benifit of TDD.
Definitely not. But as you claim in your (dubious) analogy - it is hard to
avoid obtaining good coupling and cohesion
Iguess if you refactor enough you can obtain the holy grail. No, refactoring won't bring you the holy grail. But then refactoring isn't TDD -- not even close. I've done TDD without refactoring, and refactoring without TDD. Neither situation is pleasant, but the best results by far came from TDD without refactoring. But more to the point: yes, I'm stating explicitly that TDD produces cohesive and loosely coupled designs. I'm pretty sure I stated that before, but I'm doing it again now. Lest I be mistaken for a solitary wild-eyed silver-bullet espousing maniac, though (who me?), let me point out that I have some good company in making that claim: you. You claim that "much thought for architecture and/or design" can reliably result in cohesive and loosely coupled designs. How much thought is unspecified. It has to be _much_, though.
and how, pray tell, would that differ from any other approach to developing
software. How many refactoring will be needed? etc
>Conduct a gadenken experiment. Write the code first, then pertend you>are doing TDD. Will you still do a poor job?Terrible -- the tests won't be able to access the things they need,and there'll be bugs in primitives, and debugging will require that Iassume that the bug could be hiding /anywhere/, and normal commonsense won't serve as a reliable guide of when I can stop testing(because I don't have any way of enumerating the tests I'll need).You have made a few assumptions here as to the nature of the initiallyproduced code. Most important of which are: (1) Poor cohesion (2) Excessive coupling (3) Lack of observability (so that testing is relatively painless)To me that means the code was thrown together without much thought forarchitecture and/or design (ie spagetti or macaroni type code) You asked me to gedankenexperiment without TDD; you didn't specify anything else.
If you with to compare apples with sand, who am I to stop you from eating
the sand. I am simply trying to indicate that - to convince others to adopt
something (and it is all about adopting technology) that the benifit has to
be a real benifit. Not some remarketing of something that is already
available.
Okay, I'll consider the experiment modified. I've worked that way too (in fact, it's probably my most common type of TDD). So we first analyse the problem, generate requirements, design a solution, detail the design to keep observability high, implement, THEN test. Does this road map look reasonable to you?
No immediate comment
In that case, let me state the outcomes of this new experiment. Terrible -- there'll be bugs in primitives, and debugging will require that I assume that the bug could be hiding /anywhere/, and normal common sense won't serve as a reliable guide of when I can stop testing (because I don't have any way of enumerating the tests I'll need).
I take it you believe that above are consistent with appropriate cohesion
and coupling.
I'll have made a number of false starts in design that an elementary test would have revealed the uselessness of.
Does that ever not occur?
My testing will reveal some shortcomings in the observability of the design, so I'll hack in some viewports to let my tests in,
That is one way to do it
but each one will require some more conditionally compiled code, and will increase the number of different ways to build the software.
Not necessarily so, but I will go along with the assumption
How does all this differs from a need to refactor somehow?
If you must assume the quality of the initial code which you write is thatpoor, perhaps it should be rewritten/ refactored (depending upon yourprefered buzz word) before you start testing. How can I refactor code without tests? How can I assume the testability is low if I haven't written any tests?
The code transformation strategies are independent of the performance of the
testing. You know the code is bad, and being an experienced developer you
know the drill
Why, after all, did I wait this long before I started testing, when I could have written each test as soon as I saw the design point? If I'd done that, each design point would be tested already, and my design would _have_ to be observable! If my design was tested with each design point in isolation, then of course my design would be decoupled. And if each design point had only enough code implemented to merely pass its test, then each point is cohesive (although without refactoring this doesn't promise cohesion on any other scale).
-Billy
Phlip
06-30-2003, 11:35 AM
Michael Feathers wrote:
"AG" wrote:
Uncle Bob (Robert C. Martin) tested: > checkWord(true, "dot seperated", "WidgetRoot.ChildPage"); > checkWord(true, "three level", "GrandPa.FatheR.SoN"); > checkWord(true, "Dot at start", ".RootPage.ChildPage");
Finally, but perhaps most important: What exactly did you mean by "dot separated" ? Perhaps there is a definition somewhere outside the tests? I suspect the answer is in checkWord.
checkWord() isn't the testee function, it's a Test Fixture. (I'm using
the term at a smaller scale than Fit and FitNesse use it.)
Start with this, using off-the-shelf *Unit abilities (switching to
Ruby):
verified = parseWord("WidgetRoot.ChildPage")
if false == verified then
puts "WidgetRoot.ChildPage"
puts "dot separated text failed in parseWord, and returned " +
verified.to_s()
assert(false)
end
We'l need to type that more than twice, to test all kinds of words,
and whether our parser likes or dislikes them.
So we roll it into a Test Fixture, which is "behavior re-used by a
test". The parts that vary are the input string, the polarity (true or
false), and the diagnostic text element "dot separated text".
The Truth about parseWord()'s dot affinity lies within its source, in
the lower-level tests that forced its source to exist, and in these
tests. Documents may indicate these facts, but they are not the Truth.
Such document-worthy facts exist nearly anywhere. Some, on any
project, will also be in documents. But any project contains too many
small assumptions for documenting all of them to automatically be
worthwhile. No project documents every stinkin' one, and no document
will ever "read my mind and answer any question I have". Code will.
The best we should hope is those assumptions which cause friction get
more tests, more e-mails, more Wiki traffic, etc. And more diagnostic
text elements in our test fixtures.
--
Phlip
http://www.greencheese.org/SonseOne
-- Wanted: Marriage counselor who also keeps pet rats --
David Lightstone
06-30-2003, 11:45 AM
"Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote in message
news:bdq2gp$vor$1@slb9.atl.mindspring.net... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote If you with to compare apples with sand, who am I to stop you from
eating the sand. I am simply trying to indicate that - to convince others to adopt something (and it is all about adopting technology) that the benifit has to be a real benifit. Not some remarketing of something that is already available. What is that other thing? Desk checking? I remember you talking about
it, but I don't see what you see similar in it.
You have become confused, desk checking is something most people no longer
need to do (certainly I no longer even consider doing it). It was a simple
necessity of a past long forgotten. The aspect which most people seem to
have forgotten relates to the analysis needed in order to determine the test
cases which one would use. How does such an analysis differ form that upon
which TDD is based?
If you wish to state that performance of a good analysis is no longer being
done, I will not disagree. The need for a good analysis has not vanished,
and will not
Michael Feathers www.objectmentor.com
David Lightstone
07-01-2003, 03:49 AM
"Paul Campbell" <p.au.l.ca.mp.b.ell@ob.jectvi.sion.c.o.u.k> wrote in message
news:1057046572.31114.0@despina.uk.clara.net... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message
news:DqYKa.629$yK7.504@newssvr31.news.prodigy.com... tested because I write the test first. When I defer the tests, I tend
to miss things. What you are really stateing is that diligence is necessary when
software is developed. You in particular find that TDD imposes such diligence. That
is not disputed. That it occurs does not make it a benifit. Any disciplined development aproach will achieve the same affect A primary goal of any engineering process is to prefer automatic checking
or verification over a relience on human diligence - even the most diligent
individual or or group *will* have lapses.
Is this the same human that formulates the tests upon whihc TDD is
dependend?
The primary goal of enginerring process is to obtain the result. Automatic
testing is the prefered managerial strategy (eliminate the unpredictibility
of employees, eliminate them too if possible)
In this respect TDD is obviously superior with respect to functional coverage of tests since it must be 100% unless a clear and
blatant breach of the "test first" rule occurs.
So long as you restricet yourself to functional coverage and actually
achieve your claimed 100% great. I am not interested (at this time) in
discussion whether functional coverage is adequate, and by implication
whether the 100% implies superior
Paul C.
Michael Feathers
07-01-2003, 07:06 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message
news:8r0Ma.473$9o3.80@newssvr32.news.prodigy.com... "Michael Feathers" <mfeathers@objectmentorNOSPAM.com> wrote in message news:bdq2gp$vor$1@slb9.atl.mindspring.net... "David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote If you with to compare apples with sand, who am I to stop you from eating the sand. I am simply trying to indicate that - to convince others to adopt something (and it is all about adopting technology) that the benifit
has to be a real benifit. Not some remarketing of something that is already available. What is that other thing? Desk checking? I remember you talking about it, but I don't see what you see similar in it. You have become confused, desk checking is something most people no longer need to do (certainly I no longer even consider doing it). It was a simple necessity of a past long forgotten.
I was just trying to figure out what you were talking about here where you
were relating TDD and desk checking:
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote I have been doing TDD in one form or another (different names for the same strategy) since 1967. In the good old days of punch cards it was
called desk checking. (because turn around time was so poor, you had to
simulate the example test data thru the algorithms. Examples just don't pop out
of thin air).
The aspect which most people seem to have forgotten relates to the analysis needed in order to determine the
test cases which one would use. How does such an analysis differ form that upon which TDD is based?
Some of it is significantly different. Other parts are the same. Often you
are
using the tests to specify what to do next, not to figure out whether what
you've
done is right.
If you wish to state that performance of a good analysis is no longer
being done, I will not disagree. The need for a good analysis has not vanished, and will not
Well, I agree that the reasoning involved in understanding existing code
well enough to test it is an important skill. Definitely something we need
to develop in the industry.
Michael Feathers
www.objectmentor.com
Universe
07-01-2003, 08:30 AM
Michael Feathers wrote:
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote in message The aspect which most people seem to have forgotten relates to the analysis needed in order to determine the test cases which one would use. How does such an analysis differ form that upon which TDD is based?
Some of it is significantly different. Other parts are the same. Often you are using the tests to specify what to do next, not to figure out whether what you've done is right.
"Other parts are the same. Often you are using the tests to specify what
to do next, not to figure out whether what you've done is right."
Test driven design; Design intentionally "pulled away" from being, as it
should be - *led* and *driven* by analytical investigation and discovery;
A coding process that is inherently "nickel and dime", inherently
piecemeal respecting the overall analysis conceptualization and an overall
technical solution framework rooted in that overall analysis
conceptualizaion.
I.e. once again xp/oma demonstrate firm commitment to the foregoing
essential tenets of *hackery*.
If you wish to state that performance of a good analysis is no longer being done, I will not disagree. The need for a good analysis has not vanished, and will not
Hear, here!
Well, I agree that the reasoning involved in understanding existing code well enough to test it is an important skill. Definitely something we need to develop in the industry.
Huh? How does that address the core of the matter? Viz xp/oma
deprecation of an SDLC whose foundation is goal, scheduling, tradeoff and
structure "commanded" by Analysis.
Elliott
--
OO software rests upon class abstractions expressed in class method
*behaviors*. The sum of class method behaviors is the overall class
*role*. Class role should have primary responsibility for managing class
data such that the impact of class data is driven by the operation of
class methods.
~*~ Get with OO fundamentals, get OO. ~*~
-
We Don't Need US Fat Cat's Geopolitical Hegemony!
People of the World Demand US Stop Now!
-
* http:\\www.radix.net/~universe *
@Elliott 2003 my comments ~ newsgroups+bitnet OK
Universe
07-01-2003, 09:07 AM
Costin Cozianu wrote:
...up to do with what Dijkstra achieved in the 60's. And Dijkstra's recommendation run perfectly the opposite way of TDD. See his interview: http://www.cs.utexas.edu/users/EWD/video.html
I loved his concurrence with me that practicing and making a fetish of [to
paraphrase] "nickel and dime", "fly by the seat of your pants", "piecemeal
practice over holistic conceptual led" development is a peculiarly
Anglo-Saxon, especially American/British take on things.
And actually it was Djkstra - key cofounder, with others like Hoare, Gane,
Sarson, Yourdon, of the Structured paradigm - whom "Data+Algorithm" author
Alan Wirth quoted as saying that it was *ABSTRACTION* that initially
springed to mind when the word "Structured" was mentioned.
Opposed to xp/oma/SDmag/3Amigos/etc, we should Striving for, as Djkstra
says overall "quality, correctness, elegance" the *1st* time, as much as
*possible*.
Elliott
--
OO software rests upon class abstractions expressed in class method
*behaviors*. The sum of class method behaviors is the overall class
*role*. Class role should have primary responsibility for managing class
data such that the impact of class data is driven by the operation of
class methods.
~*~ Get with OO fundamentals, get OO. ~*~
-
We Don't Need US Fat Cat's Geopolitical Hegemony!
People of the World Demand US Stop Now!
-
* http:\\www.radix.net/~universe *
@Elliott 2003 my comments ~ newsgroups+bitnet OK
William Tanksley Google
07-01-2003, 11:44 AM
"David Lightstone" <david._NoSpamlightstone@prodigy.net> wrote:"William Tanksley Google" <wtanksleyjr@cox.net> wrote:
[et cetera]>>My intent was to indicate the TDD does not provide code structure>>as a benifit. Because you can inmprove the code structure of the>>code independent of TDD. (test first or otherwise)
>You *can* improve the code structure independant of TDD, and you
can>draw straight lines freehand. Many people find it pleasant and>convenient to do so. But that doesn't mean that straightedges
don't>provide line structure, nor that TDD doesn't provide code
structure.
>While you're using a straightedge it's hard to get away from
drawing>a straight line; when you're using TDD it's hard to get away from>writing cohesive modules which are loosely coupled.
You are comparing a very simple tool (a straight edge), to one which
someclaim to be sophisticated. A more appropraite comparison would be tosomething more sophisticated. Something that can readily produce a
curve. InEuclidean Geometry there is no such thing as a curve line.
Non-Euclideangeometry is another story
This is pointless quibbling. Look at the question, not the analogy:
you claim that IF there are other ways to produce good code structure,
THEN TDD can't claim good code structure as a benefit.
I point out that straight lines are a benefit of using a straightedge,
even though there are other ways of getting straight lines. In the
same way, good code structure would be a benefit of TDD regardless of
whether there were other ways of producing it.
I wonder whether you're trying to question something else about TDD,
and we're simply failing to communicate your actual questions. I'll
put some words into your mouth, but to avoid attacking a strawman I
won't answer any of them until you claim one or more of them for your
own.
1. Resolved: TDD does NOT result in (i.e. has no correlation to) good
code structure.
2. Resolved: TDD costs more than other practices which have the same
or better code structure results.
I can answer either one of these; if you've been trying to communicate
something else, please speak up.
Obtaining cohesive and loosely coupled is of course the holy grail
insoftware development. There is no doubt about it. I take it you
wishto imply that the holy grail of software development is a benifit
ofTDD.
Definitely not.
You're replying to yourself and directly disagreeing. This is
something I haven't seen often on Usenet.
But as you claim in your (dubious) analogy - it is hard toavoid obtaining good coupling and cohesion
I don't claim that; I don't make any claims about difficulty, or even
about good coupling and cohesion (except indirectly). I only claim
that a benefit is still a benefit even if there are other ways of
achieving it.
But more to the point: yes, I'm stating explicitly that TDD producescohesive and loosely coupled designs. I'm pretty sure I stated thatbefore, but I'm doing it again now. Lest I be mistaken for a
solitarywild-eyed silver-bullet espousing maniac, though (who me?), let mepoint out that I have some good company in making that claim: you.
Youclaim that "much thought for architecture and/or design" can
reliablyresult in cohesive and loosely coupled designs.
How much thought is unspecified. It has to be _much_, though.
and how, pray tell, would that differ from any other approach to
developingsoftware. How many refactoring will be needed? etc
I can't tell you how much refactoring -- but I can tell you precisely
when the refactoring stops, and I can break the refactoring into small
chunks which are directly related to actual deliverables. Up-front
"thought", on the other hand, doesn't have any concrete tie to the
deliverable; you don't know how good your thought was until the
deliverable is ready.
You have made a few assumptions here as to the nature of theinitially produced code. Most important of which are:(1) Poor cohesion(2) Excessive coupling(3) Lack of observability (so that testing is relatively painless)
To me that means the code was thrown together without much thoughtfor architecture and/or design (ie spagetti or macaroni type code)
You asked me to gedankenexperiment without TDD; you didn't specifyanything else.
If you with to compare apples with sand, who am I to stop you from
eatingthe sand.
No, I wish to compare apples with a lack of apples. If TDD gave no
benefits, then doing nothing would be as good as doing TDD.
Come on, this is FUNDAMENTAL. You can't do an experiment without a
control group!
I am simply trying to indicate that - to convince others to adoptsomething (and it is all about adopting technology) that the benifit
has tobe a real benifit. Not some remarketing of something that is alreadyavailable.
Your definition of "real benefit" should really be clarified. It seems
that you believe that nothing is beneficial if there's some other way
to gain the same result. This seems trivially false, as demonstrated
by my example of the benefits of a straightedge.
In that case, let me state the outcomes of this new experiment.
Terrible -- there'll be bugs in primitives, and debugging will
requirethat I assume that the bug could be hiding /anywhere/, and normalcommon sense won't serve as a reliable guide of when I can stoptesting (because I don't have any way of enumerating the tests I'llneed).
I take it you believe that above are consistent with appropriate
cohesionand coupling.
No, but they're consistent with untested cohesion and coupling.
Bug happen. They happen in cohesion and coupling as often, or MORE
often, than they happen in functionality (because programmers are
usually directly watching functionality, and often not really checking
cohesion and coupling thanks to at-the-time-reasonable assumptions).
I'll have made a number of false starts in design that an elementary test would have revealed the uselessness of.
Does that ever not occur?
Yes, when you've made the elementary test before you made the design,
and when you implemented the design before you went on to the next
step in design. In short, when you're doing TDD.
So you yourself have now identified something which you believe is a
good thing, and which no methodology that you know of can avoid; the
next step is to show that TDD can achieve that. If I can do that, this
debate is over.
Agreed?
My testingwill reveal some shortcomings in the observability of the design, soI'll hack in some viewports to let my tests in, but each one willrequire some more conditionally compiled code, and will increase thenumber of different ways to build the software.
How does all this differs from a need to refactor somehow?
In a sense it doesn't -- that's the brilliant thing about TDD. If you
need to refactor, do you want to discover the need while you have a
little bit of code which is all completely tested, or do you want to
discover the need after you have all the code, most of it untested?
If you must assume the quality of the initial code which you write
isthat poor, perhaps it should be rewritten/ refactored (depending
uponyour prefered buzz word) before you start testing.
How can I refactor code without tests? How can I assume thetestability is low if I haven't written any tests?
The code transformation strategies are independent of the performance
of thetesting.
Refactoring formally requires testing, to ensure that the change
doesn't disturb existing functionality. Refactoring informally is a
bad idea.
You know the code is bad, and being an experienced developer youknow the drill
Handwaving.
You only find that the code is bad by attempting to test it.
Seriously, if I *knew* it was bad I wouldn't have written it.
Why, after all, did I wait this long before I started testing, when
Icould have written each test as soon as I saw the design point? If
I'ddone that, each design point would be tested already, and my designwould _have_ to be observable! If my design was tested with eachdesign point in isolation, then of course my design would bedecoupled. And if each design point had only enough code implementedto merely pass its test, then each point is cohesive (although
withoutrefactoring this doesn't promise cohesion on any other scale).
My point, re-quoted.
-Billy
David Lightstone
07-01-2003, 05:40 PM
One adopts something new when there are preceived new ben