Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unit Testing JavaScript Applications

Stephen Thomas
February 09, 2014

Unit Testing JavaScript Applications

Stephen Thomas

February 09, 2014
Tweet

More Decks by Stephen Thomas

Other Decks in Technology

Transcript

  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. Finding Bugs is a Bitch!

  3. What If We Could “Childproof” Our Code?

  4. Continuous Test Driven Development Block bugs from getting into our

    code at all.
  5. 1. Frictionless testing during development 2. Re-use of tests for

    integration 3. Coverage reports

  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
  7. Example Application

  8. 1. Test Development Environment

  9. 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" ] }
  10. Test Driven Development 1. Write a Test 2. Verify That

    It Fails 3. Make It Pass 4. Repeat As Necessary
  11. First Test describe("Application", function(){ it("creates global variable…", function(){ should.exist(todoApp); })

    })
  12. Passing Code if (typeof todoApp === "undefined") { todoApp =

    {}; }
  13. None
  14. None
  15. None
  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(""); }) }) …
  17. Make The Tests Pass todoApp.Todo = Backbone.Model.extend({ defaults: { title:

    "", complete: false } })
  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"); })
  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"); })
  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(); }) })
  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; })
  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; })
  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; })
  24. None
  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; })
  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; })
  27. 2. Command-Line Test Execution

  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"); }
  29. Mocha Options:
 mocha.opts test/app-todos-test.js src/app-todos.js

  30. Run Mocha

  31. 3. Test Coverage

  32. Install Blanket.js

  33. Generate Coverage Report

  34. None
  35. None
  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