On Oct 24, 2007, at 3:26 PM, Rick DeNatale wrote:
> 1) I'm not sure what you mean by the second type of test suite.  I
> don't think you're talking about putting test assertions into the
> code.  If you're not I'm not sure I see the real distinction

I interpreted the two types of testing as follows.

Assume you have a method that expects a single non-negative integer
argument.  You'll probably want to test that it behaves correctly
for the following:
	foo(0)          # edge case
	foo(1)          # typical call
	foo(36)         # random case from all values
	foo(100000000)  # large magnitude
         foo(1023)       # testing near powers of two
         foo(1024)
         foo(1025)

These tests will be designed to make sure that foo works correctly
on *expected* input.

Then there is the question about whether you should test:
	foo(-1)
	foo(nil)
	foo("bogus")
	foo("too", "many", :arguments)
	foo()

and so on.  These tests are throwing *unexpected* input at the
method.  Bertrand Meyer in his writings about design by contract
programming would say that foo isn't obligated to do anything at
all when called with arguments that are outside its 'contract'.
If foo blows up on that input it isn't the failure of 'foo' but
instead is the failure of the caller to adhere to the contract.

So the philosophical question is should you extend foo's contract
to say that it will raise a particular exception (ArgumentError),
add the code to foo, and keep the tests or instead should you
decide that the tests are superfluous and instead focus on
better tests for the code that eventually calls foo (i.e. make
sure your code never calls foo incorrectly).

Gary Wright