Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testing - The Next Frontier
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Robert Jackson
March 10, 2016
Programming
120
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testing - The Next Frontier
Talk given at the Boston Ember meetup on 2016-03-10.
Robert Jackson
March 10, 2016
More Decks by Robert Jackson
See All by Robert Jackson
😂 of TypeScript
rwjblue
0
370
Testing: The Modern Way
rwjblue
0
87
Glimmer ✨ as a Gateway to Ember 🐹
rwjblue
0
96
Testing: The Future... Today?
rwjblue
0
92
Rails Developer's Intro to Ember
rwjblue
1
210
A tale of two pods
rwjblue
3
900
Ember 2.0 - RFC Recap
rwjblue
6
710
Ember CLI Addons
rwjblue
7
830
RAILS + EMBER.JS + EMBER-CLI = ❤
rwjblue
10
1.9k
Other Decks in Programming
See All in Programming
その節約、円になってますか?
isamumumu
1
700
What's New in Android 2026
veronikapj
0
250
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
160
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
490
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
670
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
180
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.5k
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
140
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
120
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
480
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
730
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
610
Featured
See All Featured
Mobile First: as difficult as doing things right
swwweet
225
10k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
Building an army of robots
kneath
306
46k
Amusing Abliteration
ianozsvald
1
240
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Claude Code のすすめ
schroneko
67
230k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
260
How GitHub (no longer) Works
holman
316
150k
4 Signs Your Business is Dying
shpigford
187
22k
sira's awesome portfolio website redesign presentation
elsirapls
0
320
Transcript
Testing: The Next Frontier?
None
Who the heck is this guy? • Ember Core Team
• Twitch • General Open Source Addict twitter: rwjblue github: rwjblue
Thank You!!
What are we talking about?
State of Testing Today • Acceptance • Integration • Unit
Acceptance moduleForAcceptance('Acceptance | login'); test('visiting /login', function(assert) { visit('/login'); andThen(function()
{ assert.equal(currentURL(), '/login'); }); });
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'); });
Unit moduleFor('route:application'); test('perform the right query', function(assert) { let route
= this.subject(); let result = route._queryString(); assert.equal(result, '?awesome=sauce'); });
Great, :shipit:
The End
Seriously?
• Built for a globals world. • “magic” `andThen` •
No ability to stub/mock services. Acceptance Test Issues
None
• Completely ignorant about async • Manual triggering of user
interaction • Much less “tailored” API Unit/Integration Test Issues
None
Now what?
emberjs/rfcs#119
• Use `async` / `await` • Consistent interface • Extendability
• Backwards Compatibility Grand Testing Unification
None
None
None
Acceptance moduleForAcceptance('Can see things'); test('clicking redirects', async function(assert) { await
visit('/things'); let list = find('.thing-item'); assert.equal(list.length, 5); await click('.thing-item[data-id=1]'); assert.equal(this.currentRouteName, 'other- thing'); });
Integration moduleForIntegration('post-display'); test('expand when clicked', async function(assert) { await render(hbs`{{post-display}}`);
await click('.post-item'); assert.equal( this.find('.post-created-at').textContent, '2016-01-05' ); });
• Overriding a service • Registering custom test helpers •
Registering custom waiters • Accessing service instances General Testing Concerns
• Hooks for work before/after tests. • Accessing general test
information General Testing Concerns
Overriding a Service import Mock from 'somewhere/else'; moduleForAcceptance('something', { beforeEach()
{ this.owner.register('service:stripe', Mock); } });
Registering Custom Helpers import selectCategory from '../helpers/select-category'; import loginAsAdmin from
'../helpers/login-as-admin'; moduleForAcceptance('Can see things', { beforeEach() { this.registerHelpers({ loginAsAdmin, selectCategory }); } });
Custom Helpers // tests/helpers/login-as-admin'; import { testHelper } from 'ember-qunit';
export default testHelper(async function() { await this.click('.login-now'); await this.fillIn('.username', 'rwjblue'); await this.fillIn('.password', 'moar beerz plz'); await this.click('.submit'); });
Custom Helpers import selectCategory from '../helpers/select-category'; import loginAsAdmin from '../helpers/login-as-admin';
moduleForAcceptance('Can see things', { beforeEach() { this.registerHelpers({ loginAsAdmin, selectCategory }); } });
Custom Waiters import { testWaiter } from 'ember-test-helpers'; import {
hasPendingTransactions } from 'app- name/services/transactions'; export default testWaiter(function() { return hasPendingTransactions(); });
Custom Waiters import transactionWaiter from '../waiters/pending-transactions'; test('stuff happens', async function(assert)
{ // Normally done in setup, but slides.... this.registerWaiter(transactionWaiter); await click('.foo'); // all pending transactions are completed here... });
Accessing Services test('foo', function(assert) { this.store = this.owner.lookup('service:store'); this.store.push(....); });
General Hooks // */tests/configuration.js import { TestConfig } from 'ember-test-helpers';
export default class extends TestConfig { beforeSuite() {} beforeEach(testType, testContext) {} afterEach(testType, testContext) {} }
General Hooks // liquid-fire's addon-test-support/configuration.js import { TestConfig } from
'ember-test-helpers'; import runningTransitionWaiter from './waiters/running-transition'; import randoHelper from './helpers/rando'; export default class extends TestConfig { beforeEach() { this.registerWaiter(runningTransitionWaiter); this.registerHelper('randoHelper', randoHelper); } }
General Hooks // mirage's addon-test-support/configuration.js import { TestConfig } from
'ember-test-helpers'; import setup from 'ember-cli-mirage/setup-server'; export default class extends TestConfiguration { beforeEach() { this.server = setup(this.owner); } }
Test Information import { testHelper } from 'ember-qunit'; export default
testHelper(function() { if (this.testInfo.type === 'acceptance') { // acceptance test stuff here } else { // integration/unit test stuff here } });
The End