Unit testing Ember apps with Mocha


#1

We have an Ember app (running on top of Django) which currently has no unit tests. We’ve been putting it off because the state of Ember and testing has been in flux, but I feel that it’s now in a pretty good state and we’d like to begin testing. I’ve been scouring the Googlez for examples but I wanted to ask here first.

Does anyone have what they would consider the definitive (for the time being) guide to unit testing Ember applications with Mocha? I found this post but the last comment was from August 2013.

Our current stack is:

DEBUG: Ember      : 1.3.0-beta.1+canary.ea261c9f core.libs.js:5507
DEBUG: Ember Data : 1.0.0-beta.2 core.libs.js:5507
DEBUG: Handlebars : 1.0.0 core.libs.js:5507
DEBUG: jQuery     : 2.0.3  

All of our application code is contained in a single file application.activity.js. We have a secondary app which performs reporting that we’d like to split out as well, application.reports.js.

Mostly what I’m looking for is guidance on how to split out the various parts of our app for testing. We’re already using grunt to concat some assorted 3rd party libs so we could also use that to concat the pieces and parts into the main application file for production.

In addition to this guidance, I’m wondering what’s the best place to start. Models? Controllers? Routes? Views? We also use a few Handlebars helpers that would be cool to test as well.

Thanks in advance.

PS. I neglected to say that we’d ideally like to test this via CLI. We’re already using Mocha for some tests on our CouchDB views, and it would be cool to continue using it. That said, we’re not adverse to also using PhantomJS if necessary.


#2

Just a few quick questions to manage your expectations

1.) your question mentions Mocha specifically so I assume you want to hear about the ember-testing Mocha adapter, correct? Also to clarify -are you set 100% on “we must use Mocha” or would QUnit still work for you? (why/ why not)

2.) although you mention Mocha specifically, you also seem to be asking about general unit testing advise like “when should I unit test vs integration test with ember”, correct?

3.) You mention grunt, are you planning to run your tests w/ something like karma or testum? Would you want to see how to integrate your grunt build w/ the test runner (if you decided to use something like karma ?)

Thanks !


#3

We’re in the same boat, about to start adding tests, and the main argument for Mocha over QUnit is the BDD-style tests in addition to TDD-style tests and the ability to use assertion libraries like Chai.js, e.g. foo.should.be.a('string'). (QUnit doesn’t appear to work out of the box with assertion libraries that operate by throwing errors.) @teddyzeenny’s ember-mocha-adapter looks like the mocha adapter to use, handling methods for asyncStart and asyncEnd, and Matteo just wrote a Konacha walkthrough that uses ember-mocha-adapter. It also looks like @ghempton’s EPF is testing with Mocha, and successfully using mocha-as-promised, which looks interesting. Then I’m guessing the idea would be to following along with the Grunt config from EAK, which now recommends Testem as the test runner?

Alternatively, are people suggesting that we stick with QUnit as the Ember Happy Path and attempt to use plugins for BDD-style assertions (like SpecIt and Pavlov) instead?


#4
  1. I saw Teddy’s adapter, and if we move forward using Mocha, then we’ll probably us it. We’re using Mocha simply because we use it in other areas, and in other parts of the company. We’re not sold on it, but we do like it. QUnit is the only other framework I personally have used so I’d be comfortable with that. If there’s a testing setup that is overwhelmingly the best / most popular / most well documented, then I’d definitely switch to using it.

  2. Perhaps? The other members on my team both have greater experience with unit testing than I do. I just want to start writing some tests for our app. We’ve had some big changes lately that would have been more easily and confidently change if we had tests.

  3. This might not be answering your question but we run our tests with grunt directly. The grunt test command runs a Grunt task as defined in our Grunt file:

    mochaTest: { options: { reporter: “nyan” }, all: { src: [“src/test/couchdb/", "src/test/client/”] }, client: { src: [“src/test/client/"] }, couchdb: { src: ["src/test/couchdb/”] } }

    grunt.registerTask(‘test’, ‘Run the appropriate test target.’, function(target) { target = target || ‘all’; grunt.task.run(‘mochaTest:’ + target); });

We’re open to anything at the moment. Any set up, any best practice, all are on the table.


#5

QUnit is dead simple to use and is the default test adapter for Ember if you don’t specify any, so you would probably have the easiest ride there (compare the QUnit adapter code with the Mocha adapter and you can see there’s not much going on in QUnit).

That said, I am a big fan of Mocha for its BDD-style tests, spec reporter options, and choice of assertion libraries. There’s a little bit more boilerplate code compared to QUnit, but it’s not so bad.

If you’re looking for a good example of how to set up tests, Ember App Kit is worth checking out. It uses QUnit, but you should get the general idea.

At the minimum, you should have something like this:

There are variations, or course. Ember App Kit, for instance, re-creates the whole App before each test and destroys it after each, whereas I’m only setting it up once then resetting it before each test. I suppose either could work.


#6

