Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Docs #320

Merged
merged 4 commits into from
Mar 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
294 changes: 104 additions & 190 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,256 +1,170 @@
# ember-qunit [![Build Status](https://travis-ci.org/emberjs/ember-qunit.svg)](https://travis-ci.org/emberjs/ember-qunit)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the Travis badge here?


Ember QUnit simplifies unit testing of Ember applications with QUnit by
providing QUnit-specific wrappers around the helpers contained in
[ember-test-helpers](https://github.com/emberjs/ember-test-helpers).

## Usage

- [Component Integration Tests](#component-integration-tests)
- [Component Unit Tests](#component-unit-tests)
- [Other Tests](#other-tests)
- [Ember Data Tests](#ember-data-tests)
[![Latest NPM release][npm-badge]][npm-badge-url]
[![TravisCI Build Status][travis-badge]][travis-badge-url]

### Component Integration Tests
[npm-badge]: https://img.shields.io/npm/v/ember-qunit.svg
[npm-badge-url]: https://www.npmjs.com/package/ember-qunit
[travis-badge]: https://img.shields.io/travis/emberjs/ember-qunit/master.svg
[travis-badge-url]: https://travis-ci.org/emberjs/ember-qunit

```js
import hbs from 'htmlbars-inline-precompile';
import { test, moduleForComponent } from 'ember-qunit';

moduleForComponent('x-foo', {
integration: true
});

test('it renders', function(assert) {
assert.expect(2);
ember-qunit simplifies testing of Ember applications with
[QUnit](https://qunitjs.com/) by providing QUnit-specific wrappers around the
helpers contained in
[ember-test-helpers](https://github.com/emberjs/ember-test-helpers).

// setup the outer context
this.set('value', 'cat');
this.on('action', function(result) {
assert.equal(result, 'bar', 'The correct result was returned');
});

// render the component
this.render(hbs`
{{ x-foo value=value action="result" }}
`);
Installation
------------------------------------------------------------------------------

assert.equal(this.$('div>.value').text(), 'cat', 'The component shows the correct value');
`ember-qunit` is an [Ember CLI](http://www.ember-cli.com/) addon, so install it
as you would any other addon:

this.$('button').click();
});
```sh
$ ember install ember-qunit
```

Component integration tests are the default mode for `moduleForComponent`. You can still explicitly activate them by passing `integration: true`.

Integration tests have the advantage of testing your component as Ember would actually use them. It's helpful to think of this mode as simply testing the inputs and outputs of the component. These tests allow you interact with both the bound values that are passed into the component as well as its resulting actions.
Some other addons are detecting the test framework based on the installed
addon names and are expecting `ember-cli-qunit` instead. If you have issues
with this then `ember install ember-cli-qunit`, which should work exactly
the same.

Component integration tests have the following features:
- Your test context `this` acts as the outer context for the component. As a result, you can call `this.set` and `this.on` to setup values and event listeners that you can then have interact with the component.
- You are required to render the component as a template, e.g. ``this.render(hbs`{{ your-component-name value=value action="updated" }}`)``. You can render other components as well as block content.
- All of the normal Ember lifecycle hooks for a component are called (including the new ones from 1.13.x).
- Testing the component's template is through `this.$()`.
- You do not require dependencies through `needs:`. Doing so will force the test into unit mode.
- You do not have direct access to the component instance. (`this.subject()` will raise an exception).

### Component Unit Tests
Usage
------------------------------------------------------------------------------

[Ember Guide](http://guides.emberjs.com/v1.13.0/testing/testing-components/)
The following section describes the use of ember-qunit with the latest modern
Ember testing APIs, as laid out in the RFCs
[232](https://github.com/emberjs/rfcs/blob/master/text/0232-simplify-qunit-testing-api.md)
and
[268](https://github.com/emberjs/rfcs/blob/master/text/0268-acceptance-testing-refactor.md).

```js
import { test, moduleForComponent } from 'ember-qunit';
For the older APIs have a look at our [Legacy Guide](docs/legacy.md).

moduleForComponent('x-foo', {
unit: true,
needs: ['helper:pluralize-string']
});
### Setting the Application

// run a test
test('it renders', function(assert) {
assert.expect(1);
Your `tests/test-helper.js` file should look similar to the following, to
correctly setup the application required by `@ember/test-helpers`:

// creates the component instance
var subject = this.subject();
```javascript
import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';

// render the component on the page
this.render();
assert.equal(this.$('.foo').text(), 'bar');
});
setApplication(Application.create(config.APP));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the start() call is missing here. I removed it from the ember-mocha docs, because there is no for mocha. But this here should match the file from the latest blueprints: https://github.com/ember-cli/ember-cli/blob/master/blueprints/app/files/tests/test-helper.js

```

Unit tests used to be the default mode for component tests. To flag a test as a unit test, either specify `unit: true` or include `needs: []` in the callbacks object.

Unit tests have the advantage of giving you direct access to the component instance so you can test its internals. Unit tests have the following features:
Also make sure that you have set `ENV.APP.autoboot = false;` for the `test`
environment in your `config/environment.js`.

- You have access to the component instance through `this.subject()`.
- If you want to render the component's template, call either `this.render()` or `this.$()`.
- Testing the component's template is through `this.$()`.
- You are required to specify any dependencies other than the component's template in the `needs: []` option. This includes helpers, services, partials, and any other components (with their templates) that are referenced.
- Unit tests do not call most of the Ember lifecycle hooks. `didInsertElement` and `willDestroyElement` will be called, but the remaining hooks introduced in Ember 1.13.x will not be.
- There is no outer context for the component so testing things such as actions will require directly stubbing the actions on the component.
### Setup Tests

### Other Tests
The `setupTest()` function can be used to setup a unit test for any kind
of "module/unit" of your application that can be looked up in a container.

[Controllers Guide](http://guides.emberjs.com/v1.13.0/testing/testing-controllers/)
It will setup your test context with:

[Routes Guide](http://guides.emberjs.com/v1.13.0/testing/testing-routes/)
* `this.owner` to interact with Ember's [Dependency Injection](https://guides.emberjs.com/v3.0.0/applications/dependency-injection/)
system
* `this.set()`, `this.setProperties()`, `this.get()`, and `this.getProperties()`
* `this.pauseTest()` method to allow easy pausing/resuming of tests

```js
import { test, moduleFor } from 'ember-qunit';
For example, the following is a unit test for the `SidebarController`:

moduleFor('controller:home');
```javascript
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';

test('It can calculate the result', function(assert) {
assert.expect(1);
module('SidebarController', function(hooks) {
setupTest(hooks);

var subject = this.subject();

subject.set('value', 'foo');
assert.equal(subject.get('result'), 'bar');
// Replace this with your real tests.
test('exists', function() {
let controller = this.owner.lookup('controller:sidebar');
assert.ok(controller);
});
});
```

`moduleFor` works for any object you could look up with the Ember Resolver (service, routes, controllers, etc.).

Note: Controllers / Routes do not have access to rendering. You will need to either use a component test or an acceptance test.
#### Setup Rendering Tests

### Ember Data Tests
The `setupRenderingTest()` function is specifically designed for tests that
render arbitrary templates, including components and helpers.

[Ember Guide](http://guides.emberjs.com/v1.13.0/testing/testing-models/)
It will setup your test context the same way as `setupTest()`, and additionally:

```js
import { test, moduleForModel } from 'ember-qunit';
* Initializes Ember's renderer to be used with the
[Rendering helpers](https://github.com/emberjs/ember-test-helpers/blob/master/API.md#rendering-helpers),
specifically `render()`
* Adds `this.element` to your test context which returns the DOM element
representing the wrapper around the elements that were rendered via
`render()`
* sets up the [DOM Interaction Helpers](https://github.com/emberjs/ember-test-helpers/blob/master/API.md#dom-interaction-helpers)
from `@ember/test-helpers` (`click()`, `fillIn()`, ...)

moduleForModel('user', {
needs: ['model:child']
});

test('It can set its child', function(assert) {
assert.expect(1);
var subject = this.subject();
```javascript
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

var child = subject.store.createRecord('child');
subject.get('children').pushObject(child);
module('GravatarImageComponent', function(hooks) {
setupRenderingTest(hooks);

assert.equal(subject.get('some-computed-value'), true);
test('renders', async function() {
await render(hbs`{{gravatar-image}}`);
assert.ok(this.element.querySelector('img'));
});
});
```

## Advanced Usage
### Setting the resolver
### Setup Application Tests

```js
// if you don't have a custom resolver, do it like this:
setResolver(Ember.DefaultResolver.create({ namespace: App }));
The `setupApplicationTest()` function can be used to run tests that interact
with the whole application, so in most cases acceptance tests.

// otherwise something like:
import Resolver from './path/to/resolver';
import { setResolver } from 'ember-qunit';
setResolver(Resolver.create());
```
On top of `setupTest()` it will:

### Async Example
* Boot your application instance
* Set up all the [DOM Interaction Helpers](https://github.com/emberjs/ember-test-helpers/blob/master/API.md#dom-interaction-helpers)
(`click()`, `fillIn()`, ...) as well as the [Routing Helpers](https://github.com/emberjs/ember-test-helpers/blob/master/API.md#routing-helpers)
(`visit()`, `currentURL()`, ...) from `@ember/test-helpers`

Under the hood, if you use `Ember.RSVP.Promise`, ember-qunit will call
QUnit's `start` and `stop` helpers to stop the test from tearing down
and running other tests while your asynchronous code runs. ember-qunit
also asserts that the promise gets fulfilled.
```javascript
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { visit, currentURL } from '@ember/test-helpers';

In addition, you can also return promises in the test body:
module('basic acceptance test', function(hooks) {
setupApplicationTest(hooks);

```js
// If you return a promise from a test callback it becomes an asyncTest. This
// is a key difference between ember-qunit and standard QUnit.
test('async is awesome', function(assert) {
assert.expect(1);
var myThing = MyThing.create();
// myThing.exampleMethod() returns a promise
return myThing.exampleMethod().then(function() {
assert.ok(myThing.get('finished'));
test('can visit /', async function() {
await visit('/');
expect(currentURL()).to.equal('/');
});
});
```

If an error is thrown in your promise or a promise
within `test` becomes rejected, ember-qunit will fail the test.
To assert that a promise should be rejected, you can "catch"
the error and assert that you got there:

```js
test('sometimes async gets rejected', function(assert) {
assert.expect(1);
var myThing = MyThing.create()

return myThing.exampleMethod().then(function() {
assert.ok(false, "promise should not be fulfilled");
})['catch'](function(err) {
assert.equal(err.message, "User not Authorized");
});
});
```

## Test Helpers

### `moduleFor(fullName [, description [, callbacks]])`

- `fullName`: (String) - The full name of the unit, ie
`controller:application`, `route:index`.

- `description`: (String) optional - The description of the module

- `callbacks`: (Object) optional
- QUnit callbacks (`beforeEach` and `afterEach`)
- ember-test-helpers callback (`subject`)
- `integration: true` or `unit: true` (default: `integration: true`)
- `needs` specify any dependencies the tested module will require.

### `moduleForComponent(name, [description, callbacks])`

- `name`: (String) - the short name of the component that you'd use in a
template, ie `x-foo`, `ic-tabs`, etc.

- `description`: (String) optional - The description of the module

- `callbacks`: (Object) optional
- QUnit callbacks (`beforeEach` and `afterEach`)
- ember-test-helpers callback (`subject`)
- `integration: true` or `unit: true` (default: `integration: true`)
- `needs` specify any dependencies the tested module will require. (Including this will force your test into unit mode).

### `moduleForModel(name, [description, callbacks])`

- `name`: (String) - the short name of the model you'd use in `store`
operations ie `user`, `assignmentGroup`, etc.

- `description`: (String) optional - The description of the module

- `callbacks`: (Object) optional
- QUnit callbacks (`beforeEach` and `afterEach`)
- ember-test-helpers callback (`subject`)
- `integration: true` or `unit: true` (default: `integration: true`)
- `needs` specify any dependencies the tested module will require.

## Contributing
Contributing
------------------------------------------------------------------------------

### Installation

* `git clone <repository-url>` this repository
* `git clone <repository-url>`
* `cd ember-qunit`
* `npm install`

### Running

* `ember serve`
* Visit your app at [http://localhost:4200](http://localhost:4200).

### Running Tests
### Running tests

* `npm test` (Runs `ember try:each` to test your addon against multiple Ember versions)
* `ember test`
* `ember test --server`

### Building
### Running the dummy application

* `ember build`
* `ember serve`
* Visit the dummy application at [http://localhost:4200](http://localhost:4200).

For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).
Loading