[racket] Unit Testing Best Practice in Racket

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue May 1 16:29:03 EDT 2012

Do try the DrRacket head in git. See #3 below. You can have your cake and eat it. 

Personally: 

 Use rackunit to

    (define/provide-test-suite --test1 
       ... uses internal functions ...)

 in "main.rkt"

 Import into a file Tests/main.rkt, run with run-test-suite 

 Always have both files open. 

That's a good approximation to the submodule works, which will come out later this summer. 


On May 1, 2012, at 3:48 PM, Chad Albers wrote:

> Thanks for the great suggestions.  I agree that I should really be testing the public interface rather than the implementation.  As a Racket n00b, I write small functions to compose the larger public facing functions, so testing these smaller/private functions prevents me for going off track.
> 
> Thanks again,
> 
> --
> Chad Albers
> 
> 
> 
> On Mon, Apr 30, 2012 at 7:05 PM, Eli Barzilay <eli at barzilay.org> wrote:
> 20 minutes ago, Chad Albers wrote:
> > Hi,
> >
> > As a Ruby dev, I really like unit testing.  I've been using RackUnit
> > to suits my needs.  I was wondering, though, about how people go
> > about writing their tests for Racket.  Many of the functions that I
> > write will not be part of the public API that a want to share from a
> > module.  I can test the side-effects of these functions in the tests
> > for the public functions that depend on the private ones.  I find
> > it, though, handy  to test the non-public functions on their
> > own.  Is there a way to run unit test against these 'private
> > functions', without making them public via a (provide)
> 
> [I'll re-use an email I sent in a different place recently...]
> 
> There are several approaches for this, the two popular ones are:
> 
> 1. One is to put most of the code in some internal module (which goes
>   in some `private' directory), and have another module which
>   provides the public api.  With this you can write low-level tests
>   against this internal module in addition to the ones that are done
>   with the public api.
> 
> 2. Another approach is to go into the module via a back door.  For
>   example, rackunit has `require/expose' which can pull out any
>   definition.  Another way to do this is to create a sandbox for the
>   module, which gives you an evaluator that works in the context of
>   the module.
> 
> A new one:
> 
> 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...)
>     ...
> 
>   The `test' submodule (which is made from all of the (module+ test
>   ...) parts) is included in the bytecode, but it is not loaded or
>   executed when the module is required.  If you run the code directly
>   in drracket it would run it, or if you use the `raco test' utility.
> 
>   (Again, this is all new stuff that is not in 5.2.1.)
> 
> (And BTW, I personally think that testing at the public interface
> level is *much* better whenever its possible.)
> 
> --
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                    http://barzilay.org/                   Maze is Life!
> 
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users



Posted on the users mailing list.