It takes long time on my slow PC to run all tests and that’s OK since of course I can limit testing to a single namespace. But sometime I want to run all tests and the only annoying thing is that I shouldn’t continue editing files in VSCode while the testing is running.
I had an idea to solve this problem and I created a shell script to copy multiple Clojure projects into /tmp/<random> (I’m on Linux desktop), then cd into each /tmp/<random>/<project name> directory and run tests. And it is works OK
In theory I can run tests of the same projects in different versions (in different stage of development) since for example one version will be in /tmp/a and the other in /tmp/b. Or is there a problem doing that?
I realized that Java keeps files in .m2/repository so I’m not sure if I can run testing of different code but same project names. Or maybe JVM is caching something by project name and those caches would be colliding… I don’t know…
Of course cool method would be to copy it into container volume and run tests in Linux containers or at least as different users or in different namespaces but at this stage of my Clojure journey I like to keep it simple and idea of copying projects into /tmp/something and running testing is nice and simple.
That should be fine. If you copy your project to /tmp and run tests there it’s all good. Everything in .m2 is versioned, so the versions specified by your project in /tmp will be used, not the ones specified in your real project folder.
I think I overstated my dev practices and those different versions are just projects with different git commit or possibly not even different commit. But I guess I can figure out how to specify version number in deps.edn and add few lines into the shell script to add random version number into the deps.edn before running those tests.
I often run lambdaisland/kaocha test runner in watch mode, which runs the tests when relevant files are saved. Kaocha can be configured to run specific namespaces or use test selectors to minimise the number of tests run.
I also use :fail-fast? option to stop the test run on the first failing test.
This approach allows for editing of the code and even evaluation, only affecting the tests when a file is saved.
I am curious as to why editing cannot be done in VS Code while the tests are run. Does the mechanism used to run tests in VSCode lock the editor whilst tests are running? That would be unfortunate
I appreciate saving changes may effect an external test runner.
I assume the Calva test runner would only use the code evaluated in the repl, so code could easily be edited and saved whilst tests run (assume the UI is not blocked)
I technically don’t need separate Clojure projects but I like the idea to separate something I might move to a library later and also it helps me to understand how dependencies work.
In other words mynewapp depends on libraries and some libraries have no local dependencies and some depend on other local libraries.
The shell script simply copies myclojure into /tmp, then cd into /tmp/something and loops mynewapp, lib1, lib2… and runs all tests.
I run the script when I feel that nothing should fail and that all tests should be 100%. The reason why I copy myclojure is that I’m assuming (not observed though…) that when I start editing lib1/src/lib1/something.clj shortly before lib1 is tested, the tests can fail since I don’t finish typing. Also I’m assuming that for example lib2 tests might fail when I’m typing something in lib1 and lib2 depends on it.
I know for sure that If I had something simple like shell scripts in those mynewapp and lib1 directories and those shell scripts execute each other (mynewapp/mynewapp.sh would run …/lib1/lib1.sh) and I copied all directories to /tmp and run it, it would work. I just wasn’t sure about Clojure since I don’t have enough understanding how Java / Clojure works and as you can see in my deps.edn, I don’t have specified version numbers for :local/root dependencies. And I’m not sure if I can do something like {:version 1.2.3 :paths ["src"] ... in those deps.edn files.
Just versioned dependencies as @didibus mentioned. The local libs / apps will be copied there only when you for example run lein install. lein test / clj -M:test won’t write into that except downloading dependencies.
That would work assuming that the shell scripts are not writing into anything system-wide / user-wide.
I decided to test it for Clojure.
lein new xyz
Generating a project called xyz based on the 'default' template.
The default template is intended for library projects, not applications.
To see other templates (app, plugin, etc), try `lein help new`.
shournal --query --history 1
cmd-id 4: $?: 0 15 Feb 2023 13:04:46 - 15 Feb 2023 13:04:48 : lein new xyz
Working directory: /home/foobar
session-uuid KtO5/K0xEe2quIn+3YehKQ==
8 written file(s):
/tmp/lein-trampoline-rSmjCTsQMAZuS (0 bytes) Hash: -
/home/foobar/xyz/project.clj (331 bytes) Hash: 1021998550535839450
/home/foobar/xyz/README.md (741 bytes) Hash: 8315212427577166062
/home/foobar/xyz/doc/intro.md (101 bytes) Hash: 13885810224821547184
/home/foobar/xyz/src/xyz/core.clj (90 bytes) Hash: 2113769369674681647
/home/foobar/xyz/test/xyz/core_test.clj (158 bytes) Hash: 17390019948806558000
/home/foobar/xyz/LICENSE (14.04 KiB) Hash: 5497439625171630327
/home/foobar/xyz/CHANGELOG.md (770 bytes) Hash: 6943773400257972078
Directories with most input/output-activity:
Total 4 (4 written, 0 read) files at /home/foobar/xyz
Total 1 (1 written, 0 read) files at /home/foobar/xyz/doc
Total 1 (1 written, 0 read) files at /home/foobar/xyz/test/xyz
Total 1 (1 written, 0 read) files at /tmp
Total 1 (1 written, 0 read) files at /home/foobar/xyz/src/xyz
cp -a xyz /tmp/xyz-123456
cd /tmp/xyz-123456
lein test
Retrieving org/clojure/clojure/1.11.1/clojure-1.11.1.pom from central
Retrieving org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.pom from central
Retrieving org/clojure/pom.contrib/1.1.0/pom.contrib-1.1.0.pom from central
Retrieving org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.pom from central
Retrieving nrepl/nrepl/1.0.0/nrepl-1.0.0.pom from clojars
Retrieving org/nrepl/incomplete/0.1.0/incomplete-0.1.0.pom from clojars
Retrieving org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar from central
Retrieving org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar from central
Retrieving org/clojure/clojure/1.11.1/clojure-1.11.1.jar from central
Retrieving nrepl/nrepl/1.0.0/nrepl-1.0.0.jar from clojars
Retrieving org/nrepl/incomplete/0.1.0/incomplete-0.1.0.jar from clojars
lein test xyz.core-test
lein test :only xyz.core-test/a-test
FAIL in (a-test) (core_test.clj:7)
FIXME, I fail.
expected: (= 0 1)
actual: (not (= 0 1))
Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
Tests failed.