Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing: The Modern Way

Testing: The Modern Way

Review what's new in testing land for Ember and then dive into examples, both good and bad, to help us level up our Ember tests.

Robert Jackson

April 26, 2018
Tweet

More Decks by Robert Jackson

Other Decks in Programming

Transcript

  1. 4

  2. 6

  3. Integration moduleForComponent('pretty-color', { integration: true }); test('button click', function(assert) {

    this.render(hbs`{{magic-title}}`); this.$('button').click(); assert.equal(this.$().text(), 'This is Magic'); });
  4. Unit moduleFor('route:application'); test('perform the right query', function(assert) { let route

    = this.subject(); let result = route._queryString(); assert.equal(result, '?awesome=sauce'); });
  5. • Built for a globals world. • “magic” `andThen` •

    No ability to stub/mock services. Acceptance Test Issues
  6. • Completely ignorant about async • Manual triggering of user

    interaction • Much less “tailored” API Unit/Integration Test Issues
  7. • Use `async` / `await` • Consistent interface • Extendability

    • Backwards Compatibility Grand Testing Unification
  8. 26 History - Integration moduleForComponent('pretty-color', { integration: true }); test('button

    click', function(assert) { this.render(hbs`{{magic-title}}`); this.$('button').click(); assert.equal(this.$().text(), 'This is Magic'); });
  9. 27 History - Unit moduleFor('route:application'); test('perform the right query', function(assert)

    { let route = this.subject(); let result = route._queryString(); assert.equal(result, '?awesome=sauce'); });
  10. 31

  11. 32 import { setupApplicationTest } from 'ember-qunit'; import { module

    } from 'qunit'; module('Acceptance | login', function(hooks) { setupApplicationTest(hooks); test('visiting /login', async function(assert) { await visit('/login'); assert.equal(currentURL(), '/login'); }); }); Today - Application
  12. 33 Today - Rendering import { module } from 'qunit';

    import { setupRenderingTest } from 'ember-qunit'; import { render, click } from '@ember/test-helpers'; module('pretty-color', function(hooks) { setupRenderingTest(hooks); test('button click', async function(assert) { await render(hbs`{{magic-title}}`); await click('button'); assert.dom().hasText('This is magic'); }); });
  13. 34 Today - Basic import { module } from 'qunit';

    import { setupTest } from 'ember-qunit'; module('route:application', function(hooks) { setupTest(hooks); test('perform the right query', function(assert) { let route = this.owner.lookup('route:application'); let result = route._queryString(); assert.equal(result, '?awesome=sauce'); }); });
  14. 35 Today - Addons import setupMirageTest from 'ember-cli-mirage/test-support/setup-mirage'; // ...snip...

    module('Integration | Component | light table', function(hooks) { setupRenderingTest(hooks); setupMirageTest(hooks); // <-- test('button click', async function(assert) { await render(hbs`{{magic-title}}`); await click('button'); assert.dom().hasText('This is magic'); }); });
  15. 36 Today - Addons import { selectChoose } from 'ember-power-select/test-support';

    // ...snip... module('Integration | Component x-foo', function(hooks) { setupRenderingTest(hooks); test('button click', async function(assert) { await render(hbs`{{x-foo}}`); await selectChoose('.selector', 'Barbaz'); assert.dom().hasText('This is magic'); }); });
  16. 37 Today - Addons import { setupPact, given, interaction }

    from 'ember-cli-pact'; // ...snip… module('Pact | People', function(hooks) { setupTest(hooks); setupPact(hooks, { provider: 'my-api', consumer: 'my-app'}); test('locating a person by ID', async function(assert) { given('a person exists', { id: '123', name: 'Alice' }); let person = await interaction(() => this.store().findRecord('person', '123')); assert.equal(person.get('id'), '123'); assert.equal(person.get('name'), 'Alice'); }); });
  17. 43

  18. 45 for (let i = 0; i < 1000; i++)

    { module('Acceptance | index | ' + i, function(hooks) { setupApplicationTest(hooks); test('visiting /', async function(assert) { await visit('/'); await click('button'); assert.dom('.other-landing').hasText('Landed on other...'); }); }); }
  19. 49

  20. 51

  21. 52

  22. 54 test('shows and hides loading spinner after submit', async function(assert)

    { await visit('/'); click('.submit'); // <-- don't await await waitFor('.loading-spinner'); assert.dom('.loading-spinner').exists(); await settled(); assert.dom('.loading-spinner').doesNotExist(); });
  23. 56 import Resolver from 'my-app/resolver'; import engineResolverFor from 'ember-engines/test-support/engine-resolver-for'; let

    engineResolver = engineResolverFor('the-async-engine'); const resolver = Resolver.extend({ resolve() { let resolved = this._super(...arguments); if (resolved) { return resolved; } return engineResolver.resolve(...arguments); }, }).create();
  24. 58

  25. 60 test('rendering a blog post', async function(assert) { const post

    = this.server.create('post', 'inSomeState'); await Ember.run(async function() { // Must be inside a Run Loop to use the store, abstraction feels really leaky this.set('post', this.store.find('post', post.id); }); await render(hbs` {{blog-post post=post}} `); // Perform some assertion, finally });
  26. 62