Does anyone know of any resources for tips for combining Send To REPL style development with Test Driven Development?
I am thinking in regard to the way that the tests are structured in a way that it makes it straightforward to send the test setup and computation to a REPL (for REPL driving the tests, or debugging if the test fails later)
But if there are other options I am open to exploring that too…
going from Clojure playground projects to using it for a job, and trying to get a good workflow established… 😄
Congrats!
Stuart have a section about REPL and tests in his talk https://youtu.be/Qx0-pViyIDU?t=1346
At our projects we usually have helper fns to refresh code and run the tests. I personally have some shortcuts in my editor (vim) for refreshing code and for running tests on current file. We also have structured the app’s state following Stuart Sierra’s http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded. So https://github.com/stuartsierra/component and https://github.com/weavejester/reloaded.repl are super handy to begin with.
https://github.com/cognitect-labs/transcriptor might be of interest.
A good tool is "run test at point" (point == current location) https://github.com/clojure-emacs/cider/blob/3147a27ffff6858bc8fc071386c9b8999b74c12b/cider-test.el#L782 i.e. you run a single deftest. this creates a fast feedback loop between sending forms to the repl, and running the deftest that depends on that behavior
I use VS Code and Clover (for REPL eval; but also Calva for a lot of other stuff with nREPL disabled) and I have hot keys for: run current test, run all tests in this namespace, find and run all tests “associated” with the current ns.
The latter attempts to require <current ns>-test
and, if successful, run the tests there. The nice thing about that is that I can work in a source file and — without saving files — eval a function to get its updated version into the REPL and then run all associated tests, with just two hot keys and not leaving the source file.
I need to make “run current test” smarter (right now the cursor has to be on the test name rather than just anywhere in the form).
Another thing I take advantage of while writing tests is that you can just “eval form” so you can eval pieces of a test, either for debugging or just a sanity check on what they are testing. You can eval the “actual” or “expected” values independently, you can eval the whole condition, you can eval the is
expression (which is usually the same as eval’ing the condition), and/or you can eval a testing
group.
@seancorfield this last point is kind of what I was initially thinking about… are there any references to how to structure tests like you mentioned to make it “eval form” friendly
I know you have a ton of projects out there, so not sure if there are any out there that might be good reference examples
this might seem super obvious, but it's a change from imperative test frameworks that prize "before" blocks: don't do (let [result1 (form1 arg1) result2 (form2 arg2)] (is (= result1 result2)))
but instead (is (= (form1 arg1) (form2 arg2)))
that way you can eval any part of the test without having to "reach outside" to get necessary references