SlideShare a Scribd company logo
1 of 26
Download to read offline
Writing testable JS
by Ted Piotrowski
Javascript Ho Chi Minh City
Excuses for not testing
● I know the code
● Test suite is hard to configure and run
● You can’t test UI
● You can’t unit test JS code
$(document).ready(function() {
$('#new-status form').submit(function(e) {
e.preventDefault();
$.ajax({
url: '/status',
type: 'POST',
dataType: 'json',
data: { text: $('#new-status').find('textarea').val() },
success: function(data) {
$('#statuses').append('<li>' + data.text + '</li>');
$('#new-status').find('textarea').val('');
}
});
});
});
source: https://github.com/kjbekkelund/writings/blob/master/published/understanding-backbone.md/
Documentation
● Impossible to write a good test without a
good specification
● If you don’t have time to write a test, at least
write documentation
○ it will allow others to write tests later
/**
* adds two numbers together
*/
function sum(a, b)
assert(sum(1, 2), 3);
/**
* adds two numbers together
*/
function sum(a, b)
assert(sum(1, ‘a’), ?);
/**
* adds two numbers together,
* otherwise returns null
*/
function sum(a, b)
assert(sum(1, ‘a’), null);
Dependencies
● Can’t write good tests unless you
understand what external objects the code
depends on
● loose coupling
● use requirejs, almond.js, squire.js
● move dependencies up the call stack and
inject
Scope
● An assertion should only rely on the method
being tested
● What is a “unit”?
● is $(function() { }) a unit?
// Should we stub addTwo, addOne?
// When we limit scope, we forfeit integration
function addThree(a) {
var x = addTwo(a);
var y = addOne(x);
return y;
}
Testing with the DOM
● Use a DOM fragment / jQuery fragment
● Inject it into the module constructor
function Word() {
this.el = $('.word'); // external dependency
}
Word.prototype.setText = function(text) {
this.el.text(text);
};
var word = new Word();
word.setText('Hello World');
assert(???, 'Hello World');
function Word(el) {
this.el = el; // dependency injection
}
Word.prototype.setText = function(text) {
this.el.text(text);
};
var mockEl = $('<div></div>'); // use a test double
var word = new Word(mockEl); // inject the dependency
word.setText('Hello World');
assert(mockEl.text(), 'Hello World');
function Word(el) {
this.el = el || $('.word'); // optional injection
}
Word.prototype.setText = function(text) {
this.el.text(text);
};
var mockEl = $('<div></div>');
var word = new Word(mockEl);
word.setText('Hello World');
assert(mockEl.text(), 'Hello World');
Dealing with window properties
● You code will likely touch Web API
○ document, Math,
● Can use mocks and stubs for methods
● Many Web API properties are read-only
// If your production code calls alert(), you can mock it
var spy = sinon.spy(window, "alert");
assert(spy.calledWith("My alert message"));
// However, you can't modify read only properties
Math.PI = 3.15; // won’t work
window.History.length = 12;
function Win(windowObj) {
this.window = windowObj || window;
}
Win.prototype.scrollX = function() { return this.window.scrollX };
Win.prototype.scrollY = function() { return this.window.scrollY };
var win = new Win(); // in production
// win.scrollX() => actual value
var win = new Win({ // in testing
scrollX: 50, scrollY: 40, History: { … }
}); // win.scrollX() => 50
Dealing with network calls
● Use sinon fake server
{
"test should fetch comments from server" : function () {
this.server.respondWith("GET", "/some/article/comments.json",
[200, { "Content-Type": "application/json" },
'[{ "id": 12, "comment": "Hey there" }]']);
var callback = sinon.spy();
myLib.getCommentsFor("/some/article", callback);
this.server.respond();
sinon.assert.calledWith(callback, [{ id: 12, comment: "Hey there" }]));
}
}
Code coverage
● Reports what lines of production JS are
executed during testing
● necessary, but not sufficient
● Istanbul is a good tool
○ integrates with Karma
JS integration tests
● main.js file initializes your components and
injects DOM dependencies
● Stub your REST calls
● Just like unit testing, user events are your
input, DOM changes are your output
// Bootstrap your application here
// Inject your DOM dependencies at top of call stack
// Allows you to mock/stub the DOM for each component
$(function() {
var $el = $('.some-element');
var component = new Component($el);
var $el2 = $('.some-element2');
var component2 = new Component($el2);
// initialize more components, global state here
});
Demo time
More information
● Testable Javascript
● Karma test runner
● Sinon.js
● Istanbul
About us
Author: Ted Piotrowski
Find me at: tpiotrowski@atlassian.com
Sample code: https://bitbucket.org/tpiotrowski/js-hcm
Presentation made for Javascript Ho Chi Minh City Meetup Group
You can find us at:
● http://www.meetup.com/JavaScript-Ho-Chi-Minh-City/
● https://www.facebook.com/JavaScriptHCMC
● https://plus.google.com/u/0/communities/116105314977285194967
● http://www.slideshare.net/JavascriptMeetup
Lean Coffee
Discussion topics

