Unit Test with Clojure
Create a new App
Command Line
lein new funapp
Leiningen will create a basic starting project for you that will look like the structure below.
.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── doc
│ └── intro.md
├── project.clj
├── resources
├── src
│ └── funapp
│ └── core.clj
└── test
└── funapp
└── core_test.clj
Leiningen is package manage tool that will allow us a clean run and test interface. If you change into the funapp directory you can run “lein test”.
Command Line
$ lein test
lein test funapp.core-test
lein test :only funapp.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.
Notice that when you run the project you start immediately with a failed test. The tests is in the core_test.clj file and simply stating that it is expecting 0 to be equal to 1. Lets fix this test.
test/funapp/core_test.clj
(ns funapp.core-test
(:require [clojure.test :refer :all]
[funapp.core :refer :all]))
(deftest a-test
(testing "FIXME, I fail."
(is (= 0 1))))
Check out the last line of the test.
test/funapp/core_test.clj
(is (= 0 1))))
Witihin the last line there is a function “is” that asserts whether a its next argument resolves to true or false. If it is false it will result in a failing test. Let’s change that last line to look like.
test/funapp/core_test.clj
(is (= 1 1))))
This time when you run your tests you should see an output like.
Command Line
$ lein test
lein test funapp.core-test
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
Test a function
Now that you have a basic build that is passing its tests we need to make it a little more useful. Lets say that in this funapp that I a function that will add up all the numbers in a list. We will start with a list of (1 2 3).
As with any TDD process lets write a basic failing test and add it to “core_test.clj”.
test/funapp/core_test.clj
(deftest addList-test
(testing "Function should add up all numbers in the list"
(is (= 6 (addList [1 2 3])))))
Command Line
$ lein test
Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: addList in this context, compiling:(funapp/core_test.clj:11:14)
Failing is good. This particular failure is telling us that the function
Remember back from the tree diagram there is a src folder and underneath it is “funapp/core.clj”. Lets open that file up.
funapp/core.clj
(ns funapp.core)
(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!"))
Within that file add a new function called addList that will sum up all the numbers in the list.
funapp/core.clj
(defn addList
"This will add all the numbers in a list"
[x]
(reduce + x))
Try running your tests now.
Command Line
$ lein test
lein test funapp.core-test
Ran 2 tests containing 2 assertions.
0 failures, 0 errors.