I'd like to test my code in module.rkt with tests in module-test.rkt and the rackunit documentation advises I use
(require rackunit "module.rkt") in module-test.rkt
Alas, this only allows me to test things bound to symbols exported from module.rkt and I want to test everything..
Guessing, I looked up load as an alternative and got lost in the explanation of load-handlers and other things I didn't understand.
What, please, is the easy and accepted way to do what I'd like to do?
I would like this low-level code testing individual procedures to exist outside of the tree of logical modules which comprise the system. Otherwise it totally bloats the files with low-level test code. I would like the provide and require forms to relate only to how the modules are expected to be used, so they'll work fine for integration tests, but not low-level tests. Am I missing something or is this a reasonable thing to want to do? Is there an easy and non-dirty way to achieve this? if not, I'll create a make rule to concatenate the the two files into a temporary file. Thanks for any suggestions on a non-kludgy way to achieve this!
I suspect many (but not all!) Racketeers will not understand what you mean by « bloat », especially when the stated objective is (also) to access private module definitions.
So, a few options:
- only test the public interface. A frame challenge, but often that’s the only place where test failures are useful.
- Test the public interface in a separate test module and the private implementation in
(module+ test …).
- require/expose as mentioned elsewhere
- export the private definitions via a submodule that is used for testing, e.g.
(module+ for-tests (provide …)). This becomes a public interface in the same way as, say, modules in a foo/private collection path—socially, we all agree it’s ok to break folks who have deliberately chosen to ignore the warning signs and reach into your guts anyway. (A bit like Python’s « we’re all adults » idea.)
HTH
2 Likes
Is it possible to keep the test submodule in a separate file and bring it in with include? I have never used include, but if this works it would meet the goal of avoiding bloat in module.rkt.
1 Like
(include "module.txt") did it, much thanks!!!
1 Like
Thanks for all of the good ideas. By bloat I mean that the non-test code for all of the little procedures becomes obscured by the much larger amount of test code. This is not a problem for me as I use Emacs with Outshine-Mode (probably switching to outline-minor-mode soon) to hide/show what I want, but my students use DrRacket and get overwhelmed and stop reading the code.
If the test module includes the runtime module, you should know that struct definitions are generative. That is:
(struct a () #:transparent)
(define a1 (a))
(struct a () #:transparent)
(define a2 (a))
(equal? a1 a2)
(should) yield false.
Structs permeate Racket in sometimes unexpected ways, and it can be strange to test computations involving the « same » struct from the included version of a module and the required form of a module, perhaps transitively. Debugging is even weirder, as I don’t think there’s an easy way to make it obvious the structs come from different places?
Anyway, I’d recommend against « tests include program », since you may then test a program with different semantics than the one you actually run.
What I think @jjsimpso recommended was for the program module to include a test module, which is the other way ‘round and could work nicely. The module to include starts (module+ test in my conception.
2 Likes