SlideShare a Scribd company logo
UNIT TESTING 
FRONT END 
JAVASCRIPT 
YURI TAKHTEYEV 
@QARAMAZOV 
@RANGLEIO
Why Bother with Unit Tests?
Why Bother with Unit Tests?
TDD Lite
Writing Testable Code 
☛ Modular 
code 
☛ AngularJS 
services 
☛ Other 
modules not 
entangled 
with DOM
Keeping Tests Simple
Common Tools 
Runner: Karma 
Task Automation: Gulp || Grunt 
Scorer: Mocha || Jasmine 
Assertions: Chai || Jasmine 
Spies: Sinon || Jasmin 
+ CI tools (e.g. Magnum-CI)
http://yto.io/xunit
Installing the Example Code 
# First install 
git clone https://github.com/yuri/webu-unit.git 
cd webu-unit 
npm install 
sudo npm install -g gulp 
sudo npm install -g bower 
bower install 
# Now run 
gulp karma 
☛ You’ll need to install git and node before
A Basic Test 
function isOdd(value) { 
return (value % 2 === 1); 
} 
describe('isEven', function () { 
it('should handle positive ints', function () { 
if (isOdd(2)) { 
throw new Error('2 should be even'); 
} 
}); 
}); 
☛ Let’s put this in “client/app/is-odd.test.js”
Chai 
describe('isEven', function () { 
it('should handle positive ints', function () { 
expect(isOdd(1)).to.be.true; 
expect(isOdd(2)).to.be.false; 
expect(isOdd(3)).to.be.true; 
}); 
}); 
☛ More Chai at http://chaijs.com/api/bdd/
Extending Tests 
describe('isEven', function () { 
... 
it('should handle negative ints', function () { 
expect(isOdd(-1)).to.be.true; 
}); 
});
Extending Tests 
describe('isEven', function () { 
... 
xit('should handle negative ints', function () { 
expect(isOdd(-1)).to.be.true; 
}); 
});
Extending Tests 
describe('isEven', function () { 
... 
it.only('should handle negative ints', 
function () { 
expect(isOdd(-1)).to.be.true; 
}); 
});
Extending Tests 
describe('isEven', function () { 
... 
it('should handle negative ints', function () { 
expect(isOdd(-1)).to.be.true; 
}); 
}); 
function isOdd(value) { 
return (value % 2 === 1); 
}
Testing a Service 
angular.module('app.tasks', [ 
'app.server' 
]) 
.factory('tasks', function(server) { 
var service = {}; 
service.getTasks = function () { 
return server.get('tasks'); 
}; 
return service; 
}); 
☛ Let’s put this in “client/app/tasks-service.js”
The Test, Take 1 
describe('tasks service', function () { 
beforeEach(module('app.tasks')); 
it('should get tasks', function() { 
var tasks = getService('tasks'); 
expect(tasks.getTasks()).to 
.not.be.undefined; 
}); 
}); 
☛ Let’s put this in “client/app/tasks-service.test.js” 
☛ See “client/testing/test-utils.js” for 
implementation of getService(). 
Error: [$injector:unpr] Unknown provider: 
serverProvider <- server <- tasks
Mocking Dependencies 
var data; 
beforeEach(module(function($provide){ 
$provide.service('server', function() { 
return { 
get: function() { 
return Q.when(data); 
} 
}; 
}); 
$provide.service('$q', function() { 
return Q; 
}); 
})); 
Chrome 37.0.2062 (Mac OS X 10.9.4): Executed 3 of 
3 SUCCESS (0.046 secs / 0.027 secs)
Let’s Extend the Service 
service.getMyTasks = function () { 
return server.getTasks() 
.then(function(taskArray) { 
return _.filter(taskArray, function(task) { 
return task.owner === user.userName; 
}); 
}); 
}; 
☛ We’ll need to inject “user” into the service
Mocking the User 
$provide.service('user', function() { 
return { 
username: 'yuri' 
}; 
}); 
☛ The mock can be very simple
An Async Test, Wrong 
it('should get user's tasks', function() { 
var tasks = getService('tasks'); 
data = [{ 
owner: 'bob', 
description: 'Mow the lawn' 
}, { 
owner: 'yuri', 
description: 'Save the world' 
}]; 
tasks.getMyTasks() 
.then(function(myTasks) { 
expect(myTasks.length).to.equal(1); 
}); 
}); 
☛ Always check that “wrong” tests fail!
An Async Test, Right 
it('should get user's tasks', function() { 
var tasks = getService('tasks'); 
data = [{ 
owner: 'bob', 
description: 'Mow the lawn' 
}, { 
owner: 'yuri', 
description: 'Save the world' 
}]; 
return tasks.getMyTasks() 
.then(function(myTasks) { 
expect(myTasks.length).to.equal(1); 
}); 
});
Spies with Sinon 
$provide.service('server', function() { 
return { 
get: sinon.spy(function() { 
return Q.when(data); 
}) 
}; 
}); 
var server = getService('server'); 
return tasks.getMyTasks() 
.then(function(myTasks) { 
expect(myTasks.length).to.equal(1); 
server.get.should.have.been.calledOnce; 
});
Thank You. 
Contact: 
yuri@rangle.io 
http://yto.io 
@qaramazov 
This presentation: 
http://yto.io/xunit
Image Credits 
by dunechaser 
by lincolnblues 
by spenceyc 
by creative_tools 
by mycroyance 
by angeljimenez 
by snre

