Compile-time tests
1 Defining a test suite
with-examples
2 Checks mirroring Rack  Unit
check-eq?
check-not-eq?
check-eqv?
check-not-eqv?
check-equal?
check-not-equal?
check-=
check-pred
check-true
check-false
check-not-false
check-not-exn
check-regexp-match
check-match
8.18.0.18

Compile-time tests🔗ℹ

 (require examples) package: examples

This library allows writing compile-time unit tests, so that tests provide programmers with instant and prominent feedback similar to a type system. IDEs and editors such as DrRacket, Emacs, or VS Code should highlight test failures the same way they highlight other syntax errors.

    1 Defining a test suite

    2 Checks mirroring RackUnit

1 Defining a test suite🔗ℹ

syntax

(with-examples (name:id ...) body ...)

(with-examples (name:id ...) #:timeout timeout:number body ...)
Opens a fresh compile-time test suite that can refer to the names from the enclosing module, even private helpers not meant to be provided publically.

The (body ...) can run arbitrary code. Runtime errors and timeout within the body will be handled as syntax errors. The default timeout applied for each entire suite is one second, and can be customized with timeout as a positive real number.

For example, the following program raises a syntax error on the faulty factorial implementation, highlighting the first failing test case.
#lang racket/base
(require examples)
 
(define (factorial n)
  (if (< n 2) 1 (* n (- n 1))))
 
(with-examples (factorial)
  (check-equal? (factorial 0) (*))
  (check-equal? (factorial 1) (* 1))
  (check-equal? (factorial 2) (* 1 2))
  (check-equal? (factorial 3) (* 1 2 3))
  (check-equal? (factorial 4) (* 1 2 3 4)))

Note that while test suites can appear to "modify state", they are merely modifying their own instantiations "in a separate timeline". In the following example, each test suite observes its own version of the state, which is also distinct from the state initialized at runtime.

#lang racket/base
(require examples)
 
(define state (box 0))
 
(with-examples (state)
  (check-equal? (unbox state) 0)
  (set-box! state 1)
  (check-equal? (unbox state) 1))
 
(with-examples (state)
  (check-equal? (unbox state) 0)
  (set-box! state 2)
  (check-equal? (unbox state) 2))
 
(module+ main
  (printf "Init state: ~a~n" (unbox state)))

2 Checks mirroring RackUnit🔗ℹ

Compared to their counterparts from RackUnit, the checks are all macros instead of procedures. They have been reimplemented instead of a wrapping RackUnit’s utils, in order to provide fine-grained syntax error locations.

syntax

(check-eq? expr1 expr2)

Checks that expr1 is equal to expr2, using eq?.

syntax

(check-not-eq? expr1 expr2)

Checks that expr1 is not equal to expr2, using eq?.

syntax

(check-eqv? expr1 expr2)

Checks that expr1 is equal to expr2, using eqv?.

syntax

(check-not-eqv? expr1 expr2)

Checks that expr1 is not equal to expr2, using eqv?.

syntax

(check-equal? expr1 expr2)

Checks that expr1 is equal to expr2, using equal?.

syntax

(check-not-equal? expr1 expr2)

Checks that expr1 is not equal to expr2, using equal?.

syntax

(check-= expr1 expr2 epsilon)

Checks that expr2 and expr2 are numbers within epsilon of one another. It is also an error if expr1, expr2, or epsilon does not evaluate to a number.

syntax

(check-pred pred v)

Checks that pred returns a value that is not #f when applied to v. It is also an error if pred does not evaluate to a procedure that accepts one argument.

syntax

(check-true v)

Checks that v is #t.

syntax

(check-false v)

Checks that v is #f.

syntax

(check-not-false v)

Checks that v is not #f.

syntax

(check-not-exn thunk)

Checks that thunk does not raise any exception. It is also an error if thunk does not evaluate to a procedure that accepts zero argument.

syntax

(check-regexp-match regexp string)

Checks that regexp matches the string. It is also an error if regexp is does not evaluate to a value satisfying (or/c regexp? byte-regexp? string? bytes?), or string does not evaluate to a value satisfying (or/c string? bytes? path? input-port?).

syntax

(check-match expr pattern)

(check-match expr pattern guard)
Checks that value produced by expr matches against pattern as a match clause. If expression guard is provided, it is evaluated with the bindings from the matched pattern. If it produces a true value, the entire check succeeds, otherwise it fails.