1 |
|
2 | Migration Guide
|
3 | ==============================================================================
|
4 |
|
5 | Migrating to native TypeScript support in v6.1.0
|
6 | ------------------------------------------------------------------------------
|
7 |
|
8 | The types for the QUnit `TestContext` provided by the `ember-qunit` and `@ember/test-helpers` types on DefinitelyTyped made a choice to prioritize convenience over robustness when it came to what methods and values were available on `this` in any given test: they made *all* methods availabe regardless of what your setup actually involved. For example, this totally invalid code would have passed the type checker:
|
9 |
|
10 | ```ts
|
11 | import { module, test } from 'qunit';
|
12 | import { setupTest } from 'ember-qunit';
|
13 | import { hbs } from 'ember-cli-htmlbars';
|
14 |
|
15 | module('bad times', function (hooks) {
|
16 | setupTest(hooks);
|
17 |
|
18 | test('this will not *run* correctly', async function (assert) {
|
19 | await this.render(hbs`<p>whoopsie</p>`);
|
20 | });
|
21 | })
|
22 | ```
|
23 |
|
24 | To resolve this, you need to explicitly specify what `this` is for different kinds of tests:
|
25 |
|
26 | ```ts
|
27 | import { module, test } from 'qunit';
|
28 | import { setupTest } from 'ember-qunit';
|
29 | import type { RenderingTextContext } from '@ember/test-helpers';
|
30 | import { hbs } from 'ember-cli-htmlbars';
|
31 |
|
32 | module('better times', function (hooks) {
|
33 | setupTest(hooks);
|
34 |
|
35 | test(
|
36 | 'this will not *run* correctly',
|
37 | async function (this: RenderingTextContext, assert) {
|
38 | await this.render(hbs`<p>whoopsie</p>`);
|
39 | }
|
40 | );
|
41 | })
|
42 | ```
|
43 |
|
44 | While annoying, this is accurate and prevents the annoying mismatch. Combined with support for using local scope with `<template>` (see [Ember RFC 0785][rfc-0785]), available since v2.8 of `@ember/test-helpers`, the need to specify the `this` will go away entirely over time.
|
45 |
|
46 | [rfc-0785]: https://rfcs.emberjs.com/id/0785-remove-set-get-in-tests
|
47 |
|
48 | To use these public types, you also will need to add `@glimmer/interfaces` and `@glimmer/reference` to your `devDependencies`, since of `@ember/test-helpers` uses them (indirectly) in its public APIs, and `ember-qunit` uses `@ember/test-helpers` in turn.
|
49 |
|
50 |
|
51 | Upgrading from v4.x to v5.0.0
|
52 | ------------------------------------------------------------------------------
|
53 |
|
54 | `ember-qunit` had a few major changes that affects apps when migrating from v4.x to v5:
|
55 |
|
56 | * Require the application to have a `qunit` and `@ember/test-helpers` dependency of some sort
|
57 | * Require the QUnit and `@ember/test-helpers` DOM fixtures to be added to the applications `tests/index.html`
|
58 | * Require the application to have `ember-auto-import`
|
59 | * Dropped support for usage of `ember-test-helpers` imports
|
60 | * Dropped support for `moduleFor*` APIs
|
61 | * Drop support for older Node versions (8, 9, 11, 13)
|
62 | * Remove re-exports of QUnit functions from `ember-qunit`
|
63 | * Drop support for usage with Ember older than 3.8
|
64 |
|
65 | ### `qunit` and `@ember/test-helpers` dependencies
|
66 |
|
67 | Older versions of `ember-qunit` directly depended on `qunit` and
|
68 | `@ember/test-helpers`. In v5, this relationship was changed and now
|
69 | `ember-qunit` has `qunit` and `@ember/test-helpers` (v2) as peer dependencies.
|
70 |
|
71 | In order to accomodate this change, in your application, you can run:
|
72 |
|
73 | ```sh
|
74 | # npm users
|
75 | npm install --save-dev qunit "@ember/test-helpers"
|
76 |
|
77 | # yarn users
|
78 | yarn add --dev qunit "@ember/test-helpers"
|
79 | ```
|
80 |
|
81 | ### DOM fixtures
|
82 |
|
83 | In v5 `ember-qunit` moved from automatically providing the testing DOM fixtures to requiring that
|
84 | the host application provide them itself.
|
85 |
|
86 | In order to accomodate this change in your application add the following
|
87 | snippet to your `tests/index.html` just after your `{{content-for
|
88 | "test-body"}}` entry:
|
89 |
|
90 | ```html
|
91 | <div id="qunit"></div>
|
92 | <div id="qunit-fixture">
|
93 | <div id="ember-testing-container">
|
94 | <div id="ember-testing"></div>
|
95 | </div>
|
96 | </div>
|
97 | ```
|
98 |
|
99 | ### QUnit DOM
|
100 |
|
101 | If you use QUnit DOM, you may encounter the error message `assert.dom is not a function` when you run tests.
|
102 |
|
103 | To address this issue, import and run QUnit DOM's `setup` function in your `test-helper.js` file:
|
104 |
|
105 | ```javascript
|
106 | // tests/test-helper.js
|
107 | import * as QUnit from 'qunit';
|
108 | import { setup } from 'qunit-dom';
|
109 |
|
110 | //...
|
111 |
|
112 | setup(QUnit.assert);
|
113 |
|
114 | setApplication(Application.create(config.APP));
|
115 |
|
116 | start();
|
117 |
|
118 | //...
|
119 | ```
|
120 |
|
121 | **Note**: Only make this change when you've updated your version of `ember-qunit` to a `5.x.x` version. Doing so pre-emptively will result in errors trying to import `setup`.
|
122 |
|
123 | ### Remove `ember-test-helpers` modules
|
124 |
|
125 | For a long time `@ember/test-helpers` re-exported all of its modules under the `ember-test-helpers` namespace,
|
126 | in v5 of `ember-qunit` (which requires `@ember/test-helpers@2.0.0`) those re-exports are removed.
|
127 |
|
128 | For the most part, you can migrate any `ember-test-helpers` imports to `@ember/test-helpers`.
|
129 |
|
130 | ### Migrating from `moduleFor*` APIs
|
131 |
|
132 | This section provides instruction for upgrading your test suite from the
|
133 | [Legacy APIs](legacy.md) to Ember's latest testing APIs based on RFCs
|
134 | [232](https://github.com/emberjs/rfcs/blob/master/text/0232-simplify-qunit-testing-api.md)
|
135 | and
|
136 | [268](https://github.com/emberjs/rfcs/blob/master/text/0268-acceptance-testing-refactor.md).
|
137 |
|
138 | For the complete introduction to the new testing APIs, please read the
|
139 | latest [Ember Guides](https://guides.emberjs.com/release/testing/). The
|
140 | following examples will give you an overview how to migrate your existing Ember
|
141 | QUnit based test suite.
|
142 |
|
143 | #### Unit tests
|
144 |
|
145 | Before:
|
146 |
|
147 | ```javascript
|
148 | import { test, moduleFor } from 'ember-qunit';
|
149 |
|
150 | moduleFor('controller:sidebar', 'SidebarController', {
|
151 | // Specify the other units that are required for this test.
|
152 | // needs: ['controller:foo']
|
153 | });
|
154 |
|
155 | // Replace this with your real tests.
|
156 | test('exists', function(assert) {
|
157 | let controller = this.subject();
|
158 | assert.ok(controller);
|
159 | });
|
160 | ```
|
161 |
|
162 | After:
|
163 |
|
164 | ```javascript
|
165 | import { module, test } from 'qunit';
|
166 | import { setupTest } from 'ember-qunit';
|
167 |
|
168 | module('SidebarController', function(hooks) {
|
169 | setupTest(hooks);
|
170 |
|
171 | // Replace this with your real tests.
|
172 | test('exists', function(assert) {
|
173 | let controller = this.owner.lookup('controller:sidebar');
|
174 | assert.ok(controller);
|
175 | });
|
176 | });
|
177 | ```
|
178 |
|
179 | ##### Migration steps
|
180 |
|
181 | * Use `module` and `test` imported from `qunit` directly
|
182 | * Use `setupTest()` instead of `moduleFor()`
|
183 | * Use the Owner object given by `this.owner` directly instead of `this.subject()`
|
184 |
|
185 | You can use the
|
186 | [ember-qunit-codemod](https://github.com/rwjblue/ember-qunit-codemod)
|
187 | to update your test code automatically.
|
188 |
|
189 | #### Component tests
|
190 |
|
191 | Before:
|
192 |
|
193 | ```javascript
|
194 | import { test, moduleForComponent } from 'ember-qunit';
|
195 | import hbs from 'htmlbars-inline-precompile';
|
196 |
|
197 | moduleForComponent('GravatarImageComponent', {
|
198 | integration: true
|
199 | });
|
200 |
|
201 | test('it renders', function(assert) {
|
202 | this.render(hbs`{{gravatar-image}}`);
|
203 | assert.equal(this.$('img').length, 1);
|
204 | });
|
205 | ```
|
206 |
|
207 | After:
|
208 |
|
209 | ```javascript
|
210 | import { module, test } from 'qunit';
|
211 | import { setupRenderingTest } from 'ember-qunit';
|
212 | import { render } from '@ember/test-helpers';
|
213 | import hbs from 'htmlbars-inline-precompile';
|
214 |
|
215 | module('GravatarImageComponent', function(hooks) {
|
216 | setupRenderingTest(hooks);
|
217 |
|
218 | test('renders', async function(assert) {
|
219 | await render(hbs`{{gravatar-image}}`);
|
220 | assert.ok(this.element.querySelector('img'));
|
221 | });
|
222 | });
|
223 | ```
|
224 |
|
225 | ##### Migration steps
|
226 |
|
227 | * Use `module` and `test` imported from `qunit` directly
|
228 | * Use `setupRenderingTest()` instead of `moduleForComponent()`
|
229 | * Render using the `render()` helper from `@ember/test-helpers` instead of
|
230 | `this.render()`
|
231 | * `render()` is now always an async call, so use `async`/`await` to wait for it
|
232 | to complete
|
233 | * Use `this.element` to get access to the rendered DOM
|
234 | * Do not use jQuery for DOM interaction, instead use the
|
235 | [DOM Interaction Helpers](https://github.com/emberjs/ember-test-helpers/blob/master/API.md#dom-interaction-helpers)
|
236 | from `@ember/test-helpers`
|
237 |
|
238 | You can use the
|
239 | [ember-qunit-codemod](https://github.com/rwjblue/ember-qunit-codemod)
|
240 | to update your test setup code automatically.
|
241 |
|
242 | For migrating to the DOM interaction helpers, you can use the
|
243 | [ember-test-helpers-codemod](https://github.com/simonihmig/ember-test-helpers-codemod)
|
244 | to automatically convert all or most of it.
|
245 |
|
246 | #### Acceptance tests
|
247 |
|
248 | Before:
|
249 |
|
250 | ```javascript
|
251 |
|
252 | import { test } from 'qunit';
|
253 | import moduleForAcceptance from 'app/tests/helpers/module-for-acceptance';
|
254 |
|
255 | moduleForAcceptance('basic acceptance test');
|
256 |
|
257 | test('can visit /', function() {
|
258 | visit('/');
|
259 |
|
260 | andThen(() => {
|
261 | assert.equal(currentURL(), '/');
|
262 | });
|
263 | });
|
264 | ```
|
265 |
|
266 | After:
|
267 |
|
268 |
|
269 | ```javascript
|
270 | import { module, test } from 'qunit';
|
271 | import { setupApplicationTest } from 'ember-qunit';
|
272 | import { visit, currentURL } from '@ember/test-helpers';
|
273 |
|
274 | module('basic acceptance test', function(hooks) {
|
275 | setupApplicationTest(hooks);
|
276 |
|
277 | test('can visit /', async function(assert) {
|
278 | await visit('/');
|
279 | assert.equal(currentURL(), '/');
|
280 | });
|
281 | });
|
282 | ```
|
283 |
|
284 | ##### Migration steps
|
285 |
|
286 | * Use `module` and `test` imported from `qunit` directly
|
287 | * Use `setupApplicationTest()` instead of `moduleForAcceptance()` or `beforeEach`/`afterEach` hooks for setting up the
|
288 | application
|
289 | * Use the [Routing Helpers](https://github.com/emberjs/ember-test-helpers/blob/master/API.md#routing-helpers)
|
290 | from `@ember/test-helpers` instead of the global helpers, e.g. `visit`
|
291 | * Do not use the "global" test helpers for DOM interaction, instead use the
|
292 | [DOM Interaction Helpers](https://github.com/emberjs/ember-test-helpers/blob/master/API.md#dom-interaction-helpers)
|
293 | from `@ember/test-helpers`
|
294 | * use `async`/`await` to wait for asynchronous operations like `visit()` or
|
295 | `click()`
|
296 | * use `this.element` to get access to the rendered DOM
|
297 |
|
298 | You can use the
|
299 | [ember-qunit-codemod](https://github.com/rwjblue/ember-qunit-codemod)
|
300 | to update your test setup code automatically.
|
301 |
|
302 | For migrating from the global test helpers to those proved by
|
303 | `@ember/test-helpers`, you can use the
|
304 | [ember-test-helpers-codemod](https://github.com/simonihmig/ember-test-helpers-codemod)
|
305 | to assist you with that task.
|
306 |
|
307 | ###### Caveats
|
308 |
|
309 | * As of ember-cli-qunit@4.1.0 / ember-qunit@3.0.0, `Ember.testing` is only set tor `true` during the test run. Previously it was always set to `true`. For more information see https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/no-ember-testing-in-module-scope.md
|