Unit Testing JavaScript Applications

A5b424d4146905962a24acd6815aeb84?s=47 Stephen Thomas
February 09, 2014

Unit Testing JavaScript Applications

A5b424d4146905962a24acd6815aeb84?s=128

Stephen Thomas

February 09, 2014
Tweet

Transcript

  1. 1.

    http://github.com/sathomas/jsunittest stephen@sathomas.me 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
  2. 6.

    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
  3. 10.

    Test Driven Development 1. Write a Test 2. Verify That

    It Fails 3. Make It Pass 4. Repeat As Necessary
  4. 13.
  5. 14.
  6. 15.
  7. 16.

    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(""); }) }) …
  8. 18.

    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"); })
  9. 19.

    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"); })
  10. 20.

    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(); }) })
  11. 21.

    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; })
  12. 22.

    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; })
  13. 23.

    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; })
  14. 24.
  15. 25.

    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; })
  16. 26.

    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; })
  17. 28.

    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"); }
  18. 30.
  19. 34.
  20. 35.
  21. 36.

    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