The test is the core type in SchemeUnit. A test is either a test case, which is a single action to test, or a test suite, which is a collection of tests.
test | = | test-case | test-suite |
test-case | = | name × action |
test-suite | = | name × tests |
tests | = | listof test
|
An assertion is a predicate that checks a condition. The
assertion fails if it's condition is false. Otherwise it succeeds.
In SchemeUnit assertions fail by raising an exception of type
exn:test:assertion
. Otherwise they return #t
.
A test-case action is a function of no arguments. A test-case succeeds if the action evaluates without raising an exception. Test-case failures are divided into two cases: those thrown as the result of an assertion failure, which we call failures and those thrown due to other reasons, which we call errors. We define a type test-result to encapsulate these concepts:
test-result | = | test-failure | test-error | test-success |
test-failure | = | test-case × failure-exn |
test-error | = | test-case × error-exn |
test-success | = | test-case × result |
The function run-test-action
takes a name and
action from a test-case and returns the
test-result of running the action.
(run-test-action String (() -> #t)) | => | test-result |
If is unusual to use the run-test-action
function directly.
SchemeUnit provides fold-test
and fold-test-results
functions that encapsulate common patterns of traversing
tests.
(fold-test suite-fn case-fn cons-fn seed test) | ||
(fold-test ((String 'a) -> 'a) ((String 'a) -> 'a) (('a 'a) -> 'a) 'a test) | => | 'a |
(fold-test-results suite-fn case-fn cons-fn seed test) | ||
(fold-test-results ((String 'a) -> 'a) (test-result -> 'a) (('a 'a) -> 'a) 'a test) | => | 'a |
SchemeUnit provides macros for constructing test-cases and test-suites.
(make-test-case name action) (make-test-case name action teardown) (make-test-case name action setup teardown)
The make-test-case
macro has three forms to construct a
test-case. The name
is a string that is reported if
the test-case fails. The action
in an expression that
is evaluated to determine test success or failure. The optional
setup
and teardown
are expressions that are run before and
after the action
respectively. They are useful for managing
state required by a test. If is important to note that action
,
setup
and teardown
are all expressions that are wrapped in
a lambda
form by the macro. If multiple expressions are needed
for any of the parts they must be wrapped in an explicit begin
.
(make-test-suite name test ...)
The make-test-suite
macro constructs a test-suite with
the given name and tests.
SchemeUnit provides a rich library of predefined assertions. Every
assertion takes an optional message
, which is a string that is
displayed if the assertion fails. Each assertion comes in two
variants: a macro with the given name, and a function with a
* appended to the name. The macro version grabs source
location which aid debugging, as so should be used wherever possible.
The predefined assertions are:
(assert binary-predicate actual expected [message])
(assert-equal? actual expected [message])
(assert-eqv? actual expected [message])
(assert-eq? actual expected [message])
(assert-true actual [message])
(assert-false actual [message])
(assert-pred unary-predicate actual [message])
(assert-exn exn-predicate thunk [message])
(fail [message])
SchemeUnit provides a way for user's to extend its builtin collection of assertions.
(define-assertion (name param ...) expr ...)
The define-assertion
macro constructs an assertion that takes
param
s arguments and an optional message and evaluates the
expr
s. The assertion fails if the result of the expr
s is
#f
. Otherwise the assertion succeeds with a result of #t
.
The define-assertion
macro actually constructs two assertions: a
macro with name name
that collects source location information,
and a function with name name*
that does not collection source
location information but can be used in a higher-order fashion. In my
experience higher-order assertions are useful for testing SchemeUnit
but not much else.
You are encouraged to submit libraries of assertions to Schematics.
SchemeUnit provides 3 user interfaces for running tests:
A textual interface
A graphical interface
A graphical tool integrated in DrScheme
The textual inteface is in the text-ui.ss
module in the
schemeunit
collection. It provides a single function
(test/text-ui test)
that run with test and displays the results as text.
The DrScheme tool is automatically loaded so long as you install SchemeUnit into your collections directory. SchemeUnit adds a ``Test'' button to the toolbar. Click on this button to start the GUI.