[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-hackers] Re: [Chicken-users] Integrating unit tests into so
Re: [Chicken-hackers] Re: [Chicken-users] Integrating unit tests into source code
Thu, 14 Dec 2006 14:05:08 +0100
On Thu, Dec 14, 2006 at 04:45:11AM -0800, Brandon J. Van Every wrote:
> Some tests need additional code for support (setting
> things up in a particular way etc). Why would one want to put all that
> code (which may be twice as big as the code itself, or even bigger, if done
> properly) in one huge file?
> You do it if you want your code to actually work, and you think it's
> better to run the automated tests than to pay someone $XX/hour
> after-the-fact to show you your bugs.
I know and understand why to use tests. I'm not opposed to tests,
but I am opposed to lumping the tests in with the main code.
I'd much rather just keep the code clean and put the tests in
The nature of tests is so different from main code that the two should
not be mixed together. Anyway, what's the use of tests in the main file?
If it's just to have a couple of examples as documentation on how to use
the function, you're probably not interested in hundreds of tests of
a function. One clear example in the comments ought to be enough to
understand what the function is supposed to do, with the exhaustive
tests in a separate file.
Tests don't aid the reader in any way, they probably hinder readability
of code. I happen to consider readability of code one of Scheme's
major benefits, but cluttering code with tests removes this benefit IMHO.
Inline documentation is useful to the reader, and so are contracts since
they describe the specification a function should adhere to. Tests
don't say shit. They're a very low-level and nonsemantic way of
groping around to ensure your corner cases are covered. Contracts
are more semantic and declarative, so they tell you more about
what type of input is expected.
What would you prefer?
(define/contract (+ a b)
(if (= 0 a) b (+ (sub1 a) (add1 b))))
(define/test (+ a b)
((throws negativeerror (+ -1 1))
(throws negativeerror (+ 1 -1))
(= 1 (+ 0 1))
(= 1 (+ 1 0))
(= 2 (+ 1 1))
(= 0 (+ 0 0))
(if (= 0 a) b (+ (sub1 a) (add1 b)))))
As you can see, proper testing often results in bigger code.
Of course, the tests defined in the last example should be duplicated
in another file in the case of contract usage. Then you'd check the
contracts are enforced and that stuff accepted by the contracts
is indeed correctly returned.
Contracts also catche problems in the calling code instead of just
testing functions in isolation.
"The process of preparing programs for a digital computer
is especially attractive, not only because it can be economically
and scientifically rewarding, but also because it can be an aesthetic
experience much like composing poetry or music."
-- Donald Knuth
Description: PGP signature