More Related Content

What's hot

What's hot (20)

jQuery Bay Area Conference 2010
jQuery Bay Area Conference 2010jQuery Bay Area Conference 2010
jQuery Bay Area Conference 2010
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JS
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
AngularJS $Provide Service
AngularJS $Provide ServiceAngularJS $Provide Service
AngularJS $Provide Service
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
 
AngularJS Services
AngularJS ServicesAngularJS Services
AngularJS Services
 
10 tips for a reusable architecture
10 tips for a reusable architecture10 tips for a reusable architecture
10 tips for a reusable architecture
 
Angular js - 4developers 12 kwietnia 2013
Angular js - 4developers 12 kwietnia 2013Angular js - 4developers 12 kwietnia 2013
Angular js - 4developers 12 kwietnia 2013
 
AngularJS Basics with Example
AngularJS Basics with ExampleAngularJS Basics with Example
AngularJS Basics with Example
 
Angular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.xAngular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.x
 
Async js - Nemetschek Presentaion @ HackBulgaria
Async js - Nemetschek Presentaion @ HackBulgariaAsync js - Nemetschek Presentaion @ HackBulgaria
Async js - Nemetschek Presentaion @ HackBulgaria
 
Modules and injector
Modules and injectorModules and injector
Modules and injector
 
AngularJS Animations
AngularJS AnimationsAngularJS Animations
AngularJS Animations
 
AngularJs
AngularJsAngularJs
AngularJs
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte I
 
Angularjs Basics
Angularjs BasicsAngularjs Basics
Angularjs Basics
 
Human Talks - StencilJS
Human Talks - StencilJSHuman Talks - StencilJS
Human Talks - StencilJS
 
AngulrJS Overview
AngulrJS OverviewAngulrJS Overview
AngulrJS Overview
 
Обзор автоматизации тестирования на JavaScript
Обзор автоматизации тестирования на JavaScriptОбзор автоматизации тестирования на JavaScript
Обзор автоматизации тестирования на JavaScript
 
Testing JavaScript with Jasmine in Rails Applications
Testing JavaScript with Jasmine in Rails Applications Testing JavaScript with Jasmine in Rails Applications
Testing JavaScript with Jasmine in Rails Applications
 

Similar to Writing testable js [by Ted Piotrowski]

the next web now
the next web nowthe next web now
the next web now
zulin Gu
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
Chris Saylor
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
wpnepal
 
Automated javascript unit testing
Automated javascript unit testingAutomated javascript unit testing
Automated javascript unit testing
ryan_chambers
 
Ajax Basics 2
Ajax Basics 2Ajax Basics 2
Ajax Basics 2
bhuvanann
 

Similar to Writing testable js [by Ted Piotrowski] (20)

Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascript
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
 