More Related Content

PPT
AngularJS Testing Strategies
PDF
Redux Sagas - React Alicante
PPTX
React hooks
PPTX
The redux saga begins
PDF
activity_and_fragment_may_2020_lakopi
ODP
Angular JS Unit Testing - Overview
PDF
The evolution of redux action creators
PDF
Redux saga: managing your side effects. Also: generators in es6
AngularJS Testing Strategies
Redux Sagas - React Alicante
React hooks
The redux saga begins
activity_and_fragment_may_2020_lakopi
Angular JS Unit Testing - Overview
The evolution of redux action creators
Redux saga: managing your side effects. Also: generators in es6

What's hot (20)

PDF
Testing AngularJS
PDF
Workshop 23: ReactJS, React & Redux testing
PDF
React new features and intro to Hooks
PPTX
LinkedIn TBC JavaScript 100: Functions
PDF
Functional Core, Reactive Shell
PPTX
Firebase ng2 zurich
PPTX
Typescript barcelona
PDF
UI 모듈화로 워라밸 지키기
PPTX
Full Stack Unit Testing
PDF
Understanding react hooks
PDF
Stop Making Excuses and Start Testing Your JavaScript
PPTX
Testing in airflow
PPTX
Rxjs swetugg
PDF
Unit Testing Express and Koa Middleware in ES2015
PDF
Martin Anderson - threads v actors
PPTX
Avoiding callback hell in Node js using promises
PPTX
Javascript: master this
PDF
Cocoa heads 09112017
PDF
Douglas Crockford: Serversideness
PDF
JavaScript Functions
Testing AngularJS
Workshop 23: ReactJS, React & Redux testing
React new features and intro to Hooks
LinkedIn TBC JavaScript 100: Functions
Functional Core, Reactive Shell
Firebase ng2 zurich
Typescript barcelona
UI 모듈화로 워라밸 지키기
Full Stack Unit Testing
Understanding react hooks
Stop Making Excuses and Start Testing Your JavaScript
Testing in airflow
Rxjs swetugg
Unit Testing Express and Koa Middleware in ES2015
Martin Anderson - threads v actors
Avoiding callback hell in Node js using promises
Javascript: master this
Cocoa heads 09112017
Douglas Crockford: Serversideness
JavaScript Functions
Ad

Viewers also liked (20)

