Quiche.ss is a Scheme unit testing framework. Like most similar
frameworks,
it allows for declaration of tests with fixed inputs, e.g.:
(test 'rounding1 (inexact->exact (round 4.7)) 5)
However, it goes beyond that. Similar to Haskell's QuickCheck and
Clojure's
Fact, you can declare properties on any Scheme expressions:
(property 'add-commutes
((x randint)
(y randint))
(= (+ x y) (+ y x)))
A property is converted to a normal test; the random variable
declarations, together with the expression to be tested, are converted
to a list comprehension. The expression is tested on the cartesian
product of input values, and the test passes only if the expression
holds for all tested values.
This framework currently requires Chez Scheme; however, the only
Chez-specific parts are test-w-engine.ss and test-no-engine.ss. It can
be ported to any Scheme implementation that allows the error handler
to be parameterized.
Regards,
--
Michel Salim
"Michel S." <michel...@gmail.com> writes:
> Tarball: http://git.hircus.info/quiche-ss.tar
> Git repository: http://git.hircus.info/quiche-ss.git (read-only)
[...]
> However, it goes beyond that. Similar to Haskell's QuickCheck and
> Clojure's
> Fact, you can declare properties on any Scheme expressions:
How does it compare to FastCheck,
http://planet.plt-scheme.org/display.ss?package=fasttest.plt&owner=cce?
Thanks,
Ludovic.
FastCheck:
(test/text-ui
(test-random
([x (random-integer)]
[y (random-integer)])
(check-pred integer? (+ x y))))
Quiche:
(run-tests (list (property int-add ([x rand-int] [y rand-int])
(integer? (+ x y)))))
cce seems to take a different design choice than mine in one place:
the expression after test-random expands to a let-expression, in this
case
(let ([x (random-integer)]
[y (random-integer)])
(check-pred integer? (+ x y)))
that is run multiple times, whereas in my case, since I'm retrofitting
to an existing test framework, the expansion is to a single test:
(doseq ([x (make N rand-int)]
[y (make N rand-int)])
(unless (integer? (+ x y))
(error ...)))
note: doseq is similar to Haskell's for-comprehension, but is used for
effects (cf. map and for-each); it is a straight reimplementation of
Clojure's
Quiche catches errors (the error-handler part is the only non-portable
piece of code), and so it is natural to throw an error the first time
a random test fails. I'm omitting, for brevity, the error-formatting
code.
The current code only has generators for integers, characters, lists
(the list generator is parameterized by an element generator) and
strings, but it is trivially extensible. I might backport the property
form back to Clojure, which already has a deterministic test framework
(clojure.contrib.test_is)
Regards,
--
Michel S.