Home > Archive > Extreme Programming > January 2005 > Test first or test second
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Test first or test second
|
|
| Gilligan 2005-01-18, 8:59 pm |
| I am reading the latest XP explained book. (I just skimmed the first
version and never it read completely, line for line, I am reading the
new version completely).
The book says that writing the test first and then write the code, or
write the code and then write the test. I can't remember the analogy
right now (don't have the book with me) but it was something like build
a mold first or build the thing and then build a mold...
But he states that it doesn't matter which approach is used.
Write a little piece of code. Write a test for it.
Write a test. Write a little piece of code to hook to the test.
Question part of my post:
What if the test you wrote causes you to write a "bigger" piece of code
than you imagined?
If you write a little bitty piece of code (you have controlled the
size, scope, etc) and then you write a test for it to test it you have
controlled the size of the code. You do not care how big the test is,
just as long as it is the simplest thing you can write to test it. Now
you write other units and write their tests. Suppose you find that with
the new units you discover that the interface to one of the older units
is incorrect. Now you have to refactor, etc.
If you write a test first thing and then write the code you may find
that the test really needs lots of code behind it. So, you "stop"
writing the code and take your experience back to the test and create a
new test that focuses on some smaller piece. Then you write the code
for that test. Then you go back and write some more tests and some more
code. You do this until this set of logic is complete.
Can anyone say if test first code second is better than code first test
second? XP Explained doesn't seem to say.
Remember I am defining the pieces of code as extremely small and
simple. I am not saying, write a subsystem and then test it.
What is the word out there? Can you back up what you say????
Geoff
| |
| Andrew McDonagh 2005-01-18, 8:59 pm |
| Gilligan wrote:
> I am reading the latest XP explained book. (I just skimmed the first
> version and never it read completely, line for line, I am reading the
> new version completely).
>
> The book says that writing the test first and then write the code, or
> write the code and then write the test. I can't remember the analogy
> right now (don't have the book with me) but it was something like build
> a mold first or build the thing and then build a mold...
>
> But he states that it doesn't matter which approach is used.
>
> Write a little piece of code. Write a test for it.
> Write a test. Write a little piece of code to hook to the test.
>
> Question part of my post:
>
> What if the test you wrote causes you to write a "bigger" piece of code
> than you imagined?
>
> If you write a little bitty piece of code (you have controlled the
> size, scope, etc) and then you write a test for it to test it you have
> controlled the size of the code. You do not care how big the test is,
> just as long as it is the simplest thing you can write to test it. Now
> you write other units and write their tests. Suppose you find that with
> the new units you discover that the interface to one of the older units
> is incorrect. Now you have to refactor, etc.
>
> If you write a test first thing and then write the code you may find
> that the test really needs lots of code behind it. So, you "stop"
> writing the code and take your experience back to the test and create a
> new test that focuses on some smaller piece. Then you write the code
> for that test. Then you go back and write some more tests and some more
> code. You do this until this set of logic is complete.
>
>
> Can anyone say if test first code second is better than code first test
> second? XP Explained doesn't seem to say.
>
> Remember I am defining the pieces of code as extremely small and
> simple. I am not saying, write a subsystem and then test it.
> What is the word out there? Can you back up what you say????
>
> Geoff
>
The major benefit I have found in test first, code second, is that the
resulting code is always testable. It has to be testable, because we
wrote the test first. However, when ever I've written production code
first, I find it much harder to apply a test to it, simply because I
haven't written the code to be tested, but only to do it job.
| |
| Ron Jeffries 2005-01-19, 3:57 am |
| On 18 Jan 2005 11:49:37 -0800, "Gilligan" <geoffrey.slinker@gmail.com>
wrote:
>But he states that it doesn't matter which approach is used.
If he says that, then in my opinion, he's not as right as he might be.
It almost certainly matters, because most everything matters. Where
does he say that?
>Question part of my post:
>
>What if the test you wrote causes you to write a "bigger" piece of code
>than you imagined?
Then I back it out and write a different test. See, for example, my
adventures in C# articles and book for cases where I did just that.
>
>If you write a little bitty piece of code (you have controlled the
>size, scope, etc) and then you write a test for it to test it you have
>controlled the size of the code. You do not care how big the test is,
>just as long as it is the simplest thing you can write to test it. Now
>you write other units and write their tests. Suppose you find that with
>the new units you discover that the interface to one of the older units
>is incorrect. Now you have to refactor, etc.
Well, I do care how big the test is, because the bigger it is the less
likely I am to write it, and the less likely it is to be complete.
It is rare to write a little code that needs a lot of test. When that
happens, my bet would be that solving the same problem test-first
would result in code that doesn't need all that testing.
Many programmers find it difficult to stop coding and test. The code
is done; they feel confident in it; they give testing short shrift. I
myself am one of those programmers. When I do test-first, I don't get
that same impatience.
>
>If you write a test first thing and then write the code you may find
>that the test really needs lots of code behind it. So, you "stop"
>writing the code and take your experience back to the test and create a
>new test that focuses on some smaller piece. Then you write the code
>for that test. Then you go back and write some more tests and some more
>code. You do this until this set of logic is complete.
Right.
>
>Can anyone say if test first code second is better than code first test
>second? XP Explained doesn't seem to say.
I generally prefer Test-First. I would have imagined that Beck would
as well, since he wrote an entire book about it. Highly recommended,
by the way, and work through the examples would be my advice.
>
>Remember I am defining the pieces of code as extremely small and
>simple. I am not saying, write a subsystem and then test it.
>What is the word out there? Can you back up what you say????
I've tried it both ways and prefer TDD when I can see how to do it. I
don't know what would be best for you but the positive experience of
lots of people with TDD suggests to me that you might want to consider
trying it and deciding for yourself.
--
Ron Jeffries
www.XProgramming.com
I'm giving the best advice I have. You get to decide if it's true for you.
| |
| Gilligan 2005-01-19, 4:20 pm |
| Page 101, 4th paragraph:
"DCI (Defect Cost Increase) tells us to put testing near coding, but it
doesn't say exactly when to test. Testing after implementation has the
advantage that it makes sense. After all, you can't check the
tolerances of a physical part you haven't yet made. This is where the
physical metaphor behind the word "testing" is misleading. Because
software is a virtual world, "testing" before or after makes equal
sense. You can write code to fit a mold or a mold to fit the code. You
can do whichever creates the most benefit. In the end you put the two
together and see if the match (Figure 17)."
"Code and tests can be written in either order. In XP, when possible,
tests are written in advance of implementation."
He continues telling the advantage of testing first helps with
interfaces (and that is obviously a key to software design,
interfaces...). Write tests for everything you can imagine will break.
"Tests can provide a measure of progress. If I have ten tests broken
and I fix one, the I've made progress. That said, I try to have only
one broken test at a time. If I am programming test-first, I write one
failyt test, make it work, and then write the next failing test."
He says that if the assumptions of his tests prove wrong , "I have to
modify them all when the assumptions turn out to be wrong. System-level
tests give me a sense of certainty that the whole system is working at
the end of the w ".
It is clear he says XP uses test first when possible. But the test,
code, test, code,... cycle is the same as code, test, code, test,
code... cycle after the first step.
Figure 17 is titled "Code and test in either order" Page 102.
That is what the book says, how do you take it?
| |
| Chris Dollin 2005-01-19, 4:20 pm |
| Gilligan wrote:
> It is clear he says XP uses test first when possible. But the test,
> code, test, code,... cycle is the same as code, test, code, test,
> code... cycle after the first step.
No, it isn't, because there's some "thing" - a feature, a piece of
behaviour - being coded and being tested, and the two cycles are
code(X), test(X), code(Y), test(Y) ...
vs
test(X), code(X), test(Y), code(Y) ...
and you can't make those match by sliding one along the other.
--
Chris "electric hedgehog" Dollin
| |
|
| Gilligan wrote:
> Figure 17 is titled "Code and test in either order" Page 102.
> That is what the book says, how do you take it?
Haven't read the book yet. I "take" it by applying my own experience.
If you want to code a hard math formula, you might use a dummy assertion,
code the formula, check its output, and slip that into the assertion. The
goal of TDD is relentlessly predicting the result, but if the result comes
from a big hard math formula screw it. Let the code tell you what to test,
and you will get a clean interface and safety for refactors anyway.
Conclusion: Test test test, and test-first whenever possible. Because TF is
both easier and more useful, writing a book and saying "test last
occassionally" is mostly harmless.
--
Phlip
http://industrialxp.org/community/b...tUserInterfaces
| |
| Duncan Booth 2005-01-19, 4:20 pm |
| Chris Dollin wrote:
> Gilligan wrote:
>
>
> No, it isn't, because there's some "thing" - a feature, a piece of
> behaviour - being coded and being tested, and the two cycles are
>
> code(X), test(X), code(Y), test(Y) ...
> vs
> test(X), code(X), test(Y), code(Y) ...
>
> and you can't make those match by sliding one along the other.
I would have said the actual cycle is nearer:
test(x), code(x), test(x), test(y), code(y), test(y), ...
since all the tests have to fail and then pass.
| |
| Gilligan 2005-01-19, 4:20 pm |
| I see it like this:
test(x), code(x), test(x), code(x) where X is a class or unit or piece
of code until that set/family/class of code is complete.
so it can be:
test(x), code(x), test(x), code(x) or
code(x), test(x), code(x), test(x)
| |
| John Roth 2005-01-19, 4:20 pm |
|
"Gilligan" <geoffrey.slinker@gmail.com> wrote in message
news:1106144557.237254.110370@f14g2000cwb.googlegroups.com...
> Page 101, 4th paragraph:
>
> "DCI (Defect Cost Increase) tells us to put testing near coding, but it
> doesn't say exactly when to test. Testing after implementation has the
> advantage that it makes sense. After all, you can't check the
> tolerances of a physical part you haven't yet made. This is where the
> physical metaphor behind the word "testing" is misleading. Because
> software is a virtual world, "testing" before or after makes equal
> sense. You can write code to fit a mold or a mold to fit the code. You
> can do whichever creates the most benefit. In the end you put the two
> together and see if the match (Figure 17)."
--------- NOTE --------
>
> "Code and tests can be written in either order. In XP, when possible,
> tests are written in advance of implementation."
-------- NOTE ---------
He says, explicitly, "In XP, when possible, tests are written in
advance of implementation." That's "when possible," not
"when convenient," or "at the implementor's whim."
-------------- End NOTE ----------------------------
>
> He continues telling the advantage of testing first helps with
> interfaces (and that is obviously a key to software design,
> interfaces...). Write tests for everything you can imagine will break.
>
> "Tests can provide a measure of progress. If I have ten tests broken
> and I fix one, the I've made progress. That said, I try to have only
> one broken test at a time. If I am programming test-first, I write one
> failyt test, make it work, and then write the next failing test."
>
> He says that if the assumptions of his tests prove wrong , "I have to
> modify them all when the assumptions turn out to be wrong. System-level
> tests give me a sense of certainty that the whole system is working at
> the end of the w ".
>
> It is clear he says XP uses test first when possible. But the test,
> code, test, code,... cycle is the same as code, test, code, test,
> code... cycle after the first step.
No, it isn't. It may look the same, but the implied bracketing is
different. (test, code), (test, code), (test, code) is
very different from (code, test), (code, test), (code, test)...
> Figure 17 is titled "Code and test in either order" Page 102.
> That is what the book says, how do you take it?
See the bracked section above.
John Roth
>
| |
| Gilligan 2005-01-19, 4:20 pm |
| I see it like this:
test(x), code(x), test(x), code(x) where X is a class or unit or piece
of code until that set/family/class of code is complete.
so it can be:
test(x), code(x), test(x), code(x) or
code(x), test(x), code(x), test(x)
| |
| Ron Jeffries 2005-01-20, 3:58 am |
| On 19 Jan 2005 09:48:07 -0800, "Gilligan" <geoffrey.slinker@gmail.com>
wrote:
>I see it like this:
>
>test(x), code(x), test(x), code(x) where X is a class or unit or piece
>of code until that set/family/class of code is complete.
>
>so it can be:
>test(x), code(x), test(x), code(x) or
>code(x), test(x), code(x), test(x)
You may see it that way, but it isn't that way.
In TDD a given test drives the creation of one or more lines of code,
then that test runs. Then you write a new test. So it isn't test(x)
again and again, it's test(x), test(y).
I'm wondering: Have you tried TDD yet?
--
Ron Jeffries
www.XProgramming.com
I'm giving the best advice I have. You get to decide if it's true for you.
| |
| Chris Dollin 2005-01-20, 8:56 am |
| Gilligan wrote:
> I see it like this:
>
> test(x), code(x), test(x), code(x) where X is a class or unit or piece
> of code until that set/family/class of code is complete.
Well, I believe that's a fixable mistake. If your x is a smudgy mess of
stuff from something big, your tests will end up just as smudgy.
--
Chris "electric hedgehog" Dollin
| |
| Gilligan 2005-01-20, 3:58 pm |
| I am trying it now. And I keep writing a little code first and then the
tests. The tests have shown problems of two kinds, mistakes in logic,
and difficult interfaces. I make the appropriate changes, refactor the
tests, and run again. I find I have to have a little piece of code
first to capture something, the idea, the thought... something.
I may be a special case. I mentioned in another ng that I am slightly
dyslexic. Also, I have stacks of scap paper always near by so that I
write down thoughts and ideas, if I don't, they seem to be gone
forever. Maybe it is my way of coping. Maybe I am not trying hard
enough.
So, back to how I am doing it. I am currently working on a framework.
As with frameworks, I am trying to give a common way of doing data
access to our team. I have grouped my ideas by what I feel are similar
to Parnas families. I have created static UML designs and also
developed the layout of the system in source control and how the
assemblies and namespaces will be.
I have started my iterations (one man band) in which the entire
framework will be finished in this release cycle. Coded my interfaces
and abstract base classes necessary for the simpliest beginnings. Wrote
tests for this. Fixed bugs, errors, mistakes, and refactored tests and
code until it felt right. Then I added some more to the framework that
is for more complex situation. (Basically applying patterns such as
strategies and factories). Wrote tests, and iterated until it felt
right. Then the most complex implementation I could image. Wrote tests,
iterated, etc.
Then I delivered the framework to the team and they started using it.
As they discovered issues with the framework I have made changes and
updated the tests, etc. The tests have become part of the tutorial on
how to use the framework as well. Some people look at the UML and say,
I got it. Others step through the code. Others start by making their
own "tests" or experiments, etc.
So, I am not using TDD correctly I guess. I am trying to think of the
test first but continually find them lacking or even draw a complete
blank. Is it my "wiring" that makes me do this or lack of experience or
lack of having someone here to lean on that is an expert.... I don't
know.
You say the test drives the creation of one or more lines of code. I
understand, but it does more than that. You have to put those lines of
code "in" something. Therefore you have thought of a class (if you are
object oriented) or a library or something in which the lines of code
go. Whether you coded a little or you imagined it all in your head you
still have done a lot more than write a few lines of code to meet that
first test. Haven't you?
Geoff
| |
| Robert C. Martin 2005-01-21, 3:59 am |
| On 20 Jan 2005 08:37:31 -0800, "Gilligan" <geoffrey.slinker@gmail.com>
wrote:
>I am trying it now. And I keep writing a little code first and then the
>tests.
Stop doing that. Start writing a little test first, and then the
code.
>So, I am not using TDD correctly I guess. I am trying to think of the
>test first but continually find them lacking or even draw a complete
>blank.
Perhaps you are thinking on too large a scale. Think very very small.
>You say the test drives the creation of one or more lines of code. I
>understand, but it does more than that. You have to put those lines of
>code "in" something. Therefore you have thought of a class (if you are
>object oriented) or a library or something in which the lines of code
>go. Whether you coded a little or you imagined it all in your head you
>still have done a lot more than write a few lines of code to meet that
>first test. Haven't you?
No. When you first make the test pass, you may do so by writing code
that you *know* you will throw away. You know you'll have to make an
object to hold the real code, but you don't write that object at
first. You must make the test pass in some very simple way that you
know you will change later. That's OK. It's a small bit of code, and
it will prove that your tests work.
The next test you write may force you to add the object. Or maybe the
test after. Maybe.
-----
Robert C. Martin (Uncle Bob) | email: unclebob@objectmentor.com
Object Mentor Inc. | blog: www.butunclebob.com
The Agile Transition Experts | web: www.objectmentor.com
800-338-6716
"The aim of science is not to open the door to infinite wisdom,
but to set a limit to infinite error."
-- Bertolt Brecht, Life of Galileo
| |
| Shane Mingins 2005-01-21, 4:00 am |
| "Robert C. Martin" <unclebob@objectmentor.com> wrote in message
> No. When you first make the test pass, you may do so by writing code
> that you *know* you will throw away. You know you'll have to make an
> object to hold the real code, but you don't write that object at
> first. You must make the test pass in some very simple way that you
> know you will change later. That's OK. It's a small bit of code, and
> it will prove that your tests work.
>
Something that I seem to do a bit is introduce a method on the TestCase to
make the assertion pass ... eventually this method moves to an object or a
new object is created. But it means that I can move forward with the task
at hand and not spend too much time thinking about something that I may not
quite know yet.
Shane
"I could be wrong. I could be right." -- Rise by PIL
| |
| Ron Jeffries 2005-01-21, 4:00 am |
| On 20 Jan 2005 08:37:31 -0800, "Gilligan" <geoffrey.slinker@gmail.com>
wrote:
>You say the test drives the creation of one or more lines of code. I
>understand, but it does more than that. You have to put those lines of
>code "in" something. Therefore you have thought of a class (if you are
>object oriented) or a library or something in which the lines of code
>go. Whether you coded a little or you imagined it all in your head you
>still have done a lot more than write a few lines of code to meet that
>first test. Haven't you?
I'm allowed to think all I want to. But have you worked the examples
in Kent's book, or on my site? I rarely need even ten lines of code to
make a test work.
--
Ron Jeffries
www.XProgramming.com
I'm giving the best advice I have. You get to decide if it's true for you.
| |
| Gilligan 2005-01-21, 3:57 pm |
| I can not find the "examples" on your site. I will continue to browse
your site and will check back here for directions!
Some details of my current effort:
Internal framework for some components in our DAL.
Customer is my other team members.
User stories are done with XML because we all speak the language.
The static UML consists of the interfaces and abstract classes. I do
not fully express the "ideas" in UML by specifying all of the
properties, methods, etc, and I do not generate code, so I use it
lightly is what I am saying.
Some modified "swim" lanes are quickly drawn on a white board to
capture ideas on interfaces and it is very light.
Then I sliced up the parts (the release easy enough to develop that
three one w iterations makes the entire thing), and went to work.
My tests became examples. Frameworks beg for examples.
One engineer is using the framework and has brought to light that there
are some "missing" base classes that would help us have code in one and
only one place. We have added those (I think three classes) and removed
duplicate code and things are settling down very nice.
Geoff
|
|
|
|
|