Ember 2.x Ember 2.x

Introduction to Testing

This course has been updated! We now recommend you take the Ember Octane Fundamentals course.

Check out a free preview of the full Ember 2.x course:
The "Introduction to Testing" Lesson is part of the full, Ember 2.x course featured in this preview video. Here's what you'd learn in this lesson:

Testing can preformed on a specific algorithm, integration between components, or a user’s workflow through an application. Mike introduces the concept of testing and demonstrates how to run run tests in an Ember application.

Get Unlimited Access Now

Transcript from the "Introduction to Testing" Lesson

>> [MUSIC]

>> Mike North: There are a few flavors of tests that I want us to be on the same page with terminology wise. So unit tests are about testing algorithmic complexity. So if you have like this computer property which we just built which essentially is values in and value out, that is great for a unit test.

[00:00:29] Because you can list a whole bunch of different test cases where you know it's in the array, it's not in the array. Tests that if it's a matching the stringified version of this object is in the array, but it's a different object. It's a different instance of the object.

[00:00:47] Make sure that works as expected. This is a great case for you to test. So integration tests in the context of the Ember they really mean component integration tests. And what integration tests are all about is the points of contact between system components. So this is also a test that will be somewhat in isolation and what that means is when you're testing our GitHub org component.

[00:01:18] The GitHub repo component will actually not be available for you to use in templates unless you specifically say I need this. By default you're sort of in an isolated environment, just trying to reduce the scope of the scenario down to the point where you can test this thing by itself.

[00:01:35] And have the right way of interacting with it to simulate the way you expecting it to be used. Then finally we have acceptance tests, which are the same thing as functional tests. And this is not testing in isolation, this is starting your real application up programmatically rendered in a div as part of the test runner.

[00:01:59] And you're here going to be testing real workflows and clicking on a link and making sure the URL is correct and making sure this is what's on the screen. These are much slower because things really have to render and because JavaScript test. There's just more overhead in starting it up and going through these flows and just more going on.

[00:02:25] But especially when it comes to things like routes which manage transitions between state, this is a great place to get your release confidence. Because it's the whole thing, it's the real deal, it's your application as your users are going to be using it. So I tried to put together a little rule of thumb.

[00:02:49] Which thing to reach for, for a given flavor of Ember object, for a given entity in the Ember framework. So utils, models and services, I tend to test with unit tests and that's because these things can really stand on their own. A model can exist even if there is no adapter and serializer, we'll learn about this when we get to Ember data.

[00:03:12] But utils in our case, it's just a function and you just need the idea of a computer property, potentially just an Ember object, that you create in your test. You don't even need to sense of like having a component or this higher-level constructs. Services again, isolated, very simple objects designed to be used anywhere as a result they can be used anywhere.

[00:03:37] They can be tested anywhere, and they can be tested in isolation. Integration tests were a fairly recent addition. And I should say things were recently improved dramatically when it comes to component integration tests. They are built for components. They can be used for other things. But essentially you provide, the things that you provide to set up a scenario and the ways you have to change the scenario and listen to what's going on and check for the presence of things.

[00:04:09] They lend themselves extremely well to component testing. Routes, I don't even bother with route unit tests. It's possible, but really when it comes to transitioning between applications states, I want to be dealing with my application. It's very hard to test it thoroughly and completely in a valid way that is in alignment with how the app is using a route in a unit test.

[00:04:40] And then ember-data stuff, also deal with that in acceptance tests, and the reason is I wanna see that I've visited a page, that an API request goes out for a particular data. I wanna provide a synthetic payload and like an API response I wanna provide some JSON for that and then see that what I expect to render on the screen is in fact going to be on the screen.

[00:05:05] And so, really you're testing through Ember, through jQuery, all the way down to XML HTTP request. And that is a long chain of things to be able to capture correctness on. And the bottom line is data is driving what's on the screen and you want to see the whole thing percolates all the way up.

[00:05:29] So one nuance about testing has to do with this concept of a run loop. And a run loop is just a prioritize work queue which saves us from the expense of having to update the DOM for example when each and every property change event happens. So in normal mode, we're doing our gets, we're doing our sets, and if in on the JavaScript side of the world.

[00:06:01] You can do a set and then a get immediately following that and the very blossom fact changed. But things that it has been bound to in your templates, those have not changed yet. That happens after each iteration of the run that completes. So, your whole actions If you have a complicated action handload that sets a bunch of stuff up, all of that will take place and then finally, an update to the DOM will happen, all at once, A, B and C.

[00:06:33] That's actually one change but that will be property A, B and C being changed, that's like one efficient DOM update. In testing mode, because you want to, more often than not, make a property change and see that this is on, this is what happened. Make a property change, and see that this is what happened.

[00:06:53] So, we actually have the run loop turned off in Ember testing mode. And what that means is there are certain things like if you want to schedule some work to be done later or you've seen me use ember.run.later when I was delaying promises. That kind of stuff you will need to actually do some extra work to support.

[00:07:17] If that's in your code you need to provide a run loop around your test. Which is not difficult, you just need to be aware of it. But, this is essentially the difference between running your app normally versus in testing mode.
>> Speaker 2: Throttling the same way? Like if you run Throttle.

>> Mike North: Throttle uses the run loop.
>> Mike North: Running tests is quite easy. There are three ways to do it, really three and a half ways. localhost:4200/tests, you will see a queue unit test runner start running through everything. And it's hooked up to live reload of course so you can leave that open and code and save until your tests pass.

[00:08:04] ember test ci will just run your tests in the console and ember test-server, the test runner we have, it's actually testem around q unit. Testem will stay open keep running, and as you make changes it'll rerun. So it's sort of like having your browser open live reload running the tests over and over except it's in the console.

[00:08:32] So I'm actually going to demonstrate what that looks like and I expect we'll have some failing tests because we haven't been paying attention to it, shame on us.
>> Mike North: So, ember test ci, it's going to build the app, and then the output is gonna be essentially a TAP file, which is exactly what you want to feed into something like code climate or whatever.

[00:09:05] And you can see we've got some okay, and then we've got some not okay, so here there's some issue, a lot of JSHint problems. So, the other way of doing it is through the browser.
>> Mike North: And if we go over here. This is probably the more common way to do it.

>> Mike North: Get rid of this. We can hide the past tests which is great for getting rid of the noise. So here, it looks like I've probably got some white space. It's a little bit different between what's expected versus what we're actually seeing. And a lot of this is just sort of the basic auto generated tests no longer fit what my components are doing, right, so Ember CLI, it's helpful and that it gets you started.

[00:10:10] But it expects things to work in a default way and the more you do to actually build your application out, things aren't empty anymore. Things aren't you know, the component has content in it now. And the last way just to show you ember test-server.
>> Mike North: And I'm gonna make this wider so we don't.

>> Mike North: So here, similarly you see that this is continuing to run, and I can go over here and make a change.
>> Mike North: And it just reran. And this is nice so if I was running on five or six different browsers those would be in tabs across the top so you can have like phantom.js running and Chrome and Safari and whatever.

[00:11:07] But this is kind of neat to have up and running if you don't wanna have browser tabs all over the place.
>> Mike North: And hit Q to quit and we're back.