This guide explains how to setup buster-cljs in your Clojurescript project, specificaly:
How to install and setup buster.js
How to setup lein-cljsbuild to collaborate with buster.js
How to keep cross-platform test suites for both Clojure and Clojurescript
buster-cljs provides a powerful platform to test your Clojurescript code both in the browser (using many different vendors) and node.
Buster.js is a node.js package that a) provides a test case / assertions library and b) runs a node web server which pushes tests out to any browsers you slave to it. When you want to run your javascript tests, you issue the `buster-test' command in the terminal to push tests to slaved browsers, in parallel, and collect the results.
The surface-level API for buster-cljs is clojure.test compatible.
This library has been tested with Clojure 1.4, and Clojurescript version that comes bundled with lein-cljsbuild 0.2.9
This library has been tested with busterjs 0.6.3 beta 4.
With leiningen:
[com.birdseye-sw/buster-cljs "0.1.0"]
With Maven:
<dependency>
<groupId>com.birdseye-sw</groupId>
<artifactId>buster-cljs</artifactId>
<version>0.1.0</version>
</dependency>
In order to start, you'll need to install node.js and npm. Follow the instructions here.
Next, install the buster package using npm
$> npm install -g buster
Once the library is installed, create a buster.js
config file in your project root directory and run the buster-server
command.
$> buster-server
Buster is now waiting for you to slave some browsers to the server you just started. Follow the link it gives you.
In order for your project to work as intended with busterjs, you'll need to create 3 different builds using the lein-cljsbuild plugin.
Let's assume there are 2 folders in your project, src/cljs
and
test/cljs
. The first one contains the actual code and the second
one contains the test code. You will need to have one build just for
the development code and multiple ones for the test code. For example:
(defproject my-cljs-project
:dependencies [[com.birdseye-sw/buster-cljs ]]
:cljsbuild
{:builds
[{:id "dev"
:source-path "src/cljs"
:compiler
{:optimizations :simple
:pretty-print true
:externs ["externs/buster.js"]
:output-to "my_cljs_project_dev.js"}}
{:id "browser-test"
:source-path "test/cljs"
:compiler
{:optimizations :simple
:pretty-print true
:externs ["resouces/externs/buster.js"]
:libraries ["resources/js/my_cljs_project_dev.js"]
:output-to "resources/js/my_cljs_project_browser_test.js"}}
{:id "browser-advanced-test"
:source-path "test/cljs"
:compiler
{:optimizations :advanced
:pretty-print false
:externs ["resouces/externs/buster.js"]
:libraries ["resources/js/my_cljs_project_dev.js"]
:output-to "resources/js/my_cljs_project_browser_optimized_test.js"}}
{:id "node-test"
:source-path "test/cljs"
:compiler
{:optimizations :simple
:pretty-print true
:target :nodejs
:externs ["resouces/externs/buster.js"]
:libraries ["resources/js/my_cljs_project_dev.js"]
:output-to "resources/js/my_cljs_project_node_test.js"}}]})
Notice that we use the dev
build as a library source in both
browser-test
and node-test
. This is to keep your library/app code
separated from the test code. Also is important to mention that the
dev
build must be compiled always with a simple optimization,
otherwise the test won't be able to compile correctly.
Once your project.clj
has these builds you have to create a
buster.js
config in the root of your project. It specifies
where the test suites are:
var config = exports;
config["Browser Tests"] = {
environment: "browser",
sources: [],
tests: [ "resources/js/my_cljs_project_browser_test.js"
, "resources/js/my_cljs_project_browser_optimized_test.js"]
};
config["Node Tests"] = {
environment: "node",
sources: [],
tests: ["resources/js/my_cljs_project_node_test.js"]
};
Important: Advanced compilation mode is only supported in the browser. Node.js with advanced compilation is not supported just yet.
Now you are ready to run the tests. Once you have some slave browsers
connected to buster-server
, run:
$> buster-test -e browser
If you want to execute the tests for node:
$> buster-test -e node
You can also see the test suite as a static page (qUnit style) by running this command in the root directory of your project:
$> buster-static
buster-cljs works both for Clojure and Clojurescript by using lein-dalap.
This example demonstrates use of lein-dalap to translate the JVM specific forms to JS compatible Clojurescript:
^{:cljs
'(ns my-cljs-project.test.util-test
(:require [my-cljs-project.util :as util])
(:require-macros [buster-cljs.macros :refer [initialize-buster deftest describe it is])))
(ns my-cljs-project.test.util
(:require [my-cljs-project.util :as util]
[buster-cljs.clojure :refer [deftest describe it is]]))
;; This line bellow is only necessary if you are going to be testing
;; your library against node, and it will only be there in Clojurescript
#_(:cljs (initialize-buster))
;; `describe` and `it` will be equivalent to `testing` on clojure side
(deftest shout-function
(it "always caps"
(is (= (util/shout "hello") "HELLO") "shout should make hello all caps")))
Important: In order to see your test results via buster, you'll
need to wrap your assertions inside it
clauses.
Congratulations! You now know how to do most of the setup and implementation of simple tests using buster-cljs. By now you should be able to:
Read how to manage cross-platforms Clojure/Clojurescript code using lein-dalap and more about what buster.js may offer.