A Behavioral Specification Testing Library for Clojure and Clojurescript
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



1. Usage

  • Make sure your clojure(script) versions are at or above "1.9.x".

  • Add [navis/untangled-spec "x.y.z"] to your :dependencies.

  • Make sure you have at least one test file, eg: test/your-ns/arithmetic_spec.cljc, that uses untangled-spec.core:

(ns your-ns.arithmetic-spec
    [untangled-spec.core :refer [specification behavior component assertions]]))

(specification "arithmetic"
  (component "addition"
    (behavior "is commutative"
        (+ 13 42) => (+ 42 13)))))

1.1. Clojure In The Terminal

  • Add [com.jakemccrary/lein-test-refresh "x.y.z"] to your :plugins.

  • Add the following to your project.clj configuration:

    :test-refresh {:report untangled-spec.reporters.terminal/untangled-report}
  • Run lein test-refresh in your command-line, et voila! You should see something like:

Using reporter: untangled-spec.reporters.terminal/untangled-report
*************** Running tests ***************
:reloading (your-ns.arithmetic-spec)
Running tests for: (your-ns.arithmetic-spec)

Testing your-ns.arithmetic-spec
     is commutative

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

Failed 0 of 1 assertions
Finished at 17:32:43.925 (run time: 0.01s)
Make sure you make the test fail to check that error reporting is working before moving on to another section.
Error refreshing environment: java.io.FileNotFoundException: Could not locate clojure/spec__init.class or clojure/spec.clj on classpath.

Make sure you have clojure(script) versions above "1.9.x".

Error refreshing environment: java.lang.IllegalAccessError: clj does not exist, compiling:(untangled_spec/watch.clj:1:1)

Add an :exclusions [org.clojure/tools.namespace] for tools.namespace on lein-test-refresh
(and any other projects that use it, which you can check using lein deps :tree or boot -pd),
as untangled-spec requires "0.3.x" for clojurescript support, but lein-test-refresh doesn’t need that itself.

1.2. Clojure In The Browser

  • Create a dev/clj/user.clj file that contains:

(ns clj.user
    [untangled-spec.selectors :as sel]
    [untangled-spec.suite :as suite])

