TL;DR: use Karma as a test runner for your JS apps. It's great because it adds DOM support without any effort and you need DOM support when you're testing browser apps.

First of all - I love Jasmine.

It's a terrific testing framework. Maybe I'm biased because I'm a Ruby developer deep down, we Rubyists love expressiveness, but I love how readable test suites it produces.

Secondly, I love PhantomJS because it means I can run JS tests without firing my browser. That is enough when you're working on projects that are okay with modern browser support and that's usually the case right now, I hope. When that's not the case you'll going to need cross-browser tests which are not going to be discussed in this blog post, but they will be addressed soon in one of the future posts.

Thirdly, I love Gulp and I think it's way better than Grunt. Again, I might be biased - I value expressiveness and I'm also amazed by Node.js and it's most valuable feature - streams.

Having said all this, it's time to test this Ember app.

When you try to setup your Ember app for testing with something like this:

document.write('<div id="ember-testing-container"><div id="ember-testing"></div></div>');

You'll receive this error message: document is not defined

Ember requires DOM to operate and using the aforementioned toolset only enables simple JS testing. Jasmine doesn't have the concept of document baked in.

the wrong way

The first solution would probably be adding the jsdom which is basically a DOM implementation in pure JavaScript. Seems crazy, right? It is.

Suddenly we have to add a dependency to Jasmine and the only way to do that is to add the concept of RequireJS. Immediately we think of Browserify which is cool, but it also seems weird in the same time. So we now have weirdness squared. This generates a lot of FUD and it's time to discover other options.

the right way

Karma should ring a bell if you've seen Toran Billups' great tutorials about Ember testing. There's an example repo that served me well a couple of times, but it's using Karma without Gulp and QUnit instead of Jasmine.

Problems were basically gone when I added Karma to the test suite. Since I wanted to accomplish everything from Gulp, I had the feeling that something was wrong with adding a separate task runner only for tests.

This was stupid, because gulp-karma is a thing. It enables you to run Karma from within Gulp.

All the things considered - I think it's good to make every task runnable from within one task manager. I'm not sure I've chosen the right task manager for that - only thing that's important is package.json or npm.

npm is something you're going to need for almost every JS app there is, so it's good to think of it as a king of task runners. There's a good blog post about task management with npm which provides more detail and another one that explains why you should avoid global npm dependencies.

Written by

Hrvoje Šimić