A library and Leiningen plugin to run cljs.test
in many JS environments.
...and I would have gotten away with it, too, if it wasn't for you meddling kids.
This README is for the latest stable release:
[lein-doo "0.1.6"]
To use doo you need to use [org.clojure/clojurescript "0.0-3308"]
or
newer.
All arguments are optional provided there is a corresponding default under :doo
in project.clj
:
lein doo
lein doo {js-env}
lein doo {js-env} {build-id}
lein doo {js-env} {build-id} {watch-mode}
js-env
can be anychrome
,firefox
,ie
,safari
,opera
,slimer
,phantom
,node
,rhino
, ornashorn
. In the future it is planned to supportv8
,jscore
, and others.watch-mode
(optional): eitherauto
(default) oronce
which exits with 0 if the tests were successful and 1 if they failed.build-id
is one of yourcljsbuild
profiles. For exampletest
from:
:cljsbuild
{:builds [{:id "test"
:source-paths ["src" "test"]
:compiler {:output-to "resources/public/js/testable.js"
:main your-project.runner
:optimizations :none}}]}
Notice that :main
is set to the namespace your-project.runner
where you define which test namespaces you want to run, using:
(ns your-project.runner
(:require [doo.runner :refer-macros [doo-tests]]
[your-project.core-test]
[your-project.util-test]))
(doo-tests 'your-project.core-test
'your-project.util-test)
doo.runner/doo-tests
works just like cljs.test/run-tests
but it places hooks
around the tests to know when to start them and finish them. Since it
is a macro that will be calling said namespaces, you need to require
them in your-project.runner
even if you don't call any of their
functions. You can also call (doo.runner/doo-all-tests)
which wraps
cljs.test/run-all-tests
to run tests in all loaded namespaces.
Notice that doo-tests
needs to be called in the top level and can't
be called inside a function (unless you explicitly call that function
in the top level).
Then you can run:
lein doo slimer test
which starts an ClojureScript autobuilder for the test
profile and
runs slimerjs
on it when it's done.
You can also call doo
without a build-id
(as in lein doo phantom
) as
long as you specify a Default Build in your project.clj
.
doo
is packaged as a Boot task in boot-cljs-test.
To run a JavaScript file in your preferred runner you can directly call
doo.core/run-script
from Clojure:
(require '[doo.core :as doo])
(let [doo-opts {:paths {:karma "karma"}}
compiler-opts {:output-to "out/testable.js"
:optimizations :none}]
(doo/run-script :phantom compiler-opts doo-opts))
You can run doo.core/run-script
with the following arguments:
(run-script js-env compiler-opts)
(run-script js-env compiler-opts opts)
where:
js-env
- any of:phantom
,:slimer
, :node
,:rhino
,:nashorn
,:chrome
,:firefox
,:ie
,:safari
, or:opera
compiler-opts
- the options passed to the ClojureScript when it compiled the script that doo should runopts
- a map that can contain::verbose
- bool (default true) that determines if the scripts output should be printed and returned (verbose true) or only returned (verbose false).:debug
- bool (default false) to log to standard-out internal events to aid debugging:paths
- a map from runners (keywords) to string commands for bash.:exec-dir
- a directory path (file) from where runner should be executed. Defaults to nil which resolves to the current dir
This is the hardest part and doo
doesn't do it for you (yet?). Right
now if you want to run
slimer
,
phantom
, node
or nashorn that ships with the JDK 8,
you need to install them so that these commands work on the command line:
phantomjs -v
slimerjs -v
node -v
jjs -h
rhino -help
If you want to use a different command to run a certain runner, see Paths.
Remember that Rhino and Node don't come with a DOM so you can't call the window or document objects. They are meant to test functions and logic, not rendering.
If you want to run both, use lein doo headless {build-id} {watch-mode}
.
Do not install Slimer with homebrew unless you know what you are doing. There are reports of it not working with ClojureScript when installed that way because of dated versions.
Note: Slimer does not currently throw error exit codes when encountering an error, which makes them unsuitable for CI testing.
Some requirements:
- Minimum node version required:
0.12
:output-dir
is needed whenever you are using:none
.:target :nodejs
is always needed.
:node-test {:source-paths ["src" "test"]
:compiler {:output-to "target/testable.js"
:output-dir "target"
:main example.runner
:target :nodejs}}
Karma is a comprehensive JavaScript test runner. It uses plugins to extend functionality. We are interested in several "launcher" plugins which start a browser on command. You might want any of:
- karma-chrome-launcher
- karma-firefox-launcher
- karma-safari-launcher
- karma-opera-launcher
- karma-ie-launcher
Alternatively, if you don't want doo
to launch the browsers for you,
you can always launch them yourself and navigate to
http://localhost:9876
We also need to properly report cljs.test
results inside Karma.
We'll need a "framework" plugin:
- karma-cljs-test
Karma and its plugins are installed with npm
. It is
recommended
that you install Karma and it's plugins locally in the projects directory
with npm install karma --save-dev
. It is possible to install Karma and
its plugins globally with npm install -g karma
, but this is not recommended.
It is not possible to run mix local and global Karma and Karma plugins.
Karma provides a CLI tool to make running Karma simpler and to ease cross platform compatibility. doo uses the CLI tool as the default runner, if you don't install it you will need to configure doo.
For local installation run:
npm install karma karma-cljs-test --save-dev
and install the Karma CLI tool globally with
npm install -g karma-cli
then install any of the launchers you'll use:
npm install karma-chrome-launcher karma-firefox-launcher --save-dev
npm install karma-safari-launcher karma-opera-launcher --save-dev
npm install karma-ie-launcher --save-dev
The --save-dev
option informs npm
that you only need the packages
during development and not when packaging artifacts.
The installation will generate a node-modules
folder with all the
installed modules. It is recommended to add node-modules
to your
.gitignore
.
If you are using lein-npm
, follow their
instructions.
If you are using a local installation and/or node_modules
is not located
at the project root, you need to tell doo
about it. Add this to your
project.clj
:
:doo {:paths {:karma "path/to/node_modules/karma/bin/karma"}}
:cljsbuild { your-builds }
and make sure that the file karma/bin/karma
exists inside
node_modules
. If your package.json
and node_modules
folder are in the
same directory than your project.clj
, then you should use:
:doo {:paths {:karma "./node_modules/karma/bin/karma"}}
:cljsbuild { your-builds }
For more info on :paths
see Paths.
Global installation will allow you to use karma in all of your projects. The problem is that it won't be explicitly configured in your project that karma is used for testing, which makes it harder for new contributors to setup.
In some systems (e.g. Ubuntu) you might need to run all npm commands as root: sudo npm install karma --save-dev
To avoid starting a new Slimer/Phantom on every run while using auto
, we can use
Slimer/Phantom through Karma.
Install any of the launchers you'll use:
npm install karma-phantomjs-launcher --save-dev
npm install karma-slimerjs-launcher --save-dev
and call
lein doo karma-phantom test auto
lein doo karma-slimer test auto
If you are using once
, the regular phantom
/slimer
runners are recommended.
Note: karma-slimer sometimes fails to close the running Slimer instance, which you need to close manually.
After installing Electron install the launcher with
npm install karma-electron-launcher --save-dev
and call
lein doo electron test
You might want to use a different version of node, or the global version of Karma, or any other binary to run your tests for a given environment. You can configure that paths like so:
:doo {:paths {:node "user/local/bin/node12"
:karma "./frontend/node_modules/karma/bin/karma"}
:cljsbuild { your-builds }
Paths can also be used to pass command line arguments to the runners:
:doo {:paths {:phantom "phantomjs --web-security=false"
:slimer "slimerjs --ignore-ssl-errors=true"
:karma "karma --port=9881 --no-colors"
:rhino "rhino -strict"
:node "node --trace-gc --trace-gc-verbose"}}
You might want to group runners and call
them from the command line. For example, while developing you might
only be interested in chrome
and firefox
, but you also want to
test with safari
before doing a deploy:
:doo {:alias {:browsers [:chrome :firefox]
:all [:browsers :safari]}}
:cljsbuild { my-builds }
Then you can use:
lein doo browsers my-build # runs chrome and firefox
lein doo all my-build # runs chrome, firefox, and safari
As you can see, aliases can be recursively defined: watch for circular
dependencies or doo
will bark.
The only built-in alias is :headless [:phantom :slimer]
.
To save you one command line argument, lein-doo
lets you specify a
default build in your project.clj
:
:doo {:build "some-build-id"
:paths { ... }
:alias { ... }}
:cljsbuild
{:builds [{:id "some-build-id"
:source-paths ["src" "test"]
:compiler {:output-to "out/testable.js"
:optimizations :none
:main example.runner}}]}
To add custom Karma launchers (eg. as described in the Chrome Karma Plugin you can add the following config entries to your project.clj
as shown in the example below:
The plugin in the :launchers map should match an installed karma plugin and the name should match a Karma launcher (possibly a custom one as shown in the following example)
Any values in the :config key will be converted to json and merged with the karma.conf.js configuration used to launch Karma.
You will then be able to run lein doo chrome-no-security
from the comand line.
:doo {:karma {:launchers {:chrome-no-security {:plugin "karma-chrome-launcher" :name "Chrome_no_security"}}
:config {"customLaunchers"
{"Chrome_no_security" {"base" "Chrome"
"flags" ["--disable-web-security"]}}}}
To run on travis there is a sample .travis.yml
file in the example project: example/.travis.yml
(Currently only tested with PhantomJS.)
To run the tests for doo, you need to have installed rhino, phantomjs, slimer, chrome, node, and firefox. You will also need to run npm install
in the library
directory.
Most code in this project is a repackaging of cemerick/clojurescript.test, therefore most of the credit goes to Chas Emerick and contributors to that project.
Copyright © 2015 Sebastian Bensusan and Contributors.
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.