Copy whole project to tmp and start testing

Hi Everybody,

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 :slight_smile:

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.

Thank you.

Marek

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.

Right, that’s fine. I meant that if you look at a deps.edn, you always specify the version of your dependencies:

{:paths ["."]
 :deps {org.babashka/http-client {:mvn/version "0.0.2"}}}

So you don’t have to worry about that part.

So everything should work as-is if you just copy or pull a different commit in a different folder and run the tests you’re good to go.

Has an external test runner been considered?

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)

Yes, I use (experiment with) both Kaocha and cognitect-labs/test-runner and I know how to limit testing only to a namespace / directory. Thank you.

Ouh no, I can run tests while editing. I just assume it’s wrong to do it. Let me explain further…

Thank you. Just to explain further…

This is my filestructure:

myclojure/.git
myclojure/mynewapp/deps.edn
myclojure/lib1/deps.edn
myclojure/lib2/deps.edn

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.

deps.edn files look like this:

{:paths ["src"]
 :deps {org.clojure/clojure {:mvn/version "1.11.1"}
        lib1/lib1 {:local/root "../lib1"}
        lib2/lib2 {:local/root "../lib2"}}
 :aliases
 {:run-m {:main-opts ["-m" "mynewapp.mynewapp"]}
  :run-x {:ns-default mynewapp.mynewapp
          :exec-fn greet
          :exec-args {:name "Clojure"}}
  :test {:extra-paths ["src/test/clojure"]
         :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"}
                      io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}}
         :main-opts ["-m" "cognitect.test-runner" "--dir" "src/test/clojure"]
         :exec-fn cognitect.test-runner.api/test}}}

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.
shournal --query --history 1
cmd-id 8: $?: 1 15 Feb 2023 13:06:19 - 15 Feb 2023 13:06:23 :  lein test
Working directory: /tmp/xyz-123456
session-uuid KtO5/K0xEe2quIn+3YehKQ==
  6 written file(s):
     /tmp/lein-trampoline-TZbN8CnfApQK8 (0 bytes) Hash: -
     /tmp/xyz-123456/target/classes/META-INF/maven/xyz/xyz/pom.properties (50 bytes) Hash: 5072127405514259200
     /tmp/xyz-123456/target/stale/leiningen.core.classpath.extract-native-dependencies (741 bytes) Hash: 4033729210211328973
     /tmp/xyz-123456/target/classes/META-INF/maven/xyz/xyz/pom.properties (50 bytes) Hash: 5072127405514259200
     /tmp/form-init4583372013614366229.clj (0 bytes) Hash: -
     /tmp/form-init4583372013614366229.clj (11.78 KiB) Hash: 15841689575197919801
lein install
Created /tmp/xyz-123456/target/xyz-0.1.0-SNAPSHOT.jar
Wrote /tmp/xyz-123456/pom.xml
Installed jar and pom into local repo.
foobar@ip-172-16-0-198:/tmp/xyz-123456$ shournal --query --history 1
cmd-id 10: $?: 0 15 Feb 2023 13:07:03 - 15 Feb 2023 13:07:05 :  lein install
Working directory: /tmp/xyz-123456
session-uuid KtO5/K0xEe2quIn+3YehKQ==
  5 written file(s):
     /tmp/lein-trampoline-qdkDxAtMhVpNf (0 bytes) Hash: -
     /tmp/xyz-123456/target/classes/META-INF/maven/xyz/xyz/pom.properties (50 bytes) Hash: 5072127405514259200
     /tmp/xyz-123456/target/stale/leiningen.core.classpath.extract-native-dependencies (511 bytes) Hash: 9616604044851857426
     /tmp/xyz-123456/target/xyz-0.1.0-SNAPSHOT.jar (8.32 KiB) Hash: 10127287552397991358
     /tmp/xyz-123456/pom.xml (2.13 KiB) Hash: 3230530413157337364

Directories with most input/output-activity:
  Total 1 (1 written, 0 read) files at /tmp/xyz-123456/target/classes/META-INF/maven/xyz/xyz
  Total 1 (1 written, 0 read) files at /tmp/xyz-123456
  Total 1 (1 written, 0 read) files at /tmp/xyz-123456/target
  Total 1 (1 written, 0 read) files at /tmp
  Total 1 (1 written, 0 read) files at /tmp/xyz-123456/target/stale
ls -lA ~/.m2/repository/xyz/xyz/0.1.0-SNAPSHOT/
total 24
-rw-r--r-- 1 foobar foobar  190 Feb 15 13:07 _remote.repositories
-rw-r--r-- 1 foobar foobar  692 Feb 15 13:07 maven-metadata-local.xml
-rw-r--r-- 1 foobar foobar 8524 Feb 15 13:07 xyz-0.1.0-SNAPSHOT.jar
-rw-r--r-- 1 foobar foobar 2183 Feb 15 13:07 xyz-0.1.0-SNAPSHOT.pom

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.