Hi, Brina. This is my README of how I use RackUnit in my project. http://gyoudmon.org/~wargrey:wisemon/readme_rkt.html#%28elem._%28chunk._~3ctestsuite~3a._building._the._baby._digimon~3e~3a1%29%29
(test-suite <http://gyoudmon.org/~:/rackunit/api.html#%28form._%28%28lib._rackunit%2Fmain..rkt%29._test-suite%29%29> (format <http://gyoudmon.org/~:/reference/Writing.html#%28def._%28%28quote._~23~25kernel%29._format%29%29> "make ++only ~a" babymon-name) #:before (domake #:check? #true) (for <http://gyoudmon.org/~:/reference/for.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for%29%29> ([goal (in-list <http://gyoudmon.org/~:/reference/sequences.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._in-list%29%29> (list <http://gyoudmon.org/~:/reference/pairs.html#%28def._%28%28quote._~23~25kernel%29._list%29%29> README.md babymon.rkt))]) (test-pred <http://gyoudmon.org/~:/rackunit/api.html#%28def._%28%28lib._rackunit%2Fmain..rkt%29._test-pred%29%29> (format <http://gyoudmon.org/~:/reference/Writing.html#%28def._%28%28quote._~23~25kernel%29._format%29%29> "~a should exist" (notdir goal)) file-exists? <http://gyoudmon.org/~:/reference/Filesystem.html#%28def._%28%28quote._~23~25kernel%29._file-exists~3f%29%29> goal)) In my practice, I follow the idea of Behavior Driven Development, so in this example, the #:before routine runs `make` to build something, then the (for) routine check its behavior, say, it should create two files, hence, there is a `goal` in the (for) loop as the input argument of testcases. In my opinion, RackUnit is just too flexible since you have the entire Racket with you. Sometimes, the so-called #:before and #:after are just the way of thinking with which concepts inherit from the XUnit framework, actually, you can always forget them literally and treat the body of (test-suite) as a normal Racket module, and you are writing a program that tests other programs. After all, RackUnit knows how to find the suites and cases and do its work in the right way. Besides the #:after routine, the Racket Plumber is the final guard that can also works as the teardown routine in case that RackUnit happen to fail its work. (Because tests and results are embedded in the documentation, I always write macros that can help me make the docs looks elegant.) <make: teardown> <http://gyoudmon.org/~wargrey:wisemon/readme_rkt.html#%28elem._%28chunk._~3cmake~3a._teardown~3e~3a1%29%29> ::= (register-handbook-finalizer (thunk <http://gyoudmon.org/~:/reference/procedures.html#%28form._%28%28lib._racket%2Ffunction..rkt%29._thunk%29%29> (delete-directory/files <http://gyoudmon.org/~:/reference/Filesystem.html#%28def._%28%28lib._racket%2Ffile..rkt%29._delete-directory%2Ffiles%29%29> baby-zone))) On Wed, Mar 9, 2016 at 2:35 AM, Brian Adkins <lojicdot...@gmail.com> wrote: > Not exactly. I'm looking for a way to run a function before *each*, of > possibly many, test-cases. The test-suite #:before only runs once before > running all the test-cases. > > Although my gist: https://gist.github.com/lojic/db7016fb95b1c05e4ade only > has a few test-cases, if there were many, the redundancy of specifying the > context each time would be annoying. > > What I'd really like is something similar to Elixir though, so I think > I'll code up that macro/function. It would be more functional to have each > test-case accept a context parameter, so you'd define a setup function that > returns a value that each test-case accepts as input. > > It might look something like: > > (test-suite > "my test suite" > #:setup (lambda () (open-bank)) > > (test-case "initial balance is 0" account > (check-eq? (balance account) 0)) > > ... > > So, the lambda specified in #:setup returns an object, account, that is > passed to each test-case. > > I'll need to think of a reasonable syntax for it, but the idea is that > each test-case in a suite will have context created for it functionally. > > > On Tuesday, March 8, 2016 at 1:17:53 PM UTC-5, Matthias Felleisen wrote: > > Are you looking for something like this: > > > > #lang racket > > > > (require rackunit rackunit/text-ui) > > > > (define my-database #f) > > > > (define my-first-test-suite > > (test-suite > > "An example suite" > > #:before (lambda () (set! my-database '(a b c)) (displayln `(Before > ,my-database))) > > #:after (lambda () (set! my-database #f) (displayln `(Before > ,my-database))) > > (test-case > > "An example test" > > (check-eq? 1 1)) > > (test-suite "A nested test suite" > > (test-case "Another test" > > (check-equal? 1 2))))) > > > > > > Welcome to DrRacket, version 6.4.0.13--2016-03-04(-/f) [3m]. > > Language: racket. > > > (run-tests my-first-test-suite) > > (Before (a b c)) > > -------------------- > > An example suite > A nested test suite > Another test > > Another test > > FAILURE > > name: check-equal? > > location: unsaved-editor:17:26 > > actual: 1 > > expected: 2 > > . Check failure > > -------------------- > > (Before #f) > > 1 success(es) 1 failure(s) 0 error(s) 2 test(s) run > > 1 > > > > > > > > On Mar 8, 2016, at 1:14 PM, Brian Adkins wrote: > > > > > Jay: > > > > > > Here's a gist: https://gist.github.com/lojic/db7016fb95b1c05e4ade > > > > > > without.rkt is how I coded it up and with.rkt is how I'd like to be > able to code it. > > > > > > I agree that it's trivial to add, but for something as common as > "setup" and "teardown" for unit testing, there may be an advantage to > having it in RackUnit. When it comes down to it, test-case, check-equal, > etc. aren't hard to add either, but why should we all implement those. > > > > > > Brian > > > > > > On Tuesday, March 8, 2016 at 12:49:21 PM UTC-5, Jay McCarthy wrote: > > >> Hi Brian, > > >> > > >> > > >> Can you explain what you want to write? Just imagine that the feature > was already there... what do you want? > > >> > > >> > > >> I think of Rackunit as a way of writing checks, so if I wanted to do > what you're talking about, then I'd define the macro/function that you > don't want to. In other words, with Rackunit, you are just writing a > program and it provides a way to keep track of and print out individual > tests, so all the features of Racket are there for writing that program. > There's no reason to add functions, dynamic-wind, and begin blocks to > Rackunit, because they're already in Racket. For instance, my tests look > like > > >> > > >> > > >> (define f ....) > > >> (module+ test > > >> (check-equal? (f ....) ....) > > >> (check-equal? (f ....) ....) > > >> (check-equal? (f ....) ....)) > > >> > > >> > > >> > > >> and sometimes > > >> > > >> > > >> (define (f ....) > > >> (module+ test > > >> (define (test-f-like-woah ....) > > >> .... (check-equal? (f ....) ....) ....) > > >> (test-f-like-woah ....) > > >> (test-f-like-woah ....)) > > >> > > >> > > >> > > >> If I had already done the second kind, then I'd put setup in there. > > >> > > >> > > >> Given that Rackunit doesn't already have an "outer" paren, each check > really is atomic, so any setup would be environmental, like wrapping in a > dynamic-wind/parameterize or just another function call before the > check-equal?. > > >> > > >> > > >> Now, if you REALLY want this, and I don't feel that you should, you > could look at current-check-around and do something like: > > >> > > >> > > >> (let ([old (current-check-around)]) > > >> (parameterize ([current-check-around (lambda (c) (before!) (old c) > (after!))]) > > >> (check-equal? ....) > > >> (check-equal? ....) > > >> > > >> (check-equal? ....))) > > >> > > >> > > >> > > >> This would run (before!) 3 times and (after!) 3 times. > > >> > > >> > > >> Jay > > >> > > >> > > >> > > >> > > >> On Tue, Mar 8, 2016 at 12:23 PM, Brian Adkins wrote: > > >> Does RackUnit provide a facility similar to the setup & teardown > functions of other unit testing frameworks? In other words, I'd like to > execute some code before each test w/o coding each test to call a setup > function or having to create my own macro given how common this is. > > >> > > >> > > >> > > >> As far as I can tell, neither the #:before of test-suite nor the > before macro accomplish this. In fact, I haven't been able to discern the > purpose of the before macro because the following seem equivalent to me: > > >> > > >> > > >> > > >> (before > > >> > > >> before-expr > > >> > > >> expr1 > > >> > > >> expr2) > > >> > > >> > > >> > > >> before-expr > > >> > > >> expr1 > > >> > > >> expr2 > > >> > > >> > > >> > > >> At least with the after macro, there is a guarantee that the > after-expr will be evaluated in the face of exceptions. > > >> > > >> > > >> > > >> Also, as I mentioned in IRC, I just discovered that the setup > function in Elixir (the love child of Erlang and Ruby :) returns an > expression that each test accepts as input. This is more functional than > the traditional approach of the setup function mutating a variable that the > test cases access and allows the tests to run concurrently in the same > file. Might be worth adding to a wishlist for future versions of RackUnit. > > >> > > >> > > >> > > >> Thanks, > > >> > > >> Brian > > >> > > >> > > >> > > >> -- > > >> > > >> 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. > > >> > > >> For more options, visit https://groups.google.com/d/optout. > > >> > > >> > > >> > > >> > > >> > > >> -- > > >> > > >> Jay McCarthy > > >> Associate Professor > > >> PLT @ CS @ UMass Lowell > > >> http://jeapostrophe.github.io > > >> > > >> "Wherefore, be not weary in well-doing, > > >> for ye are laying the foundation of a great work. > > >> And out of small things proceedeth that which is great." > > >> - D&C 64:33 > > > > > > -- > > > 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+unsubscr...@googlegroups.com. > > > For more options, visit https://groups.google.com/d/optout. > > -- > 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+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.