the next web now
the next web nowthe next web now
the next web now
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sites
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
Testing javascript in the frontend
Testing javascript in the frontendTesting javascript in the frontend
Testing javascript in the frontend
 
Testing in JavaScript
Testing in JavaScriptTesting in JavaScript
Testing in JavaScript
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
Sqladria 2009 SRC
Sqladria 2009 SRCSqladria 2009 SRC
Sqladria 2009 SRC
 
Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJS
 
JavaScript straight from the Oracle Database
JavaScript straight from the Oracle DatabaseJavaScript straight from the Oracle Database
JavaScript straight from the Oracle Database
 
Automated javascript unit testing
Automated javascript unit testingAutomated javascript unit testing
Automated javascript unit testing
 
Ajax Basics 2
Ajax Basics 2Ajax Basics 2
Ajax Basics 2
 

More from JavaScript Meetup HCMC

3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
JavaScript Meetup HCMC
 

More from JavaScript Meetup HCMC (8)

Building workflow in Javascript: Build the awesome with Gulp.
Building workflow in Javascript: Build the awesome with Gulp.   Building workflow in Javascript: Build the awesome with Gulp.
Building workflow in Javascript: Build the awesome with Gulp.
 
[Js hcm] Java script- Testing the awesome
[Js hcm] Java script- Testing the awesome[Js hcm] Java script- Testing the awesome
[Js hcm] Java script- Testing the awesome
 
Knockout js (Dennis Haney)
Knockout js (Dennis Haney)Knockout js (Dennis Haney)
Knockout js (Dennis Haney)
 