(suite/def-test-suite my-test-suite
  {:config {:port 8888} (2)
   :test-paths ["test"]
   :source-paths ["src"]}
  {:available #{:focused :unit :integration}
   :default #{::sel/none :focused :unit}})

(my-test-suite) (1)
  1. Starts the test suite, note that it will stop any pre-existing test suite first, so it’s safe to call this whenever (eg: hot code reload).

  2. You can now goto localhost:8888/untangled-spec-server-tests.html

  • Make sure the "dev" folder is in your :source-paths, if you are using lein that’s probably just a :profiles {:dev {:source-paths ["dev"]}}.

  • Add clj.user to your :repl-options {:init-ns clj.user}, which again if using lein probably goes in your :profiles {:dev #_…​}

1.3. CLJS In The Browser

  • Add [figwheel-sidecar "x.y.z"] to your dev time dependencies (latest releases).

    • Add [com.cemerick/piggieback "x.y.z"] to your dev time dependencies (latest version).

    • Add :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl] to your :repl-options.

  • Add [org.clojure/clojurescript "x.y.z"] as a normal dependencies (latest releases).

  • Add to your /dev/clj/user.clj:

  [com.stuartsierra.component :as cp]
  [figwheel-sidecar.system :as fsys]

(defn start-figwheel [build-ids]
  (-> (fsys/fetch-config)
    (assoc-in [:data :build-ids] build-ids)
    fsys/figwheel-system cp/start fsys/cljs-repl))
  • Create a /dev/cljs/user.cljs

(ns cljs.user
    your-ns.arithmetic-spec (1)
    [untangled-spec.selectors :as sel]
    [untangled-spec.suite :as suite]))

(suite/def-test-suite on-load {:ns-regex #"your-ns\..*-spec"} (2)
  {:default #{::sel/none :focused}
   :available #{:focused :should-fail}})
  1. Ensures your tests are loaded so the test suite can find them

  2. Regex for finding just your tests from all the loaded namespaces.

    • (Optional) Create an HTML file for loading your tests in your resources/public folder. If you’re using the standard figwheel config, then you can also choose to load one that is provided in the JAR of Untangled Spec.

<!DOCTYPE html>
        <link href="css/untangled-spec-styles.css" rel="stylesheet" type="text/css">
        <link href="css/untangled-ui.css" rel="stylesheet" type="text/css">
        <link id="favicon" rel="shortcut icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAIElEQVQ4T2NMS0v7z0ABYBw1gGE0DBhGwwCYh4ZBOgAAcQUjIUXh8RYAAAAASUVORK5CYII="/>
        <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
        <div id="untangled-spec-report">Loading "js/test/test.js", if you need to name that something else (conflicts?) make your own test html file</div>
        <script src="js/test/test.js" type="text/javascript"></script>

The HTML above is exactly the content of the built-in file untangled-spec-client-tests.html.

:cljsbuild {:builds [

{:id "test"
 :source-paths ["src" "dev" "test"]
 :figwheel     {:on-jsload cljs.user/on-load}
 :compiler     {:main          cljs.user
                :output-to     "resources/public/js/test/test.js"
                :output-dir    "resources/public/js/test/out"
                :asset-path    "js/test/out"
                :optimizations :none}}

lein repl
#_=> (start-figwheel ["test"])
java.lang.RuntimeException: No such var: om/dispatch, compiling:(untangled/client/mutations.cljc:8:1)

Means you have a conflicting org.omcljs/om versions, either resolve them by looking at lein deps :tree or bood -pd, or pin your version to the latest version or whatever version untangled-spec is using.

  • Run the tests by loading your HTML file (or the one provided in the Untangled Spec JAR). The default figwheel port is 3449, so the URL that should always work by default if you’ve named your javascript output js/test/test.js would be: http://localhost:3449/untangled-spec-client-tests.html

1.3.1. For CI

  • Add lein-doo as both a test dependency and a plugin

    :dependencies [#_... [lein-doo "0.1.6" :scope "test"] #_...]
    :plugins [#_... [lein-doo "0.1.6"] #_...]
  • Add a :doo section to your project.clj

    :doo {:build "automated-tests"
          :paths {:karma "node_modules/karma/bin/karma"}}
  • Add a top level package.json containing at least:

      "devDependencies": {
        "karma": "^0.13.19",
        "karma-chrome-launcher": "^0.2.2",
        "karma-firefox-launcher": "^0.1.7",
        "karma-cljs-test": "^0.1.0"
  • Add a :cljsbuild for your CI tests, eg:

:cljsbuild {:builds [

{:id "automated-tests"
 :source-paths ["src" "test"]
 :compiler     {:output-to     "resources/private/js/unit-tests.js"
                :output-dir    "resources/private/js/unit-tests"
                :asset-path    "js/unit-tests"
                :main          untangled-spec.all-tests
                :optimizations :none}}

  • Add a file that runs your tests

(ns your-ns.all-tests
    your-ns.arithmetic-spec ;; ensures tests are loaded so doo can find them
    [doo.runner :refer-macros [doo-all-tests]]))

(doo-all-tests #"untangled-spec\..*-spec")
  • Run npm install & then lein doo chrome automated-tests once,

If you put the automated-tests build in a lein profile (eg: test),
you will have to prepend a with-profile test …​ in your command.
  • See doo itself for further details & as a fallback if this information is somehow out of date.

3. Development

This section is for the development of untangled-spec itself.
If you wanted instructions on how to use untangled-spec in your app/library, see Usage

3.1. CLJS In The Browser

lein repl
#_user=> (start-figwheel ["test"])

& localhost:8888/untangled-spec-server-tests.html

3.2. Clojure In The Terminal

lein test-refresh

3.3. Clojure In The Browser

lein repl
#_user=> (start)

& localhost:8888/untangled-spec-server-tests.html

3.4. CI Testing

To run the CLJ and CLJS tests on a CI server, it must have chrome, node, and npm installed.
Then you can simply use the Makefile:

make tests

or manually run:

npm install
lein test-cljs
lein test-clj

4. License

MIT License Copyright © 2015 NAVIS