[racket] Unit Testing Best Practice in Racket

From: Eli Barzilay (eli at barzilay.org)
Date: Sat May 5 01:10:20 EDT 2012

8 hours ago, Matthias Felleisen wrote:
> On Apr 30, 2012, at 7:05 PM, Eli Barzilay wrote:
> > 3. If you use nightly builds, you can put the test code in a
> >   sub-module:
> > 
> >     #lang racket
> >     ...
> >     (module+ test (require rackunit))
> >     ...
> >     (module+ test ...test code here...)
> >     ...
> I have added this sketch to the Style guide, replacing my own manual
> method with this new notion:
>  http://www.ccs.neu.edu/home/matthias/Style/style/Units_of_Code.html#(part._.Sections_and_.Sub-modules)
> Note that this won't work in 5.2.1 yet. -- Matthias

BTW, there should also be a note there about not doing this for
distributed code because of the added dependencies.

And related to that, there's also a convenient pattern that I started
for a bunch of test files for a collection.  Note that since this is
intended for *test* files, it plays with the `main' submodule, not
with the `test' one.  (The `test' thing is useful for files that are
used for testing and separately for their functionality.)

I make each of the files look like this:

  #lang racket
  (require tests/eli-tester) ; same for rackunit but see below[*]
  (define utility ...) ; if needed
  (provide test-this)        ;*
  (module+ main (test-this)) ;*   <-- `main', not `test'
  (define (test-this)        ;*
    (test ...stuff...))
  ; possibly the same for additional test collections

The three marked lines make `test-this' run in test mode and also make
it available outside.  Now I can write the main test module:

  #lang racket
  (require tests/eli-tester "test-this.rkt" "test-that.rkt")
  (test (test-this) (test-that)) ; see below[*]

This sets things up in a similar way to Matthew's core tests setup
that is in tests/racket/* -- I can now run either

  racket test-this.rkt


  racket main.rkt

to run just the subset or everything.  Matthew's setup achieves the
same with some global namespace tricks (and using `load').

[*] The same could be done with rackunit, but note that this actually
covers a feature that it provides (at least with the gui, IIRC) for
running only some of the tests.  I like this setup because it uses the
language for doing a similar thing.  (And that goes particularly well
with my tester's philosophy of leaving as much as possible to the

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.