We have split our app to various require.js modules and we use karma test driver to run our unit tests on various browsers. We realize we really want to run our unit tests inside browsers. Karma comes with mocha adapter already.

We used testem before. It was good, but karma comes with code coverage out of the box and generally suite our needs better.

We use custom build karma configuration generator that generates karma config file for particular test, group of tests or for all our tests. You do not have to use require, however. Just make sure your app js file is included in the config file if the app is reasonably small.

In unit tests, we test model, controller or business logic. We do not test views, since they tend to change quite often and we try to keep them dumb, without any aditional logic.

However, we employ CLI (node.js) selenium integration test based on auQuery and wd.js and a bit of a custom glue code that wraps mocha functions so that the selenium calls runs in fibers and all feels more synchronous. We wrote this, before wd.js introduced mocha support and promise chains. If we were about to start integration tests, we would probably go with wd.js as it is now.


#7

What I’m taking away from this is that testing Ember apps is still the wild west. No one has settled on one way that seems to work the best. It’s all about using what you like, and making it work with a little glue here, an adapter there.

Thanks for the feedback everyone. I’d love even more too if you’re interested.


#8

Yeah, that’s my impression after scouring the internet which is unfortunate imho given how important testing is and how great the rest of the standards are in Ember. Perhaps there are just too many combinations to cover at the moment and the community has to offer some guidance. I am going to try a Teaspoon + Mocha mix myself. I will blog about it and report back here if successful.


#9

Just wanted to follow up with a method to unit test Handlebars Helpers. Given a helper like this

Ember.Handlebars.registerBoundHelper('emailLink', function(email) {
    // Make sure this is not empty before creating
    if (email !== '') {
        var link = '<a href="mailto:%@1">%@1</a>';
        return new Handlebars.SafeString(link.fmt(email));
    } else {
        return '';
    }
});

Your test might look like this:

var email = 'amatthews@myemma.com',
    rendered = Ember.Handlebars.helpers.emailLink._rawFunction(email).string,
    expected = '<a href="mailto:amatthews@myemma.com">amatthews@myemma.com</a>';

expect( rendered ).to.eql(expected);

The rawFunction property is the trick. Call your helper by name, then reference it’s rawFunction property as the base function. Test as desired.


#10

teddy zeeny has an ember-mocha-adapter where all you need to do is drop it in your test setup. Right now I’m pushing for supporting mocha out of the box with ember-cli. I definitely don’t want to keep using qunit, so I’ll get around to a pull request this weekend. If I take too long, and someone else wants to do it , I’ll help.


#11

If anyone is curious about incorporating Mocha into EAK, I’ve forked the Todos sample app to use Mocha. It wasn’t a seemless process and I had to make a few (minor) changes to Teddy Zeeny’s Ember-mocha-adapter to get things working. Specifically, I needed to add the QUnit interface to get it working with the existing test helpers. More details available in the pull request.

The big target for me is properly porting ember-qunit to Mocha. If that can happen, then incorporating it back into ember-cli should be a fairly simple process. This is something I’ll probably get to eventually, but I’d be more than happy to help if anyone wants start the process.

My primary motivation was decoupling Ember from QUnit on principle. I don’t like QUnit (style, functionality, website), but I’m more interested in modularizing testing like they’ve modularized preprocessors (CoffeeScript, LESS, SASS, etc.).


#12

Do you know if anyone is using jasmine? I’d really prefer to use that… I like the rspec-style expects format and qunit isn’t doing it for me at all at the moment: I need the multi-level grouping of describe and it blocks.

Trouble is, I could only find one person who had attempted an adapter, and I don’t think it works with Jasmine 2 which is what I’ve got installed. Maybe I’ll switch back to Jasmine 1.x… unsure :S

edit: turns out it does work with Jasmine 2. Now if I can just get jasmine-jquery working, too :wink:


#13

I’ve seen it but usually its something pretty custom and running on top of Rails/Django/etc. There’s this addon if you wanna use it, https://github.com/square/qunit-bdd, though I really haven’t yet.


#14

Yeah, I’m working on Rails. Ah I got it working :slight_smile: Yeah the syntax is identical to qunit-bdd, except that it says before/afterEach instead of before/after, and it has a bunch more matchers which are really nice. I can’t seem to get them to work right now, though.


#15

I’m also interested in unit testing Ember with mocha however I’m interested in two specific things I dont see mentioned too much:

  1. testing ember modules in isolation, separate from an ember app
  2. testing ember modules in the command line (avoiding browser reporters like QUnit or headless browsers like PhantomJS)

We already have nice integration and acceptance tests, using browsers and/or headless browsers like phantom and karma but I’m looking to beef up unit tests where possible.

Has anyone else come up with similar test structures?


#16

I’m using Karma in conjunction with Jasmine and it’s working wonderfully…command-line with zombie browsers.


#17

@samdelagarza are you still using Jasmine with a current version of Ember (>= 1.11)?