Clojure test: Combining test-selectors with fixtures - clojure

Using Leiningen one can created test-selectors as follows:
:test-selectors {:default (complement :slow)
:slow :slow
:all (constantly true)}
The problem is that if one of the tests that is marked as :slow is using fixtures, the fixtures will be run even if the user specifies a different test suite.
What would be a good approach to address this problem?

What version of leiningen are you using? This commit (included in lein since version 2.3.0) changed the way that tests are skipped when using :test-selectors, and it is supposed to have fixed the exact issue you are describing.
You can check the version with lein -v

Related

Problems with importing package from Github

before I start, you probably need to know three things:
I don't have Java background
I'm a Clojure newbie - started to learn it
question is related to my "training" package kennyfy
TL;DR version I'm not able to import/use my training package in a project
Longer version
I set myself a goal - write simple API which converts text to kennyspeak. Before that I've created a package (using default lein template).
I tried to import this package to my API.
Part of project.clj looks like this:
:repositories [["jitpack" "https://jitpack.io"]]
:dependencies [[com.github.radmen/clojure-kennyfy "0.1.2"]]
lein deps fetches the package without any problems.
When I try to use it, Clojure fails with following message:
kennyfy-api.core=> (radmen.kennyfy/kenny-speak "foo")
ClassNotFoundException radmen.kennyfy java.net.URLClassLoader.findClass (URLClassLoader.java:382)
I understand the error, yet I've no idea why this class is not imported.
I am quite sure, that this may be related to the metadata stored in the package, which results in failed imports.
What am I doing wrong?
Thank you
$ java -version
openjdk version "1.8.0_192"
OpenJDK Runtime Environment (build 1.8.0_192-b26)
OpenJDK 64-Bit Server VM (build 25.192-b26, mixed mode)
$ lein version
Leiningen 2.8.3 on Java 1.8.0_192 OpenJDK 64-Bit Server VM
Clojure 1.9.0
A clojure namespaces is loaded the first time it is required.
foo.core=> (radmen.kennyfy/kenny-speak "foo")
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:382).
radmen.kennyfy
foo.core=> (require '[radmen.kennyfy :as kennyfy])
nil
foo.core=> (kennyfy/kenny-speak "foo")
"mpfppfppf"
foo.core=> (radmen.kennyfy/kenny-speak "foo")
"mpfppfppf"
foo.core=>

Use leiningen aliases to specify JVM flags

How can I specify JVM flags so that they apply only to one alias in a project.clj file?
Specifically I want to try the built in server capability in Clojure 1.8.0.
I can do this with an uberjar and the command:
java -Dclojure.server.interactive="{:port 8411 :accept srv.action/process}" -jar target\uberjar\srv-0.1.0-SNAPSHOT-standalone.jar
But I was hoping I could set that -D... from within a lein alias.
I tried this
:aliases {
"serve" [:jvm-opts ["-Dclojure.server.interactive={:port 8411 :accept srv.action/process}"] "run"]
}
But I get
java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String
Is it possible to do this?
I am using "Leiningen 2.6.1 on Java 1.8.0_92 Java HotSpot(TM) 64-Bit Server VM"
Leiningen profiles are definitely the way to do this. You can define a profile with any of the usual options, in your case :jvm-opts. In your profile.clj include something similar to the following:
:profiles {:clj-server {:jvm-opts ["-Dclojure.server.interactive={:port 8411 :accept srv.action/process}"]}}
Then you can tell leiningen you wish to use this profile via with-profile.
lein with-profile clj-server run
However, this will only use the options specified in the new profile. If you wish to activate the new profile in addition to the default profiles (dev, test, etc) you need to prepend the profile with a +.
lein with-profile +clj-server run
If you're lazy, like me, you can define an alias to run different tasks utilizing this newly defined profile:
:aliases {"clj-server-run" ["with-profile" "+clj-server" "run"]}
Then it's as easy as calling lein clj-server-run.
Hopefully this helps. I truly recommend reading through the leiningen documentation provided as well as its extremely useful.
I found an answer using profiles:
:profiles {:uberjar {:aot :all}
:server {:jvm-opts ["-Dclojure.server.interactive={:port 8411 :accept srv.action/process}"]}}
:aliases {
"serve" [ "with-profile" "server" "run"]})
I added a 'server' profile, which is allowed to specify its own :jvm-opts and then an alias to run that profile. It can be run with lein serve.
Any comments welcome.

Lein console (like sbt)