ZIP
Automated Frontend Testing
PDF
Front-End Testing: Demystified
PDF
Cats, Dinosaurs and A Lot of Pizza with Reed + Rader
PDF
(Re)aligning The Way 400,000 People Think
PDF
A New Era for Animators
PDF
Managing The Process
PDF
Components are the Future of the Web: It’s Going To Be Okay
PDF
The Browser Is Dead, Long Live The Web!
PDF
Getting to Know Grunt By Writing Your Own Plugin
PDF
It’s the Experience That Makes the Product, Not the Features
PDF
Front-end Tools: Sifting Through the Madness
PDF
Designing True Cross-Platform Apps
PDF
Graphic Designer to Object Designer: Your 3D Printing Evolution
PDF
Upgrading the Web with Douglas Crockford @ FITC's Web Unleashed 2015
PPTX
Improving Game Performance in the Browser
PDF
5 Things Every Designer Should be Doing Right Now
PDF
Functional Web Development
PPTX
Pocket web gl sk
PDF
Designing Interactive Experiences for Kids of All Ages with Mark Argo
PDF
Kickstarting Your Stupid Magazine
Automated Frontend Testing
Front-End Testing: Demystified
Cats, Dinosaurs and A Lot of Pizza with Reed + Rader
(Re)aligning The Way 400,000 People Think
A New Era for Animators
Managing The Process
Components are the Future of the Web: It’s Going To Be Okay
The Browser Is Dead, Long Live The Web!
Getting to Know Grunt By Writing Your Own Plugin
It’s the Experience That Makes the Product, Not the Features
Front-end Tools: Sifting Through the Madness
Designing True Cross-Platform Apps
Graphic Designer to Object Designer: Your 3D Printing Evolution
Upgrading the Web with Douglas Crockford @ FITC's Web Unleashed 2015
Improving Game Performance in the Browser
5 Things Every Designer Should be Doing Right Now
Functional Web Development
Pocket web gl sk
Designing Interactive Experiences for Kids of All Ages with Mark Argo
Kickstarting Your Stupid Magazine
Ad

Similar to Unit Testing Front End JavaScript (20)

PDF
Testing, Performance Analysis, and jQuery 1.4
PDF
Angular testing
PDF
Describe's Full of It's
PPT
An Introduction to AngularJs Unittesting
PPTX
The next step, part 2
PDF
Understanding JavaScript Testing
PDF
Test-Driven Development of AngularJS Applications
PPT
25-functions.ppt
PDF
Angularjs Test Driven Development (TDD)
PDF
Promises are so passé - Tim Perry - Codemotion Milan 2016
PDF
Node Anti-Patterns and Bad Practices
PPTX
TDD & BDD
PDF
Reliable Javascript
PDF
To Err Is Human
PDF
Testing in JavaScript
KEY
jQuery Bay Area Conference 2010
PPTX
Best practices unit testing
DOCX
C-Sharp Arithmatic Expression Calculator
PDF
Test driven node.js
PDF
Unit testing with mocha
Testing, Performance Analysis, and jQuery 1.4
Angular testing
Describe's Full of It's
An Introduction to AngularJs Unittesting
The next step, part 2
Understanding JavaScript Testing
Test-Driven Development of AngularJS Applications
25-functions.ppt
Angularjs Test Driven Development (TDD)
Promises are so passé - Tim Perry - Codemotion Milan 2016
Node Anti-Patterns and Bad Practices
TDD & BDD
Reliable Javascript
To Err Is Human
Testing in JavaScript
jQuery Bay Area Conference 2010
Best practices unit testing
C-Sharp Arithmatic Expression Calculator
Test driven node.js
Unit testing with mocha

More from FITC (20)

PPTX
Cut it up
PDF
Designing for Digital Health
PDF
Profiling JavaScript Performance
PPTX
Surviving Your Tech Stack
PDF
How to Pitch Your First AR Project
PDF
Start by Understanding the Problem, Not by Delivering the Answer
PDF
Cocaine to Carrots: The Art of Telling Someone Else’s Story
PDF
Everyday Innovation
PDF
HyperLight Websites
PDF
Everything is Terrifying
PDF
Post-Earth Visions: Designing for Space and the Future Human
PDF
The Rise of the Creative Social Influencer (and How to Become One)
PDF
East of the Rockies: Developing an AR Game
PDF
Creating a Proactive Healthcare System
PDF
World Transformation: The Secret Agenda of Product Design
PDF
The Power of Now
PDF
High Performance PWAs
PDF
Rise of the JAMstack
PDF
From Closed to Open: A Journey of Self Discovery
PDF
Projects Ain’t Nobody Got Time For
Cut it up
Designing for Digital Health
Profiling JavaScript Performance
Surviving Your Tech Stack
How to Pitch Your First AR Project
Start by Understanding the Problem, Not by Delivering the Answer
Cocaine to Carrots: The Art of Telling Someone Else’s Story
Everyday Innovation
HyperLight Websites
Everything is Terrifying
Post-Earth Visions: Designing for Space and the Future Human
The Rise of the Creative Social Influencer (and How to Become One)
East of the Rockies: Developing an AR Game
Creating a Proactive Healthcare System
World Transformation: The Secret Agenda of Product Design
The Power of Now
High Performance PWAs
Rise of the JAMstack
From Closed to Open: A Journey of Self Discovery
Projects Ain’t Nobody Got Time For

