Run tests from Clojure Repl and Leiningen
Asked Answered
A

4

40

As a newbie to clojure, I have used leiningen to create a sample project with

lein new app first-project

which gave me this directory

.
├── doc
│   └── intro.md
├── LICENSE
├── project.clj
├── README.md
├── resources
├── src
│   └── first_project
│       └── core.clj
├── target
│   └── repl
│       ├── classes
│       └── stale
│           └── extract-native.dependencies
└── test
    └── first_project
        └── core_test.clj

Without modifying any files, I can lauch successfully the only failing test with

lein test
...
Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
Tests failed.

But I am unable to do the same from the REPL using run-tests

lein repl
first-project.core=> (use 'clojure.test)
nil
first-project.core=> (run-tests)

Testing first-project.core

Ran 0 tests containing 0 assertions.
0 failures, 0 errors.
{:type :summary, :pass 0, :test 0, :error 0, :fail 0}

I tried (but does not work)

(require 'first-project.core-test)
Amblyoscope answered 22/1, 2014 at 21:25 Comment(0)
F
19

In your example above the repl is in the wrong namespace. It may work better if you switch the repl to the core_test namespace. and then run (run-tests).

(in-ns 'first-project.core-test)
(run-tests)

Another fun way of developing tests is to just run them from the REPL until they work, because tests are normal functions with some extra metadata.

(in-ns 'first-project.core-test)
(my-test)

Remember you have to load the file in addition to calling in-ns Let's say your test file is tests/first_project/core_test.clj, then you will need to call

(load "tests/first_project/core_test")
(in-ns 'first-project.core-test)
(my-test)

Keep in mind that _ in the file system becomes - in the namespace and / becomes ..

Frivolous answered 22/1, 2014 at 21:48 Comment(4)
After (in-ns 'first-project.core-test), the repl does not know anymore the namespaces for run-tests or require/use functions. I tried (clojure.test/run-tests) but it did not find any tests (Ran 0 tests)Amblyoscope
load the file first. In emacs this is ctrl-c ctrl-kFrivolous
you can also switch the repl to the namespace with ctrl-c alt-nFrivolous
This doesn't work (running Clojure 1.10). No tests are found. The require way of doing it works. This is because in-ns just sets the "current namespace" for the Clojure runtime but doesn't load anything from class files or wherever to actually fill that namespace.Oys
K
70

Start a REPL with lein repl, then use require

(require '[clojure.test :refer [run-tests]])
(require 'your-ns.example-test :reload-all)
(run-tests 'your-ns.example-test)

I prefer to stay in the user namespace, as opposed to changing it with in-ns as mentioned by another answer. Instead, pass the namespace as an argument to run-tests (as shown above).

I'd also recommend staying away from (use 'clojure.test); that is why I suggested (require '[clojure.test :refer [run-tests]]) above. For more background, read http://dev.clojure.org/jira/browse/CLJ-879

Kelso answered 21/6, 2014 at 2:23 Comment(2)
Worth adding :refresh-all to require 'your-nsHagbut
@JakubM indeed, but it needs to be :reload-all: (require 'incanter.core-tests :reload-all)Vortumnus
F
19

In your example above the repl is in the wrong namespace. It may work better if you switch the repl to the core_test namespace. and then run (run-tests).

(in-ns 'first-project.core-test)
(run-tests)

Another fun way of developing tests is to just run them from the REPL until they work, because tests are normal functions with some extra metadata.

(in-ns 'first-project.core-test)
(my-test)

Remember you have to load the file in addition to calling in-ns Let's say your test file is tests/first_project/core_test.clj, then you will need to call

(load "tests/first_project/core_test")
(in-ns 'first-project.core-test)
(my-test)

Keep in mind that _ in the file system becomes - in the namespace and / becomes ..

Frivolous answered 22/1, 2014 at 21:48 Comment(4)
After (in-ns 'first-project.core-test), the repl does not know anymore the namespaces for run-tests or require/use functions. I tried (clojure.test/run-tests) but it did not find any tests (Ran 0 tests)Amblyoscope
load the file first. In emacs this is ctrl-c ctrl-kFrivolous
you can also switch the repl to the namespace with ctrl-c alt-nFrivolous
This doesn't work (running Clojure 1.10). No tests are found. The require way of doing it works. This is because in-ns just sets the "current namespace" for the Clojure runtime but doesn't load anything from class files or wherever to actually fill that namespace.Oys
O
1

To recap:

Way of require

Full qualification of functions is only needed if you issued an in-ns earlier. Then do:

(clojure.core/require '[clojure.core :refer [require]]
                      '[clojure.test :refer [run-tests]]
                      '[clojure.repl :refer [dir]])

; Load whatever is in namespace "foo.bar-test" and reload everything
; if `:reload-all` has been additionally given

(require 'foo.bar-test :reload-all) 
;=> nil

; List your tests for good measure (Note: don't quote the namespace symbol!)

(dir foo.bar-test)
;=> t-math
;=> t-arith
;=> t-exponential
;=> nil 

; Check meta-information on a test to verify selector for example 

(meta #'foo.bar-test/t-math)
;=> {:basic-math true, :test #object[foo.bar_tes...

; `run-tests` will probably run nothing because the current namespace
; doesn't contain any tests, unless you have changed it with "in-ns"

(run-tests) 
;=> Ran 0 tests containing 0 assertions.

; run tests by giving namespace explicitly instead

(run-tests 'foo.bar-test) 
;=> Ran 3 tests containing 29 assertions.
Oys answered 7/9, 2019 at 13:55 Comment(0)
J
0

Just to add that if you are using VsCode + Calva, you can run the repl and run Tests for Current Namespace ctrl+alt+c t

Jaquelinejaquelyn answered 16/2, 2023 at 16:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.