Is there some built-in functionality or plugin to lein to get a lein console, so for example one could test without waiting every time for JVM to start up.
$ lein console
>>> test
...
>>> test
...
>>> jar
Note: I'd like to trigger test runs myself, not e.g. by watching source files. That's why I'd like to have a lein console.
Clarification: I'm not looking for lein repl. I'd like to have a console where I could run lein task commands.
Older versions of leiningen used to include lein interactive, which behaved much like the feature you are asking for: it opened a shell into which you could type test and have it run lein test from the already-running lein jvm, and so on. This feature was removed in the transition to lein 2.0, I think, and although I don't know why I suspect there was a good reason. Maybe try asking in #leiningen on freenode?
You might want to have a look at grenchman. While it's not a Leiningen console it at least enables reusing of an existing REPL session. From what I gather, usage is as follows:
Move somewhere that is not inside a project and call:
$ lein repl :headless
Within your project directory, use:
$ grench lein <task> <options>
Tasks will be run inside the already spun up Leiningen JVM and the startup overhead should disappear.
Building grenchman seems to be tedious, though, and it is recommended to use one of the precompiled binaries (BUT they are currently not available).
And finally, that page also states:
Grenchman is still very new and may not be fully reliable.
So, good luck, I guess?
One option is to run a repl from leiningen's own jar file.
$ java -cp ~/.lein/self-installs/leiningen-2.5.0-standalone.jar clojure.main
Clojure 1.6.0
user=> (require '[leiningen.core.project :as project] '[leiningen.test :as test])
nil
user=> (def prj (project/read))
#'user/prj
user=> (test/test prj)
lein test org.noisesmith.orsos.load-test
Ran 3 tests containing 3 assertions.
0 failures, 0 errors.
nil
user=> (require '[leiningen.jar :as jar])
nil
user=> (jar/jar prj 'org.noisesmith.orsos)
Compiling org.noisesmith.orsos
Created /media/justin/806084F16084EEEA/clojure/orsos/target/orsos-0.1.0-SNAPSHOT.jar
{[:extension "jar"] "/media/justin/806084F16084EEEA/clojure/orsos/target/orsos-0.1.0-SNAPSHOT.jar"}
user=>
As a baseline, this can run lein tasks without having to restart lein every time. If you also use rlwrap or use nrepl it becomes a bit more usable. As far as I know there is no user friendly tooling around this (though there easily could be).
If you wish to use tasks from lein plugins those can be added to the -cp arg.

leiningen - clojurescript equivalent of lein run?

In clojure I can run:
lein run -m my.namespace # run the -main function of a namespace
and this will run my code from the command line.
Is there an equivalent for Clojurescipt to run the generated code in node.js? (In leiningen)
(I have read the doco for starting the Clojurescript REPL, for the running on node.js and the reply integrated into my application. I was just looking for a one-line command line solution.)
Depending on what your goal is, you might find it useful to use 'cljsbuild test'. You can specify a test context on your project.clj that uses node.js/v8/phantomjs.
Example:
:cljsbuild {
:test-commands {
"v8" ["v8"
"target/generated-sources/private/js/client.js"
"tests/v8-test-runner.js"]}}
v8-test-runner.js:
path.to.your.entrypoint.start()
You can also leave 'lein cljsbuild auto' running and start the javascript application directly:
v8 target/generated-sources/private/js/client.js tests/v8-test-wrapper.js
That's probably the best option if you are building a node.js application using clojurescript. You don't need to worry about classpaths in javascript (which is the major thing that lein run provides), you can just run your application directly from the assembled javascript file.

How do I add unit tests to a Leiningen project?

I noticed that leiningen has a great unit test plugin - you just enter "lein test" :) . However, it's not clear how it "finds" the test files. Is there a specific folder I need to put them in? Or, if its just scanning namespaces (which is what it says in the lein docs), how do I know what namespace I need to use for leiningen to see my tests?
I was thinking about simply making one test file, called tests.clj. A sample template would really be nice.
At the top level make a test/ directory, and then create some file, say mytests.clj. Here's a sample (caveat: I didn't actually compile this, but simplified an existing test):
(ns mytests
(:use clojure.test))
(defn myfixture [block]
(do
(println "before test")
(block)
(println "after test")))
(use-fixtures :each myfixture)
(deftest mytest
(is (= 2 (+ 1 1))))
for lein version 2.7.1 : {this is from Linux Mint with Leiningen 2.7.1 on Java 1.8.0_121 Java HotSpot(TM) 64-Bit Server VM }
I wanted to do more with testing and now have this new knowledge...
lein new <projname>
cd <projname>
tree -d
cat test/<projname>/core_test.clj
lein test
-> observe failing test template even on blank new project
then you could add: (print "start adding test")
and see your efforts ...