Recently uploaded (20)

PDF
Triggering QUIC, presented by Geoff Huston at IETF 123
PDF
Slides PDF The World Game (s) Eco Economic Epochs.pdf
PPTX
innovation process that make everything different.pptx
PPTX
522797556-Unit-2-Temperature-measurement-1-1.pptx
PDF
Sims 4 Historia para lo sims 4 para jugar
PPTX
INTERNET------BASICS-------UPDATED PPT PRESENTATION
PPTX
Digital Literacy And Online Safety on internet
PDF
Paper PDF World Game (s) Great Redesign.pdf
PDF
RPKI Status Update, presented by Makito Lay at IDNOG 10
PDF
Tenda Login Guide: Access Your Router in 5 Easy Steps
PDF
Vigrab.top – Online Tool for Downloading and Converting Social Media Videos a...
PDF
WebRTC in SignalWire - troubleshooting media negotiation
PPTX
Module 1 - Cyber Law and Ethics 101.pptx
PDF
APNIC Update, presented at PHNOG 2025 by Shane Hermoso
PDF
Best Practices for Testing and Debugging Shopify Third-Party API Integrations...
PPTX
durere- in cancer tu ttresjjnklj gfrrjnrs mhugyfrd
PPTX
Introduction about ICD -10 and ICD11 on 5.8.25.pptx
PPTX
Job_Card_System_Styled_lorem_ipsum_.pptx
PDF
Behind the Smile Unmasking Ken Childs and the Quiet Trail of Deceit Left in H...
PDF
LABUAN4D EXCLUSIVE SERVER STAR GAMING ASIA NO.1
Triggering QUIC, presented by Geoff Huston at IETF 123
Slides PDF The World Game (s) Eco Economic Epochs.pdf
innovation process that make everything different.pptx
522797556-Unit-2-Temperature-measurement-1-1.pptx
Sims 4 Historia para lo sims 4 para jugar
INTERNET------BASICS-------UPDATED PPT PRESENTATION
Digital Literacy And Online Safety on internet
Paper PDF World Game (s) Great Redesign.pdf
RPKI Status Update, presented by Makito Lay at IDNOG 10
Tenda Login Guide: Access Your Router in 5 Easy Steps
Vigrab.top – Online Tool for Downloading and Converting Social Media Videos a...
WebRTC in SignalWire - troubleshooting media negotiation
Module 1 - Cyber Law and Ethics 101.pptx
APNIC Update, presented at PHNOG 2025 by Shane Hermoso
Best Practices for Testing and Debugging Shopify Third-Party API Integrations...
durere- in cancer tu ttresjjnklj gfrrjnrs mhugyfrd
Introduction about ICD -10 and ICD11 on 5.8.25.pptx
Job_Card_System_Styled_lorem_ipsum_.pptx
Behind the Smile Unmasking Ken Childs and the Quiet Trail of Deceit Left in H...
LABUAN4D EXCLUSIVE SERVER STAR GAMING ASIA NO.1

