test

Usage

(require-extension test)
(import test)
(test 4 (+ 2 2))

Description

This is designed to be as simple and friendly as possible. The basic interface

  (test [<name>] <expected-value> <expression>)

is really all you need to use. It will catch errors and print informative failure messages, including the name (which defaults to an abbreviated form of the test expression), the source, and the line number information of the failed expression. Equality is checked with EQUAL?, unless the expected value is inexact, in which case it checks to be sure the percentage difference between the result and expected value fall within the TEST-EPSILON parameter of each other. This is because it almost never makes sense to test inexact numbers with EQUAL? or =, and usually you'll want a single epsilon throughout a range of tests.

Two other test macros are

  (test-assert [<name>] <expression>)
  (test-error [<name>] <expression>)

which simply assert that the expression is non-false and results in an error, respectively.

Group reporting, including elapsed time and pass percentages, can be achieved using

  (test-begin [<name>])
  (test ...)
  ...
  (test-end [<name>])

where the group name is optional in either case.

You can also group in a single lexical scope (and also establish nested groups) with the TEST-GROUP macro

  (test-group <name>
    (test ...)
    ...
    )

The name for TEST-GROUP is not optional.

As a convenience there is a TEST-EXIT procedure, which exits the process with a status of 0 if all tests in all groups have passed, and with an optional numeric status (defaulting to 1), if there have been any failures or errors.

  (test-exit [<failure-exit-code>])

That's all. All other aspects of testing are controlled by parameters.

Parameters

The following parameters can be used to override the reporting behavior, for example if you wanted a GUI interface instead of the default textual reporting.

Environment

Often you'll be working on a change or new feature, and while the code is changing the test suite remains relatively constant. However, it's a pain to recompile the test suite every time, and to re-run the entire suite when just working on one area, or even when you just want to run a single test by name.

The parameters allow filtering, but it can be a pain to setup an interface to this or to recompile with different settings. So for easy use, by default the parameters can be initialized from environment variables.

CURRENT-TEST-FILTERS can be set by the environment variables TEST_FILTER, a regexp which test names must match to be run, and TEST_REMOVE, a regexp of tests not to run. For example, if you have your test suite in the file test-foo.scm, compiled to test-foo, and you only want to run the test named "test-foo-with-bells-on," you could do so with

 $ TEST_FILTER=bells-on ./test-foo

The test name defaults to the source expression, which can also be handy for quick filtering. For instance, if in the same test suite you knew that you had broken the "flurble" data structure, you could filter out all tests using it with

 $ TEST_REMOVE=flurble- ./test-foo

For more structured filtering you can also filter by group. The CURRENT-TEST-GROUP-FILTERS parameter can be initialized with the TEST_GROUP_FILTER and TEST_GROUP_REMOVE environment variables in the same way as above.

You can also default the CURRENT-TEST-VERBOSITY parameter to #f by setting the TEST_QUIET environment variable.

test tries to automatically determine if your terminal supports ANSI colors and uses them (sparingly, mostly so that failures and errors stand out). You can force this on or off by setting the environment variable TEST_USE_ANSI variable to 0 or 1.

License

BSD

History

0.8
Port to hygienic chicken [Peter Bex]
0.7
fix for dynamic test names w/o syntax-rules [Peter Bex]
0.6
adding several TERM settings to those recognized as ANSI
0.5
fixing spurious warning in nested groups
0.4
time reporting was off
0.3
minor bugfixes
0.2
minor bugfixes
0.1
initial release