Collective Wisdom from the Experts 163
That the result length is the same as the input length comes out in the wash
and doesn’t need restating.
Even stating the postcondition in the way described is not enough to give you a
good test. A good test should be readable. It should be comprehensible and simple
enough that you can see readily that it is correct (or not). Unless you already have
code lying around for checking that a sequence is sorted and that one sequence
contains a permutation of values in another, it is quite likely that the test code will
be more complex than the code under test. As Tony Hoare observed:
There are two ways of constructing a software design: one way is to make it so
simple that there are obviously no deficiencies and the other is to make it so com-
plicated that there are no obvious deficiencies.
Using concrete examples eliminates this accidental complexity and opportu-
nity for accident. For example, given the following sequence:
3 1 4 1 5 9
The result of sorting is the following:
1 1 3 4 5 9
No other answer will do. Accept no substitutes.
Concrete examples help to illustrate general behavior in an accessible and
unambiguous way. The result of adding an item to an empty collection is not
simply that it is not empty: it is that the collection now has a single item, and that
the single item held is the item added. Two or more items would qualify as not
empty, and would also be wrong. A single item of a different value would also be
wrong. The result of adding a row to a table is not simply that the table is one row
bigger; it’s also that the row’s key can be used to recover the row added. And so on.
In specifying behavior, tests should not simply be accurate: they must also be precise.