How to set up rackunit tests to test the REPL?

27 views
Skip to first unread message

Kuang-Chen Lu

unread,
Sep 8, 2021, 9:31:01 PM9/8/21
to Racket Users
Hi,

What are the recommended ways to create unit tests that test both run and REPL (#%top-interaction)?

Background: I created a custom language and have some unit tests. My updated language passed all unit tests. After delivery, a client ran into a bug that only happens in REPL. I could have found the bug if the REPL was also tested.

Thanks,

KC

Ryan Culpepper

unread,
Sep 9, 2021, 9:20:56 AM9/9/21
to Kuang-Chen Lu, Racket Users
This is one of the few (IMO) legitimate uses of `eval`.

Your test suite should create a namespace, set it up by requiring your language's module, and then eval interactions expressed as quoted S-expressions or syntax objects. Here's a basic example for testing `match`:

    #lang racket/base
    (require syntax/strip-context rackunit)

    (define test-ns (make-base-empty-namespace))
    (parameterize ((current-namespace test-ns))
      (namespace-require 'racket/base)
      (namespace-require 'racket/match))

    ;; test-eval : (U Syntax S-expr) -> Any
    (define (test-eval expr)
      (parameterize ((current-namespace test-ns))
        (eval `(#%top-interaction
                . ,(cond [(syntax? expr)
                          (namespace-syntax-introduce
                           (strip-context expr))]
                         [else expr])))))

    (check-equal? (test-eval
                   '(match (list 1 2 3)
                      [(cons x ys) x]
                      [_ #f]))
                  1)

    (void (test-eval '(define null? zero?))) ;; !!!

    (check-equal? (test-eval
                   #'(match 0
                       [(? null?) 'ok]
                       [_ 'no]))
                  'ok)

The call to `strip-syntax` is necessary in the second test to make `null?` refer to the redefinition in the testing namespace instead of the normal binding visible to the testing module.

Ryan


--
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/e768fbf6-81db-4bb9-9195-6e3ce74a2d55n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages