This is what I (NatPryce) do instead of CodeUnitTestFirst when I use a language that supports DesignByContract, such as the EiffelLanguage.
In languages without DesignByContract, XP uses a UnitTest to both specify the expected behaviour of a class (its contract) and test the implementation of the contract. Languages with DesignByContract separate the declarative specification of the contract from the test code that verifies its implementation (SeparationOfConcerns).
We want samples, please. In Eiffel. ;)
Ok, how about the usual Stack example. For readers who do not know Eiffel syntax:
class STACK [T] -- A stack. We won't follow strict query/command separation -- to help Java programmers understand what's going on :-) creation make feature {ANY} -- Queries is_empty : BOOLEAN is -- Is the stack empty? deferred ensure is_empty = (count = 0) end count : INTEGER is -- How many items are in the stack? deferred ensure Result >= 0 end top : T is -- Returns the top of the stack require not is_empty deferred ensure top = item(1) end item( n : INTEGER ) : T is -- Peek at items lower down the stack. Items are indexed from 1 -- with lower indices being nearer the top of the stack. (That's -- the way Eiffel does it; sorry Java and C fans!) require not is_empty n >= 1 and n <= count deferred end feature {ANY} -- Commands push( new_item : T ) is -- Pushes a new object onto the top of the stack deferred ensure not is_empty count = old count + 1 top = new_item count > 1 implies item(2) = old top end pop : T is -- Pops the top off the stack require not is_empty deferred ensure Result = old top count = old count - 1 old count > 1 implies top = old item(2) end make is -- Makes an empty stack deferred ensure is_empty end endSecond, the tests... Phew I'm tired after that. Anyone want to write an EiffelUnit test?
Third, replace those deferred features with implementations. I'll leave that as an exercise to the reader.
--NatPryce
I have discovered, while using this technique, that EiffelUnit does not really act in the way I would like. I think it's too close a copy of JavaUnit. When contracts are separated from the test driver, there is less need for assert statements because the postconditions and invariants already express those assertions. However tests need to document how they are exercising the contract and this information should be collected by the testing framework. When errors are reported, I want to see "test X, line Y, violated precondition of O: predicate P was false", or something like that
--NatPryce
We used to do a variant of this in Smalltalk, and I still do something like it in Java. First I create the "stub" class that gives only the external interfaces -- no implementation. Then I code the UnitTest. Then I run the UnitTest and fill in the stubs...