Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Unit Testing JavaScript Applications
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Stephen Thomas
February 09, 2014
Technology
3k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Unit Testing JavaScript Applications
Video of presentation at
http://www.infoq.com/presentations/tdd-javascript
Stephen Thomas
February 09, 2014
More Decks by Stephen Thomas
See All by Stephen Thomas
Sepsis
sathomas
0
110
Leave No One Behind
sathomas
0
130
Introducing D3.js
sathomas
0
2.5k
Building JavaScript Visualizations Part 1
sathomas
1
2.7k
Building JavaScript Visualizations Part 2
sathomas
0
2.6k
Securing JavaScript Web Applications
sathomas
4
440
Web-Based Visualizations with D3.js
sathomas
8
860
Custom Domains with Github Pages
sathomas
2
330
Other Decks in Technology
See All in Technology
JAWS-UGグッズ職人仕事の流儀
kentapapa
0
120
AI コーディングと人間の認知スループット / CTO Night & Day 2026 Morning Session / AI Coding and Human Cognitive Throughput
prog893
5
1.3k
Code for Security プロジェクト紹介 2026年10月
yu23ki14
0
110
"優秀な誰か"の下位互換にならないために
yut0naga1_fa
1
1.8k
AIがコードを書く時代に、エンジニアは何で自分の価値を証明するのか / In an era where AI writes code how do engineers prove their value
carta_engineering
3
1.1k
自作バイナリを動かす「入口」8選
puhitaku
2
1.3k
Metadata - Section 1: HTML Basics
mohab1
0
130
「エーアイ」をバズワードにしないために RPA 導入経験と Kiro 上での Claude モデル利用経験から
kazzpapa3
0
100
パスキーの自動テストはどこまでいけるのか
teamlab
PRO
0
290
Post AI時代のリファクタリング実践記 / Refactoring in the post AI era
kaminashi
1
300
20261017福岡devIO 「AIは"良いダッシュボード"を作れるか?
jtakeda
0
190
Browser Spec: Testing Hotwire with Ruby
takahashim
1
130
Featured
See All Featured
Building the Perfect Custom Keyboard
takai
2
910
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Test your architecture with Archunit
thirion
2
2.4k
GraphQLとの向き合い方2022年版
quramy
50
15k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
270
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
280
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
440
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
570
How STYLIGHT went responsive
nonsquared
100
6.3k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
300
How to Talk to Developers About Accessibility
jct
2
580
Transcript
http://github.com/sathomas/jsunittest
[email protected]
icon-comment-alt icon-comments icon-comments-alt icon-credit-card icon-dashboard icon-download icon-download-alt icon-edit
icon-envelope icon-envelope-alt icon-leaf icon-legal icon-lemon icon-lock icon-unlock icon-magic icon-magnet icon-map-marker icon-minus icon-minus-sign icon-resize-vertica icon-retweet icon-road icon-rss icon-screenshot icon-search icon-share icon-share-alt icon-shopping-car http://speakerdeck.com/sathomas Directional Icons icon-arrow-down icon-arrow-left icon-arrow-right icon-arrow-up icon-chevron-down icon-circle-arrow-down icon-circle-arrow-left icon-circle-arrow-right icon-circle-arrow-up icon-chevron-left icon-car icon-car icon-car icon-car icon-ch Video Player Icons icon-play-circle icon-play icon-step-backward icon-fast-backward icon-fas icon-ste Unit Testing JavaScript Applications Stephen Thomas
Finding Bugs is a Bitch!
What If We Could “Childproof” Our Code?
Continuous Test Driven Development Block bugs from getting into our
code at all.
1. Frictionless testing during development 2. Re-use of tests for
integration 3. Coverage reports
1. Frictionless testing during development 2. Re-use of tests for
integration 3. Coverage reports Test’Em: Test Development Environment Mocha+: Command line execution Blanket.js: Coverage analysis
Example Application
1. Test Development Environment
Test’Em Configuration { "framework": "mocha", "src_files": [ "node_modules/jquery/dist/jquery.js", "node_modules/underscore/underscore.js", "node_modules/backbone/backbone.js",
"node_modules/chai/chai.js", "node_modules/sinon/pkg/sinon.js", "src/*.js", "test/*.js" ] }
Test Driven Development 1. Write a Test 2. Verify That
It Fails 3. Make It Pass 4. Repeat As Necessary
First Test describe("Application", function(){ it("creates global variable…", function(){ should.exist(todoApp); })
})
Passing Code if (typeof todoApp === "undefined") { todoApp =
{}; }
None
None
None
Testing a Model describe("Todo Model", function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo
= new todoApp.Todo(); }) it("should default status…", function(){ this.todo.get('complete').should.be.false; }) it("should default title…", function(){ this.todo.get('title').should.equal(""); }) }) …
Make The Tests Pass todoApp.Todo = Backbone.Model.extend({ defaults: { title:
"", complete: false } })
Testing a View describe("Todo List Item View", function(){ beforeEach(function(){ this.todo
= new todoApp.Todo({ title: "Todo"}); this.item = new todoApp.TodoListItem({ model: this.todo}); }) it("render() should return view", function(){ this.item.render().should.equal(this.item); }); it("should render as list item", function(){ this.item.render() .el.nodeName.should.equal("LI"); })
Stubs describe("Todo Model", function(){ describe("Attributes", function(){ beforeEach(function(){ this.todo = new
todoApp.Todo(); this.stb = sinon.stub(this.todo,"save"); }) afterEach(function(){ this.stb.restore(); }) it(“should set title attr…", function(){ this.todo.set('title',"Test"); this.todo.get('title') .should.equal("Test"); })
Mocking a REST API describe("REST API", function(){ it("should load via
the API", function(){ this.ajax = sinon.stub($,"ajax") .yieldsTo("success", [ {id:1, title:"Mock1", complete:false} ]); this.todos = new todoApp.Todos(); this.todos.fetch(); this.todos.should.have.length(1); this.todos.at(0).get('title') .should.equal("Mock1"); this.ajax.restore(); }) })
Mocha Tip #1: Never “Comment Out” a Test describe("Todo Model",
function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it("should default…", function(){ this.todo.get('complete').should.be.false; })
Mocha Tip #1: Never “Comment Out” a Test describe("Todo Model",
function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it.skip("should default…", function(){ this.todo.get('complete').should.be.false; })
Mocha Tip #1: Never “Comment Out” a Test describe("Todo Model",
function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it.skip("should default…", function(){ this.todo.get('complete').should.be.false; })
None
Mocha Tip #1b: Skip an Entire Test Block describe.skip("Todo Model",
function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it("should default…", function(){ this.todo.get('complete').should.be.false; })
Mocha Tip #2: Focus on a Single Test describe("Todo Model",
function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it.only("should default…", function(){ this.todo.get('complete').should.be.false; })
2. Command-Line Test Execution
Test Code Setup if (typeof exports !== 'undefined' && this.exports
!== exports) { var jsdom = require("jsdom").jsdom; var doc=jsdom("<html><body></body></html>"); var window = doc.createWindow(); var $ = require("jquery")(window); global._ = require("underscore"); global.Backbone = require("backbone"); Backbone.$ = $; var chai = require("chai"); var sinon = require("sinon"); }
Mocha Options: mocha.opts test/app-todos-test.js src/app-todos.js
Run Mocha
3. Test Coverage
Install Blanket.js
Generate Coverage Report
None
None
Resources • Test Development Environment Test’em: https://github.com/airportyh/testem • Command Line
JavaScript Execution Environment node.js: http://nodejs.org • JavaScript Unit Testing Framework Mocha: http://visionmedia.github.io/mocha/ • JavaScript Assertion Library Chai: http://chaijs.com • Spies, Stubs, and Mocks Sinon.JS: http://sinonjs.org • Test Coverage Blanket.js: http://blanketjs.org