Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

How to write Testable Javascript

688 vues

Publié le

Everyone who wasn't writing JavaScript, probably is now. Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.

That's great, but how do we test it? In ColdFusion we have CFCs, most languages have classes... but JavaScript doesn't have classes (yet).

So how do I write unit tests, what units are there, and how do I make my code look like that? JavaScript is a flexible language, and with great flexibility comes great complexity and responsibility. Take your JavaScript spaghetti and make it unit testable.

Attendees should have some exposure to JavaScript, but this is for the Professional Newbie... who always needs to learn and adapt.

Publié dans : Technologie
  • Soyez le premier à commenter

How to write Testable Javascript

  1. 1. ★How do I write Testable Javascript?
  2. 2. ★Agenda ★Who Am I? ★State of the Room? ★Ways to test Javascript? ★Different Testing Environments? ★Overview of Testing Tools ★Using Testing in your Workflow ★Spaghetti Javascript ★Refactor Spaghetti into Testable Javascript ★Installing Jasmine + Live Demo
  3. 3. ★Who Am I? ★Gavin Pickin – developing Web Apps since late 90s ○Ortus Solutions Software Consultant ○ContentBox Evangelist ★What else do you need to know? ○CFMLRepo.com http://www.cfmlrepo.com ○Blog - http://www.gpickin.com ○Twitter – http://twitter.com/gpickin ○Github - https://github.com/gpickin ★Lets get on with the show.
  4. 4. ★State of the Room ★ A few questions for you guys ★ If you have arms, use them.
  5. 5. ★State of the Room Testing? What’s testing?
  6. 6. ★State of the Room Yeah, I’ve heard of it. Why do you think I’m here?
  7. 7. ★State of the Room Yes I know I should be testing, but I’m not sure how to do it
  8. 8. ★State of the Room My Boss and my Customers wouldn’t let me
  9. 9. ★State of the Room I’m a tester
  10. 10. ★State of the Room I’m a test writing ninja Call me Majano, Luis Majano
  11. 11. ★Ways to Test your Code ★Click around in the browser yourself ★Setup Selenium / Web Driver to click around for you ★Structured Programmatic Tests
  12. 12. ★Types of Testing
  13. 13. ★Types of Testing ★Black/White Box ★Unit Testing ★Integration Testing ★Functional Tests ★System Tests ★End to End Tests ★Sanity Testing ★Regression Test ★Acceptance Tests ★Load Testing ★Stress Test ★Performance Tests ★Usability Tests ★+ More
  14. 14. ★Levels of Testing
  15. 15. ★Cost of a Bug The bug will cost one way or another
  16. 16. ★Integration Testing
  17. 17. ★Integration Testing ★Integration Tests several of the pieces together ★Most of the types of tests are variations of an Integration Test ★Can include mocks but can full end to end tests including DB / APIs
  18. 18. ★Unit Testing
  19. 19. ★Unit Testing “unit testing is a software verification and validation method in which a programmer tests if individual units of source code are fit for use. A unit is the smallest testable part of an application” - wikipedia
  20. 20. ★Unit Testing ★Can improve code quality -> quick error discovery ★Code confidence via immediate verification ★Can expose high coupling ★Will encourage refactoring to produce > testable code ★Remember: Testing is all about behavior and expectations
  21. 21. ★Styles – TDD vs BDD ★TDD = Test Driven Development ○Write Tests ○Run them and they Fail ○Write Functions to Fulfill the Tests ○Tests should pass ○Refactor in confidence ★Test focus on Functionality
  22. 22. ★Styles – TDD vs BDD ★BDD = Behavior Driven Development Actually similar to TDD except: ★Focuses on Behavior and Specifications ★Specs (tests) are fluent and readable ★Readability makes them great for all levels of testing in the organization ★Hard to find TDD examples in JS that are not using BDD describe and it blocks
  23. 23. ★TDD Example Test( ‘Email address must not be blank’, function(){ notEqual(email, “”, "failed"); });
  24. 24. ★BDD Example Describe( ‘Email Address’, function(){ It(‘should not be blank’, function(){ expect(email).not.toBe(“”); }); });
  25. 25. ★Matchers expect(true).toBe(true); expect(true).toBe(true); expect(true).toBe(true); expect(true).toBe(true);
  26. 26. ★Matchers expect(true).not.toBe(true); expect(true).not.toBe(true); expect(true).not.toBe(true); expect(true).not.toBe(true); expect(true).not.toBe(true);
  27. 27. ★Matcher Samples expect(true).toBe(true); expect(a).not.toBe(null); expect(a).toEqual(12); expect(message).toMatch(/bar/); expect(message).toMatch("bar"); expect(message).not.toMatch(/quux/); expect(a.foo).toBeDefined(); expect(a.bar).not.toBeDefined();
  28. 28. ★Different Testing Environments? NodeJS - CLI In the Browser
  29. 29. ★Overview of Testing Tools ★There are a few choices
  30. 30. ★Main Testing Players ★Jasmine, Mocha and QUnit
  31. 31. ★Jasmine ★Jasmine comes ready to go out of the box ★Fluent Syntax – BDD Style ★Includes lots of matchers ★Has spies included ★Very popular, lots of support ★Angular uses Jasmine with Karma (CLI) ★Headless running and plays well with CI servers
  32. 32. ★Jasmine - Cons ★Async testing in 1.3 can be a headache ★Expects *spec.js suffix for test files ○This can be modified depending on how you are running the tests
  33. 33. ★Jasmine – Sample Test describe("Hello world function", function() { it(”contains the word world", function() { expect(helloWorld()).toContain("world"); }); });
  34. 34. ★Mocha★Simple Setup ★Simple Async testing ★Works great with other Assertion libraries like Chai ( not included ) ★Solid Support with CI Servers, with Plugins for others ★Opinion says Mocha blazing the trail for new features
  35. 35. ★Mocha - Cons ★Requires other Libraries for key features ○No Assertion Library included ○No Mocking / Spied included ○Need to create the runner manually ★Newer to the game so not as popular or supported as others but gaining traction.
  36. 36. ★Mocha – BDD Sample Test var expect = require('chai').expect; describe(’Hello World Function', function(){ it('should contain the word world', function(){ expect(helloWorld()).to.contain(’world'); }) })
  37. 37. ★QUnit ★The oldest of the main testing frameworks ★Is popular due to use in jQuery and age ★Ember’s default Unit testing Framework
  38. 38. ★QUnit - Cons ★Development slowed down since 2013 (but still under development) ★Syntax – No BDD style ★Assertion libraries – limited matchers
  39. 39. ★QUnit – Sample Test QUnit.test( "ok test", function( assert ) { assert.ok( true, "true succeeds" ); assert.ok( "non-empty", "non-empty string succeeds" ); assert.ok( false, "false fails" ); assert.ok( 0, "0 fails" ); assert.ok( NaN, "NaN fails" ); assert.ok( "", "empty string fails" ); assert.ok( null, "null fails" ); assert.ok( undefined, "undefined fails" ); });
  40. 40. ★Spaghetti Javascript Photo Credit – Kombination http://www.kombination.co.za/wp-content/uploads/2012/10/baby_w_spaghetti_mess_4987941.jpg
  41. 41. ★Spaghetti Javascript Example If we have time at the end
  42. 42. ★Spaghetti Javascript Example
  43. 43. ★Refactoring Spaghetti ★Things to refactor to make your code testable ○Code should not be one big chunk of Javascript in onReady() ○Deep nested callbacks & Anon functions cannot easily be singled out and tested ○Remove Tight Coupling – DOM access for example
  44. 44. ★Object Literals var personObjLit = { ssn: ’xxxxxxxx', age: '35', name: 'Gavin Pickin', getAge: function(){ return this.age; }, getName: function() { return this.name; } };
  45. 45. ★Module Pattern var personObjLit2 = function() { ssn = ’xxxxxxx'; age = '35'; name = 'Gavin Pickin’; return { getAge: function(){ return age; }, getName: function() { return name; } }; };
  46. 46. ★Using Testing in your Workflow ★Using HTML Test Runners ○Keep a Browser open ○F5 refresh tests
  47. 47. ★Command Line Tests ★Run Jasmine – manual ○Run tests at the end of each section of work ★Run Grunt-Watch – automatic ○Runs Jasmine on every file change ○Grunt can run other tasks as well, minification etc
  48. 48. ★Testing in your IDE ★Browser Views ○Eclipse allows you to open files in web view – uses HTML Runner ★Run Jasmine / Grunt / Karma in IDE Console ○Easy to setup – See Demo– Sublime Text 2
  49. 49. ★Live Demo and Examples *Install / Run Jasmine Standalone for Browser *Install / Run Jasmine with NodeJs *Install/ Run Jasmine with Grunt Watch *Install / Run Grunt Watch inside Sublime Text 2
  50. 50. ★Install / Run Jasmine for In- Browser Testing Download standalone package from Github (I have 2.1.3) https://github.com/jasmine/jasmine/tree/master/dist Unzip into your /tests folder Run /tests/SpecRunner.html to see example tests
  51. 51. ★Standalone Jasmine
  52. 52. ★Installing Jasmine for in Browser Testing
  53. 53. ★SpecRunner Setup Jasmine Browser Test <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Jasmine Spec Runner v2.1.3</title> <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.1.3/jasmine_favicon.png"> <link rel="stylesheet" href="lib/jasmine-2.1.3/jasmine.css”> <script src="lib/jasmine-2.1.3/jasmine.js"></script> <script src="lib/jasmine-2.1.3/jasmine-html.js"></script> <script src="lib/jasmine-2.1.3/boot.js"></script> <!-- include source files here... --> <script src="../js/services/loginService.js"></script> <!-- include spec files here... --> <script src="spec/loginServiceSpec.js"></script> </head> <body> </body> </html>
  54. 54. ★Installing Jasmine with NodeJS Assuming you have NodeJs Installed… install Jasmine $ npm install jasmine jasmine@2.2.1 node_modules/jasmine ├── exit@0.1.2 ├── jasmine-core@2.2.0 └── glob@3.2.11 (inherits@2.0.1, minimatch@0.3.0)
  55. 55. ★Installing Jasmine with NodeJS Once Jasmine is installed in your project $ Jasmine init
  56. 56. ★Installing Jasmine with NodeJS Edit Jasmine.json to update Locations for Spec Files and Helper Files { "spec_dir": "spec", "spec_files": [ "**/*[sS]pec.js" ], "helpers": [ "helpers/**/*.js" ] }
  57. 57. ★Running Jasmine Tests with NodeJS$ Jasmine Started F Failures: 1) A suite contains spec with an expectation Message: Expected true to be false. Stack: Error: Expected true to be false. at Object.<anonymous> (/Users/gavinpickin/Dropbox/Apps/testApp/www/spec/test_spec.js:3: 18) 1 spec, 1 failure Finished in 0.009 seconds
  58. 58. ★Running Jasmine Tests with NodeJS ★Jasmine-Node is great for Node ★Jasmine Node doesn’t have a headless browser ★Hard to test Browser code ★So what should I use?
  59. 59. ★Installing Jasmine with Grunt Watcher ★Install Grunt npm install grunt ★Install Grunt – Jasmine npm install grunt-contrib-jasmine ★Install Grunt – Watch npm install grunt-contrib-watch ★Note: On Mac, I also needed to install Grunt CLI npm install –g grunt-cli
  60. 60. ★Configuring Jasmine with Grunt Watcher // gruntfile.js - https://gist.github.com/gpickin/1e1e7902d1d3676d23c5 module.exports = function (grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('node_modules/grunt/package.json'), jasmine: { all: { src: ['js/*.js' ], options: { //'vendor': ['path/to/vendor/libs/*.js'], 'specs': ['specs/*.js' ] } } },
  61. 61. ★Configuring Jasmine with Grunt Watcher // gruntfile.js part 2 watch: { js: { files: [ 'js/*.js', 'specs/*.js', ], tasks: ['jasmine:all'] } } });
  62. 62. ★Configuring Jasmine with Grunt Watcher // gruntfile.js part 3 grunt.loadNpmTasks('grunt-contrib-jasmine'); grunt.loadNpmTasks('grunt-contrib-watch'); };
  63. 63. ★Example Spec Jasmine with Grunt Watcher describe("A suite", function() { it("contains spec with an expectation", function() { expect(true).toBe(true); }); });
  64. 64. ★Running Jasmine with Grunt Watcher
  65. 65. ★Running Jasmine with Grunt Watcher
  66. 66. ★Running in Sublime Text 2 ★Install PackageControl into Sublime Text ★Install Grunt from PackageControl ○https://packagecontrol.io/packages/Grunt ★Update Grunt Sublime Settings for paths { "exec_args": { "path": "/bin:/usr/bin:/usr/local/bin” } } ★Then Command Shift P – grunt
  67. 67. ★Running in Sublime Text 2
  68. 68. ★Refactoring Spaghetti ★Lets look at some code ★This isn’t BEST PRACTICE, its BETTER PRACTICE than you were doing ★Its not really refactoring if you don’t have tests, its “moving code and asking for trouble”
  69. 69. ★Q&A ★Any questions?