TDD with Leiningen

159 views
Skip to first unread message

Adam Getchell

unread,
Dec 1, 2011, 1:30:58 AM12/1/11
to clo...@googlegroups.com
Hello,

I'm porting a scientific application written in SBCL to Clojure. I'd like to do the right thing by setting up tests to ensure my functions are correct, and package up the project correctly using Leiningen.

I've read "Clojure in Action", however, the sample code from Chapter 8, which details TDD, didn't work in my environment (I'm using IntelliJ + LaClojure).

I've also read over the Leiningen tutorial here: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md which makes a passing reference to using "lein test".

However, I haven't put together how I should setup a proper test suite to generate tests for functions I have defined in, say, a file called "utilities.clj".

Any pointers/hints? For example, what do I name a file such that my "deftests" get invoked by Leiningen correctly?

Thanks,

Adam Getchell
--
"Invincibility is in oneself, vulnerability in the opponent." -- Sun Tzu

Adam Getchell

unread,
Dec 1, 2011, 2:36:14 AM12/1/11
to clo...@googlegroups.com
So, here's an example:

In the file C:\Projects\CDT\Newton\src\Newton.utilities.clj I have:

(ns Newton.utilities)

;; To keep same name conventions as utilities.lisp
;; In idomatic clojure, this could be replaced by the anonymous function
;; #(apply + %)
(defn sum
  "sums the elements of a list"
  [list]
    (apply + list))

As a first stab, I edited the file C:\Projects\CDT\Newton\test\Newton\test\core.clj to:

(ns Newton.test.core
  (:use [Newton.core])
  (:use [clojure.test]))

;;(deftest replace-me ;; FIXME: write
;;  (is false "No tests have been written."))

(deftest sum-test
  (is (= (#'Newton.utilities/sum '(1 2 3 4 5)) 15)))

Then lein test gives me:

PS C:\Projects\CDT\Newton> lein test
Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: Ne
wton.utilities/sum in this context, compiling:(Newton/test/core.clj:9)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:6416)
        at clojure.lang.Compiler.analyze(Compiler.java:6216)
        at clojure.lang.Compiler.analyze(Compiler.java:6177)
        at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3452)
...

What am I doing wrong?

Thanks,

Adam

Adam Getchell

unread,
Dec 1, 2011, 2:46:05 AM12/1/11
to clo...@googlegroups.com
So, figured out my error, thanks for listening:

C:\Projects\CDT\Newton\test\Newton\test\core.clj:

(ns Newton.test.core
  (:use [Newton.core])
  (:use [clojure.test])
  (:use [Newton.utilities]))

(deftest sum-test
  (is (= (sum '(1 2 3 4 5)) 15)))

Then:

PS C:\Projects\CDT\Newton> lein test

Testing Newton.test.core

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

Okay, I paradigm down, several to go!

Adam

Brian Marick

unread,
Dec 8, 2011, 4:10:13 PM12/8/11
to clo...@googlegroups.com
I don't know if you got any answers. If you're not wedded to clojure.test, the examples of Midje here may help:

https://github.com/marick/Midje

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-----
Brian Marick, Artisanal Labrador
Now working at http://path11.com
Contract programming in Ruby and Clojure
Occasional consulting on Agile


Kevin Downey

unread,
Dec 8, 2011, 4:22:38 PM12/8/11
to clo...@googlegroups.com
ala carte testing is easy, clojure comes with a testing library called
'clojure.test'

the simplest way to test functions is to define tests using deftest,
and to assert things using is

(use '[clojure.test :only [deftest is]])

(defn foo [x] (+ x 1))

(deftest test-foo ;; deftest creates a var, so needs to have a
different name from the function being tested
(is (= (foo 1) 2)))

you can run all the tests in a namespace using (run-all-tests)

clojure.test includes a few other things (fixtures, are assertions,
testing blocks, etc) but is generally a simple bare bones library.

`lein test` is a task for the lein build tool that runs clojure.test
tests if your project is a lein project.

the lein convention is to package tests in a separate namespace from
what is tested.

tests for the namespace foo.bar are in the namespace foo.test.bar.

the files backing test namespaces are also kept in a separate
directory, ./src vs. ./test

--
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

Jay Fields

unread,
Dec 8, 2011, 4:22:53 PM12/8/11
to clo...@googlegroups.com
My response is similar to Brian's: If you want to try something other
than clojure.test, you might like
https://github.com/jaycfields/expectations

specifically, it plays well with IntelliJ, and gives you an easy way
to run all your clojure tests using IntelliJ's built in junit
integration.

Cheers, Jay

Reply all
Reply to author
Forward
0 new messages