Konacha is a testing tool for JavaScript applications running on Rails.
Why Konacha?
- It’s very fast.
- It treats JavaScript like a first-class citizen: Your tests are written in JavaScript, call into JavaScript code, and inspect JavaScript objects. You can still trigger events, e.g. with jQuery, if you need to simulate user actions.
- It comes with support for the Rails asset pipeline. [1]
- It supports CoffeeScript.
- You can use the in-browser runner (good for development), or run your test suite from the command line through Selenium (good for build servers).
What it cannot do is talk to the server. In particular:
- It cannot use the database.
- It cannot access your Rails (server-side) views. Any DOM nodes you are testing need to be created on the client side (for instance with JST templates), not served out by views.
When you need either of these two, write integration tests with Capybara instead.
Tutorial: Overview
Testing Plain JavaScript
Let’s start by testing some pure JavaScript (without DOM manipulation). Say you want to test the following function in a Rails 3.1+ app:
1 2 3 4 5 6 7 8 |
|
To test this, first add Konacha to your Gemfile:
1 2 3 |
|
Now mkdir -p spec/javascripts
, and create a spec file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
We’ll get to the details of the syntax in a minute.
If you prefer CoffeeScript, you can also use .js.coffee
spec files. For spec
files in particular, I find CoffeeScript much more readable than plain
JavaScript.
Run bundle exec rake konacha:serve
, and point your browser at
localhost:3500.
If everything loaded alright, you should now see two tests passing, and the third one failing:
If that’s not what you are getting, make sure you have a JavaScript console open in the Konacha browser window, so you can see errors. If there are any issues with loading your tests (such as syntax errors in your test declarations), Konacha will not catch it and display an error. You just get a blank test page, or worse, parts of your test suite are silently dropped. For that reason, I always run my tests with a JavaScript console open.
Testing the DOM
Let’s write up a minimal three-line app:
1 2 3 4 5 |
|
Here, appendTo
shall be the method used to initialize our app and render it
into the DOM – normally into an empty root div provided by the view. To test
it with Konacha, we render it into the special #konacha
div, which is
automatically cleared between test cases.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Open localhost:3500, or localhost:3500/view_spec to run the test in isolation.
Writing Tests
Assertions
The assertions you saw in the test code above – .should.be.false
and
assert.ok(...)
– are provided through the Chai testing library. Chai comes
with two assertion styles, which you can mix and match freely in your tests:
should/expect (“BDD-style”) and
assert (“TDD-style”).
I generally find the should
style more readable, but I recommend you still
acquaint yourself with both styles, as they are not one-to-one equivalents.
If you are coming from RSpec, you will be disappointed to find that Chai’s
should
interface is much less powerful than RSpec’s. For example, it does not
allow you to call arbitrary
operators
or predicate
methods.
So whereas in Ruby I would write a.should be_open
, in JavaScript I write
assert.ok(a.open())
or a.open().should.be.ok
.
Structure
Konacha uses the Mocha framework with the BDD
interface style to
structure your tests into suites and test cases. The describe
/it
syntax
should look familiar to most:
1 2 3 4 5 6 7 8 |
|
Practical Hints
Extract common code into a
spec/javascripts/spec_helper.js
file, and//= require spec_helper
at the top of each spec file.Group your tests into subdirectories as you see fit.
It’s happened to me several times that I wrote assertions that cannot fail. Examples include
.should.be.thisIsATypo
(does nothing) and$('.foo').should.not.be.empty
(empty
does not play with jQuery). For that reason, I recommend practicing test-first development, so you’ve seen each of your tests fail at least once.Writing DOM tests with jQuery turns out to be rather awkward. Try adding chai-jquery to your project for some jQuery-specific Chai assertions. For instance:
1 2 |
|
- Always keep a JavaScript console open while running tests, so you’ll see load errors.
Further Reading
Footnotes
[1] Without asset pipeline support, you would either have to enumerate all your
dependencies manually, or include the generated application.js
file and live
with stack-traces like application.js:54029
.
Thanks to John Firebaugh, Yuri Gadow, and Joel Parker Henderson for reading drafts of this.