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
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
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
});
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