Debugging JavaScript (by Thomas Bindzus, Founder, Vinagility & Thanh Loc Vo, ...
Debugging JavaScript (by Thomas Bindzus, Founder, Vinagility & Thanh Loc Vo, ...Debugging JavaScript (by Thomas Bindzus, Founder, Vinagility & Thanh Loc Vo, ...
Debugging JavaScript (by Thomas Bindzus, Founder, Vinagility & Thanh Loc Vo, ...
 
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
 
Nicolas Embleton, Advanced Angular JS
Nicolas Embleton, Advanced Angular JSNicolas Embleton, Advanced Angular JS
Nicolas Embleton, Advanced Angular JS
 
Khanh-Nguyen - Gearman - distributed process solution
Khanh-Nguyen - Gearman - distributed process solutionKhanh-Nguyen - Gearman - distributed process solution
Khanh-Nguyen - Gearman - distributed process solution
 
Nicolas-Embleton - Deploying node.js with forever and nginx
Nicolas-Embleton  - Deploying node.js with forever and nginxNicolas-Embleton  - Deploying node.js with forever and nginx
Nicolas-Embleton - Deploying node.js with forever and nginx
 

Recently uploaded

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

Writing testable js [by Ted Piotrowski]

  • 1. Writing testable JS by Ted Piotrowski Javascript Ho Chi Minh City
  • 2. Excuses for not testing ● I know the code ● Test suite is hard to configure and run ● You can’t test UI ● You can’t unit test JS code
  • 3. $(document).ready(function() { $('#new-status form').submit(function(e) { e.preventDefault(); $.ajax({ url: '/status', type: 'POST', dataType: 'json', data: { text: $('#new-status').find('textarea').val() }, success: function(data) { $('#statuses').append('<li>' + data.text + '</li>'); $('#new-status').find('textarea').val(''); } }); }); }); source: https://github.com/kjbekkelund/writings/blob/master/published/understanding-backbone.md/
  • 4. Documentation ● Impossible to write a good test without a good specification ● If you don’t have time to write a test, at least write documentation ○ it will allow others to write tests later
  • 5. /** * adds two numbers together */ function sum(a, b) assert(sum(1, 2), 3);
  • 6. /** * adds two numbers together */ function sum(a, b) assert(sum(1, ‘a’), ?);
  • 7. /** * adds two numbers together, * otherwise returns null */ function sum(a, b) assert(sum(1, ‘a’), null);
  • 8. Dependencies ● Can’t write good tests unless you understand what external objects the code depends on ● loose coupling ● use requirejs, almond.js, squire.js ● move dependencies up the call stack and inject
  • 9. Scope ● An assertion should only rely on the method being tested ● What is a “unit”? ● is $(function() { }) a unit?
  • 10. // Should we stub addTwo, addOne? // When we limit scope, we forfeit integration function addThree(a) { var x = addTwo(a); var y = addOne(x); return y; }
  • 11. Testing with the DOM ● Use a DOM fragment / jQuery fragment ● Inject it into the module constructor
  • 12. function Word() { this.el = $('.word'); // external dependency } Word.prototype.setText = function(text) { this.el.text(text); }; var word = new Word(); word.setText('Hello World'); assert(???, 'Hello World');
  • 13. function Word(el) { this.el = el; // dependency injection } Word.prototype.setText = function(text) { this.el.text(text); }; var mockEl = $('<div></div>'); // use a test double var word = new Word(mockEl); // inject the dependency word.setText('Hello World'); assert(mockEl.text(), 'Hello World');
  • 14. function Word(el) { this.el = el || $('.word'); // optional injection } Word.prototype.setText = function(text) { this.el.text(text); }; var mockEl = $('<div></div>'); var word = new Word(mockEl); word.setText('Hello World'); assert(mockEl.text(), 'Hello World');
  • 15. Dealing with window properties ● You code will likely touch Web API ○ document, Math, ● Can use mocks and stubs for methods ● Many Web API properties are read-only
  • 16. // If your production code calls alert(), you can mock it var spy = sinon.spy(window, "alert"); assert(spy.calledWith("My alert message")); // However, you can't modify read only properties Math.PI = 3.15; // won’t work window.History.length = 12;
  • 17. function Win(windowObj) { this.window = windowObj || window; } Win.prototype.scrollX = function() { return this.window.scrollX }; Win.prototype.scrollY = function() { return this.window.scrollY }; var win = new Win(); // in production // win.scrollX() => actual value var win = new Win({ // in testing scrollX: 50, scrollY: 40, History: { … } }); // win.scrollX() => 50
  • 18. Dealing with network calls ● Use sinon fake server
  • 19. { "test should fetch comments from server" : function () { this.server.respondWith("GET", "/some/article/comments.json", [200, { "Content-Type": "application/json" }, '[{ "id": 12, "comment": "Hey there" }]']); var callback = sinon.spy(); myLib.getCommentsFor("/some/article", callback); this.server.respond(); sinon.assert.calledWith(callback, [{ id: 12, comment: "Hey there" }])); } }
  • 20. Code coverage ● Reports what lines of production JS are executed during testing ● necessary, but not sufficient ● Istanbul is a good tool ○ integrates with Karma
  • 21. JS integration tests ● main.js file initializes your components and injects DOM dependencies ● Stub your REST calls ● Just like unit testing, user events are your input, DOM changes are your output
  • 22. // Bootstrap your application here // Inject your DOM dependencies at top of call stack // Allows you to mock/stub the DOM for each component $(function() { var $el = $('.some-element'); var component = new Component($el); var $el2 = $('.some-element2'); var component2 = new Component($el2); // initialize more components, global state here });
  • 24. More information ● Testable Javascript ● Karma test runner ● Sinon.js ● Istanbul
  • 25. About us Author: Ted Piotrowski Find me at: tpiotrowski@atlassian.com Sample code: https://bitbucket.org/tpiotrowski/js-hcm Presentation made for Javascript Ho Chi Minh City Meetup Group You can find us at: ● http://www.meetup.com/JavaScript-Ho-Chi-Minh-City/ ● https://www.facebook.com/JavaScriptHCMC ● https://plus.google.com/u/0/communities/116105314977285194967 ● http://www.slideshare.net/JavascriptMeetup