Unit Testing Front End JavaScript

  • 1. UNIT TESTING FRONT END JAVASCRIPT YURI TAKHTEYEV @QARAMAZOV @RANGLEIO
  • 2. Why Bother with Unit Tests?
  • 3. Why Bother with Unit Tests?
  • 5. Writing Testable Code ☛ Modular code ☛ AngularJS services ☛ Other modules not entangled with DOM
  • 7. Common Tools Runner: Karma Task Automation: Gulp || Grunt Scorer: Mocha || Jasmine Assertions: Chai || Jasmine Spies: Sinon || Jasmin + CI tools (e.g. Magnum-CI)
  • 9. Installing the Example Code # First install git clone https://github.com/yuri/webu-unit.git cd webu-unit npm install sudo npm install -g gulp sudo npm install -g bower bower install # Now run gulp karma ☛ You’ll need to install git and node before
  • 10. A Basic Test function isOdd(value) { return (value % 2 === 1); } describe('isEven', function () { it('should handle positive ints', function () { if (isOdd(2)) { throw new Error('2 should be even'); } }); }); ☛ Let’s put this in “client/app/is-odd.test.js”
  • 11. Chai describe('isEven', function () { it('should handle positive ints', function () { expect(isOdd(1)).to.be.true; expect(isOdd(2)).to.be.false; expect(isOdd(3)).to.be.true; }); }); ☛ More Chai at http://chaijs.com/api/bdd/
  • 12. Extending Tests describe('isEven', function () { ... it('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; }); });
  • 13. Extending Tests describe('isEven', function () { ... xit('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; }); });
  • 14. Extending Tests describe('isEven', function () { ... it.only('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; }); });
  • 15. Extending Tests describe('isEven', function () { ... it('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; }); }); function isOdd(value) { return (value % 2 === 1); }
  • 16. Testing a Service angular.module('app.tasks', [ 'app.server' ]) .factory('tasks', function(server) { var service = {}; service.getTasks = function () { return server.get('tasks'); }; return service; }); ☛ Let’s put this in “client/app/tasks-service.js”
  • 17. The Test, Take 1 describe('tasks service', function () { beforeEach(module('app.tasks')); it('should get tasks', function() { var tasks = getService('tasks'); expect(tasks.getTasks()).to .not.be.undefined; }); }); ☛ Let’s put this in “client/app/tasks-service.test.js” ☛ See “client/testing/test-utils.js” for implementation of getService(). Error: [$injector:unpr] Unknown provider: serverProvider <- server <- tasks
  • 18. Mocking Dependencies var data; beforeEach(module(function($provide){ $provide.service('server', function() { return { get: function() { return Q.when(data); } }; }); $provide.service('$q', function() { return Q; }); })); Chrome 37.0.2062 (Mac OS X 10.9.4): Executed 3 of 3 SUCCESS (0.046 secs / 0.027 secs)
  • 19. Let’s Extend the Service service.getMyTasks = function () { return server.getTasks() .then(function(taskArray) { return _.filter(taskArray, function(task) { return task.owner === user.userName; }); }); }; ☛ We’ll need to inject “user” into the service
  • 20. Mocking the User $provide.service('user', function() { return { username: 'yuri' }; }); ☛ The mock can be very simple
  • 21. An Async Test, Wrong it('should get user's tasks', function() { var tasks = getService('tasks'); data = [{ owner: 'bob', description: 'Mow the lawn' }, { owner: 'yuri', description: 'Save the world' }]; tasks.getMyTasks() .then(function(myTasks) { expect(myTasks.length).to.equal(1); }); }); ☛ Always check that “wrong” tests fail!
  • 22. An Async Test, Right it('should get user's tasks', function() { var tasks = getService('tasks'); data = [{ owner: 'bob', description: 'Mow the lawn' }, { owner: 'yuri', description: 'Save the world' }]; return tasks.getMyTasks() .then(function(myTasks) { expect(myTasks.length).to.equal(1); }); });
  • 23. Spies with Sinon $provide.service('server', function() { return { get: sinon.spy(function() { return Q.when(data); }) }; }); var server = getService('server'); return tasks.getMyTasks() .then(function(myTasks) { expect(myTasks.length).to.equal(1); server.get.should.have.been.calledOnce; });
  • 24. Thank You. Contact: [email protected] http://yto.io @qaramazov This presentation: http://yto.io/xunit
  • 25. Image Credits by dunechaser by lincolnblues by spenceyc by creative_tools by mycroyance by angeljimenez by snre