Unit testing Ember apps without unit testing Ember

We are currently in the process of enhancing the testing documentation on the Ember guide. Below is a list of tests that we are in the process of writing (see https://github.com/emberjs/website/pull/1401). I want to make sure that the tests we write are actually testing implementation and not Ember itself.

Components

  • Testing functions
  • Testing with context
  • Testing with provided templates
  • Testing interaction (click/etc)

Handlebars Helpers

  • Testing unbound helpers
  • Testing bound helpers

Controllers

Routes

  • Testing functions
  • Testing actions
  • Testing different callbacks (beforeModel/afterModel/etc)

Views

  • Testing functions
  • Testing computed properties
  • Testing rendered content (template)
  • Testing interaction (click/etc)

Models (Ember Data)

  • Testing functions
  • Testing computed properties
  • Testing needs/belongsTo

Are there any tests that we are missing?

2 Likes

I don’t see much value in testing normal properties on a model, but I do think testing computed properties has value. It’s essentially a utility function and that’s a great candidate for testing.

Components

should test

Handlebars Helpers

should test

Controllers

should test, but I’m wondering how, and what it would look like

Routes

should test, but I’m curious what the benefit would be

Views

should test

Models (Ember Data)

should test. Computed properties are the best target, but even checking normal properties might be good…if only to make sure they don’t get changed for some reason.

I think the fullName example is still valuable. The test ensures the fullName property will be what you expect in the future, so if someone removes or changes the behavior they will be guided by a test failure to find what its real implementation should be and if it is really needed anymore.

The fullName example is pretty simple so I can understand why not writing a test seems lovely, but I don’t think it holds up for all uses of a computed property. Sometimes you really do want to test that behavior for your future self. That kind of unit test is also extremely cheap to write and still provides a fair amount of value, in my opinion.

I don’t think it’s constructive to have should/should not lists of what to test. In my experience, these kind of discussions have often derailed. Maybe a better question would be to find out what kind of tests people want to write for each layer of abstraction.

@cavneb we’re not testing that the computed property works, but that the result of that computed property came out as expected. Ember doesn’t know anything about First and Last names, right? It’s a solid test.

@fivetanley @ulisesrmzroche @commadelimited you have all pointed out my folly. I guess that test would be a valid one. I will revise the topic to reflect what @fivetanley said and make it a question of what kind of tests people want to write for each layer of abstraction.

You should be testing everything with logic in it though. Throw input, check output. And if we’re doing strict TDD, then everything would be tested anyway.

If Ember makes it so easy to test these things, then @ulisesrmzroche is right. Test everything and be done with it. Really when it comes down to it you’re always testing the framework/language…at least in part. You’re expecting it to do what it says it will do.

@fivetanley @ulisesrmzroche @commadelimited @sivakumar0182 @raytiley I have revised the topic to be more helpful to our end goal.

One place that seems like it could use some recommended best practices is how/what to test around relationships in Ember Data. I think many people would start by setting up some Post and Comment objects in the fixture adapter and making sure that post.get('comments') returns the right thing. That is definitely testing Ember and Ember Data more than the application logic. We may want to encourage people to just test that their relationship exists, and to trust that Ember Data is tested to fulfill the relationships.

test('profile relationship', function() {
  var relationships = Ember.get(App.User, 'relationships');
  deepEqual(relationships.get(App.Profile), [
    { name: "profile", kind: "belongsTo" }
  ]);
});

http://jsbin.com/zoxoz/1/edit

Does this seem like a reasonable suggestion to make?

UPDATE: Btw, this has already been added to the WIP testing models page (https://github.com/cavneb/website/blob/testing-redux/source/guides/testing/testing-models.md), I’m just curious to hear thoughts from others on this particular point. Specifically, are the times when you actually need to exercise the whole relationship chain to properly test your own code, or is it always/usually sufficient to just check for the existence of the relationship?

1 Like

I found that testing custom Adapters (for Ember Data) is be pretty hard and would appreciate some help with that.

My rule of thumb has always been this:

If a someFunction.toString().match(/something/) is as good a test as what I’m writing, I don’t need this test.

2 Likes

@cavneb Something that’s bitten us in the past is having a relationship in a Model be async vs non-async. It’s currently possible to test for that flag right now. Is there value in testing for that?

@commadelimited what if someone new to your team comes in and changes that setting? That should break a lot of other things in your app too, not just relationships. This now involves time. (sync vs async). Better to have a test that makes sure it’s always set to either or rather than having to hunt a lot of edgecases that may occur because someone pulled the switch.

Like we shouldn’t be testing the code that puts together the relationship, (this should be tested on ember’s side) but you should be testing the design and logic in your app. (customizations to your ember app)

as for me list you provided more than enough. Can’t wait such guide.

We do have some unit test and what was really difficult for me is to find out how to instantiate Ember objects in isolation (which you should do for unit testing). For each type (view, controller, route) it was a really hard to find out. For example who could ever guess that you have to configure container with optionsForType() before registering any template…

Need a place to vent and this seems as good as any…

I’m trying to be a responsible developer and test everything I write, but I’m getting beat down and I’m starting to really consider moving to Angular.

As a basic example, I’m trying to test an attribute in an Ember-Data model that uses a custom transform I’ve written (a simple array transform).

I’m using Ember-CLI and import my model using the sanctioned moduleForModule method, but the minute I try to do something simple like myModel.toJSON() I’m greeted with an: Assertion Failed: Unable to find transform for 'string'.

Great, so now I need to start thinking about dependencies and exactly which parts of Ember I need to import in order to test my model attribute. Once I’ve followed the debugger chain and figured out exactly what I need, now it’s a question of how to actually get all that stuff registered into the __container__ properly so that it worked properly…

In short, this is a nightmare. I just want to test a basic get/set attribute on my model.

/rant

1 Like

ya, unit testing models is basically not easy/possible without helpers. This is do to some questionable choices. As time permits this will become better.

Until then, we have created lovely test helpers to bootstrap these models for you.

https://github.com/switchfly/ember-test-helpers which is bundled with ember-cli as ember-qunit.

Unfortunately, their are still some deficiencies. I have suggested a potential short-term way forward here: https://github.com/rwjblue/ember-qunit/issues/108

Maybe you can take a look and leave some constructive thoughts there.

Just to follow up – my post was written during a moment of intense frustration and looking back, was probably due to my inexperience with the framework. I’ve been feeling really positive about testing with Ember for awhile now :blush:

I just watched this after going to an ember meetup and having it recommended

Learned a lot about tdd in ember.