![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Is Test-driven design really any better or worse than programming by
contract? What are the benefits of it? It seems TDD is just "separate your
code into functional-and-thus-testable pieces and mock up the parts you
can't specify", which would seem perfect for programming by contract.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 3/1/2009 4:18 PM, Darren New wrote:
> Is Test-driven design really any better or worse than programming by
> contract? What are the benefits of it? It seems TDD is just "separate
> your code into functional-and-thus-testable pieces and mock up the parts
> you can't specify", which would seem perfect for programming by contract.
>
I wasn't aware that the two were mutually exclusive.
Programming by contract creates the specification for your code.
TDD ensures that your code meets that specification.
Or am I missing something?
--
...Chambers
www.pacificwebguy.com
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Chambers wrote:
> I wasn't aware that the two were mutually exclusive.
In some sense, I think.
> Programming by contract creates the specification for your code.
Sort of, yes. More precisely, it formalizes the unit level of semantics of
what your code is expected to do.
> TDD ensures that your code meets that specification.
Not TDD. TDD is "the test is the specification." If it passes the test, you
don't change anything, and if it doesn't, it's broken by definition.
If your compiler could check your PbC was upheld by the implementation,
would you need a test? If your test code tests something (and expects
success) from something the PbC says should fail, which is right?
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Personally, I prefer PbC, as it minimizes side-effects.
With TDD, the whole point of programming is to get it to pass the tests.
When I first read about it, they even gave this example (pseudocode):
Test:
add(3,5)=8
add(a,b)
return 8
It passes the test, so TDD assumes that the function is correct. This,
to me, is wrong. Obviously, you wouldn't use one single test to verify
the function of your code, you would use multiples, but the point
remains that with TDD your whole purpose is to "game the system." As
long is it passes the test, then it's correct.
PbC is much more flexible in that you're free to look at something and
say, "That's not right."
--
...Chambers
www.pacificwebguy.com
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Chambers wrote:
> It passes the test, so TDD assumes that the function is correct. This,
> to me, is wrong.
This is kind of what inspired the question to start with:
http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Not TDD. TDD is "the test is the specification." If it passes the test, you
> don't change anything, and if it doesn't, it's broken by definition.
To me, that seems like a *very* stupid way to design your code.
I'm really a fan of PbC; when I need to implement some rather complex unit, I
seem to be automatically going for this approach - and it leads me to very
robust interfaces, because in addition to how each side *must* or *may* behave,
I start thinking separately about how the other side may actually *expect* it to
behave. Thus, between one side's obligations and the other side's expectations I
get some room for maneuver for later changes or fault-tolerance.
I have found that in complex systems, it's all about well-defined interfaces. If
your interfaces are poor, the best unit implementations will get you nowhere.
You will get all kinds of poorly understood errors, because of race conditions
or deadlocks between units, or other such crap, often being sporadic and
timing-dependent, and therefore both hard to notice in the first place, and
hard to hunt down.
Yeah, module testing is a good thing, but specifying interfaces by virtue of
test cases... yuck!
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 3/1/2009 7:38 PM, Darren New wrote:
> This is kind of what inspired the question to start with:
>
>
http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/
Interesting... this kind of goes along with the fact that many
programmers tend to add features not needed, on the assumption that they
may, one day, be needed. Coding for future problems, rather than the
one at hand :)
I read a blog post from someone (can't remember who at the moment) who
stringently told his programmers to always specific code, even if they
were certain that a general case method would be useful later on. 90%
of the time, they never ended up using the general case methods.
Instead, he said they could write a simplified general case after they
already used the same functionality in two separate projects. Once they
used it in three separate projects, then they were allowed to do a full
design cycle on it and add it to the company's other libraries.
--
...Chambers
www.pacificwebguy.com
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
"clipka" <nomail@nomail> wrote:
> I have found that in complex systems, it's all about well-defined interfaces. If
> your interfaces are poor, the best unit implementations will get you nowhere.
> You will get all kinds of poorly understood errors, because of race conditions
> or deadlocks between units, or other such crap, often being sporadic and
> timing-dependent, and therefore both hard to notice in the first place, and
> hard to hunt down.
Oh, and worst of all: Once you find and identify one of those bugs, each
module's developer will insist that *his* module is perfectly ok, and that it
is the other modules that need to be fixed. Yay!
And once you implement a workaround, chances are you break something else...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Chambers wrote:
> > It passes the test, so TDD assumes that the function is correct. This,
> > to me, is wrong.
>
> This is kind of what inspired the question to start with:
>
>
http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/
There is one big flaw in the message the exercise seems to try to convey: In
reality, starting from a simple testcase may *not* necessarily lead you
automatically to an implementation suitable for future testcases to come.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka wrote:
> There is one big flaw in the message the exercise seems to try to convey: In
> reality, starting from a simple testcase may *not* necessarily lead you
> automatically to an implementation suitable for future testcases to come.
Yes. It also assumes you know what the simple testcase is supposed to be.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |