Hey y’all. I’m very very new to clojure; not new to unit testing or TDD, but new to having an REPL in my dev flow
I’m curious to as how best to structure my code… I want to be able to spin up a usable REPL, so I have an repl.clj
in my src
folder with various utilities. But now that I want to move on, I want to put those in my tests.
It feels like I may be better off scrapping my approach and copying a good example of how someone else structures things instead
Hi @jings.bill My approach is to have the equivalent of repl.clj
in a dev
folder so it doesn't end up getting bundled into a JAR or anything, and then I have a :dev
alias that adds that dev
folder to the classpath when I'm working locally. So that part of our workflow overlaps.
I have a pretty tight "RDD" workflow in that I run a REPL, connect my editor to it, and never type into my REPL -- I only ever type into source (or test) files and eval code with a hot key from the editor. The important aspect is to edit/eval/edit/eval in that very tight loop -- and I often eval forms without saving the code several times as I'm building up my code. I use "Rich Comment Forms" (that's what Stu Halloway calls them, based on Rich Hickey using them 🙂 ) which is a (comment ...)
form in my source (or test) file that contains the code I'm working on as it evolves, and that becomes actual source functions and test functions as I get enough code evolved.
Stu talks about this in his REPL-Driven Development talk (to the Chicago Clojure Meetup a few years back) and also Running With Scissors which is a more recent talk (to Strange Loop perhaps?).
If you want to spend a bit of money for an online video course, I'd highly recommend looking at Eric Normand's REPL-Driven Development course. I think it's excellent.
These all emphasize how central the REPL is to your workflow, and so testing should naturally evolve out of that.
Thanks so much. How do you handle code that you use in common between test
and dev
?
Since I have dev
, src
, and test
on my classpath for dev work, "common" code can go in test
namespaces and the dev
stuff can require it as needed.
(assumption: you need run :dev
without test code present)
Here's an example RCF from a source file (not a test file -- since I work in source files to evolve code):
(comment
(require '[clojure.test :refer [deftest is]])
(deftest example
(is (= 0 (sys/ip->long "0.0.0.0")))))
So I can actually write tests directly in the source file as I'm working, and then cut'n'paste them into a test file once I have them figured out.And that means I can eval each form in that RCF as needed and I can run an individual test or "all tests in the current namespace" via hotkeys from inside my editor.
So I stay in my editor all day long and only rarely need to run tests from the command-line as a sort of "sanity check" (usually before committing code).
Yeah, that’s exactly the flow I’m looking for. The REPL gives me all I would want from a test driven flow and more, so it’s more a matter of moving the products of that flow into cold storage rather than forgetting them