Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JavaScript Craftsmanship: Why JavaScript is Worthy of TDD

3,299 views

Published on

Slides presented to the Columbus Polyglot

Published in: Technology
  • Login to see the comments

JavaScript Craftsmanship: Why JavaScript is Worthy of TDD

  1. 1. JavaScript Craftsmanship Why JavaScript is worthy of TDD
  2. 2. You Don’t Call Yourself a Toy Maker So don’t treat JavaScript like a toy language
  3. 3. Justin Searls www.pillartechnology.com
  4. 4. Justin Searls • searls@gmail.com • github.com/searls • twitter.com/searls www.pillartechnology.com
  5. 5. Justin Searls • searls@gmail.com • github.com/searls • twitter.com/searls Recent Stuff iPad app for secure AES-256 note-taking: itunes.com/app/textual jasmine-maven-plugin for JavaScript testing: github.com/searls/jasmine-maven-plugin www.pillartechnology.com
  6. 6. Telecom Customer Infrastructure
  7. 7. Telecom Customer Infrastructure
  8. 8. x Telecom Customer Infrastructure
  9. 9. x Telecom Customer Infrastructure
  10. 10. Telecom Customer Infrastructure
  11. 11. Telecom Last Mile Customer Infrastructure
  12. 12. Telecom Last Mile Customer Infrastructure
  13. 13. Telecom Customer Infrastructure
  14. 14. Telecom Customer Infrastructure
  15. 15. a Word on Telecoms
  16. 16. a Word on Telecoms • The “Last Mile” is the final leg of delivering connectivity to a customer
  17. 17. a Word on Telecoms • The “Last Mile” is the final leg of delivering connectivity to a customer • Labor-intensive task of burying wires to connect endpoints to the smart & expensive central infrastructure
  18. 18. a Word on Telecoms • The “Last Mile” is the final leg of delivering connectivity to a customer • Labor-intensive task of burying wires to connect endpoints to the smart & expensive central infrastructure • Challenges are practical, not theoretical; typified by battling physical terrain, zoning rules, and basic economics
  19. 19. a Word on Telecoms • The “Last Mile” is the final leg of delivering connectivity to a customer • Labor-intensive task of burying wires to connect endpoints to the smart & expensive central infrastructure • Challenges are practical, not theoretical; typified by battling physical terrain, zoning rules, and basic economics • Nobody goes to college for four years to serve the last mile; the “real” hard problems are centralized
  20. 20. Carefully crafted server Customer software
  21. 21. $('#button').click( function(){ $.get('/me-outta-here'); } ); Carefully crafted server Last Mile Customer software
  22. 22. $('#button').click( function(){ $.get('/me-outta-here'); } ); Carefully crafted server Last Mile Customer software
  23. 23. Carefully crafted server Customer software
  24. 24. Carefully crafted server Customer software
  25. 25. JavaScript is Many Developers’ Last Mile
  26. 26. JavaScript is Many Developers’ Last Mile • A final chore to connect users to our carefully-tended server-side functionality
  27. 27. JavaScript is Many Developers’ Last Mile • A final chore to connect users to our carefully-tended server-side functionality • Labor-intensive – any code treated as dumb wiring is bound to grow out of control over time
  28. 28. JavaScript is Many Developers’ Last Mile • A final chore to connect users to our carefully-tended server-side functionality • Labor-intensive – any code treated as dumb wiring is bound to grow out of control over time • Challenges are practical – browser compatibility quirks and debugging crowd out intentional design
  29. 29. JavaScript is Many Developers’ Last Mile • A final chore to connect users to our carefully-tended server-side functionality • Labor-intensive – any code treated as dumb wiring is bound to grow out of control over time • Challenges are practical – browser compatibility quirks and debugging crowd out intentional design • Nobody goes to college for four years to write JavaScript; “real” code runs on the server-side
  30. 30. But!
  31. 31. But! Unlike cable access, software itself is not a commodity
  32. 32. Carefully crafted server Customer software
  33. 33. Carefully crafted server Carefully crafted Customer software client software
  34. 34. Carefully crafted server Carefully crafted Customer software client software
  35. 35. Carefully crafted server Carefully crafted Customer software client software
  36. 36. Carefully crafted server Carefully crafted Customer software client software
  37. 37. Carefully crafted server Carefully crafted Customer software client software
  38. 38. How’d we get here?
  39. 39. How’d we get here? • Inertia: the static server-side web arrived first
  40. 40. How’d we get here? • Inertia: the static server-side web arrived first • Focus: good JavaScript is paramount to (almost) no one
  41. 41. How’d we get here? • Inertia: the static server-side web arrived first • Focus: good JavaScript is paramount to (almost) no one • Missing Itches: factors that normally encourage people to take a language seriously are missing from JavaScript
  42. 42. Inertia
  43. 43. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  44. 44. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  45. 45. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  46. 46. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  47. 47. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  48. 48. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  49. 49. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  50. 50. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  51. 51. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  52. 52. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js
  53. 53. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js Woah. In the same year:
  54. 54. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js Woah. In the same year: 1. Server-side reached the sophistication of Ruby on Rails
  55. 55. Inertia Year Server Client 1993 CGI (Perl) 1995 PHP2 JavaScript 1.0, 1996 ASP 1.0 Macromedia Flash 1997 Java Servlet 1.0 1998 PHP3 JavaScript 1.3 (ECMA-262) 2005 Ruby on Rails 1.0 Prototype.js 2006 jQuery, Firebug 2007 env.js 2009 Node.js Woah. In the same year: 1. Server-side reached the sophistication of Ruby on Rails 2. Cross-browser JavaScript only began to become pragmatic
  56. 56. Focus An IT middle manager, an experienced craftsman, and a junior developer walk into a bar...
  57. 57. Focus An IT middle manager, an experienced craftsman, and a junior developer walk into a bar... • The IT middle manager says, “Write all the JavaScript you want, but we only review and reward server-side code.”
  58. 58. Focus An IT middle manager, an experienced craftsman, and a junior developer walk into a bar... • The IT middle manager says, “Write all the JavaScript you want, but we only review and reward server-side code.” • The experienced craftsman says, “JavaScript is awesome! But let’s code this story server-side so we can test-drive it.”
  59. 59. Focus An IT middle manager, an experienced craftsman, and a junior developer walk into a bar... • The IT middle manager says, “Write all the JavaScript you want, but we only review and reward server-side code.” • The experienced craftsman says, “JavaScript is awesome! But let’s code this story server-side so we can test-drive it.” • The junior developer gets the message and keeps his JavaScript craft at the level of copy-pasting hover menus from hotscripts.com
  60. 60. Missing Itches
  61. 61. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  62. 62. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  63. 63. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  64. 64. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  65. 65. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  66. 66. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  67. 67. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  68. 68. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  69. 69. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  70. 70. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  71. 71. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  72. 72. Missing Itches Itch Is Missing Numerous vendors competing, Vendor hype, docs, certs but not promoting or curating Language constructs Relatively few reserved keywords Frameworks (jQuery) mask pain Spaghetti code astoundingly well UI test tools (e.g. Selenium) offer CI Continuous Integration green light, indirect code coverage Language flexibility + community a Right Way™ to do __ diversity → competing conventions
  73. 73. One might respond:
  74. 74. One might respond: “Exactly! So why should I care whether my JavaScript is awesome?”
  75. 75. Why Awesomize JavaScript?
  76. 76. Why Awesomize JavaScript? • Performance
  77. 77. Why Awesomize JavaScript? • Performance • User experience
  78. 78. Why Awesomize JavaScript? • Performance • User experience • Behavior can go where it logically belongs
  79. 79. Why Awesomize JavaScript? • Performance • User experience • Behavior can go where it logically belongs • Better discriminated presentation tier (for, say, mobile)
  80. 80. Why Awesomize JavaScript? • Performance • User experience • Behavior can go where it logically belongs • Better discriminated presentation tier (for, say, mobile) • Portability
  81. 81. One might respond, again:
  82. 82. One might respond, again: “Well, fine. I’ll try taking JavaScript seriously. But what does that even mean?”
  83. 83. One might respond, again: “Well, fine. I’ll try taking JavaScript seriously. But what does that even mean?” And one might answer: “First, try doing whatever you already do to make your other code awesome.”
  84. 84. A few fan favorites • Pair Programming • Team coding standards • TDD • Continuous Integration • Make Change Cheap
  85. 85. A few fan favorites • Pair Programming • Team coding standards • TDD • Continuous Integration • Make Change Cheap
  86. 86. JavaScript Unit Testing Too many frameworks → Analysis paralysis (see: the jam study) Healthy ones: • Jasmine - http://pivotal.github.com/jasmine • JsTestDriver - http://code.google.com/p/js-test-driver • qunit - http://github.com/jquery/qunit • jspec - http://wiki.github.com/visionmedia/jspec Seemingly stale/dead ones: • JsUnit - http://www.jsunit.net • Screw Unit - http://github.com/nathansobo/screw-unit • ~16 more - http://ejohn.org/blog/which-unit-testing-framework
  87. 87. What actions do I take?
  88. 88. What actions do I take? 1. Read around and decide on a tool
  89. 89. What actions do I take? 1. Read around and decide on a tool 2. Set up a project
  90. 90. What actions do I take? 1. Read around and decide on a tool 2. Set up a project 3. Create an HTML runner file (yuck!)
  91. 91. What actions do I take? 1. Read around and decide on a tool 2. Set up a project 3. Create an HTML runner file (yuck!) 4. Refresh a browser to execute a test as you go
  92. 92. What actions do I take? 1. Read around and decide on a tool 2. Set up a project 3. Create an HTML runner file (yuck!) 4. Refresh a browser to execute a test as you go 5. Figure out how to integrate it into your CI build
  93. 93. What actions do I take? 1. Read around and decide on a tool use Jasmine 2. Set up a project 3. Create an HTML runner file (yuck!) use jasmine-gem or jasmine-maven-plugin 4. Refresh a browser to execute a test as you go 5. Figure out how to integrate it into your CI build use jasmine-gem or jasmine-maven-plugin
  94. 94. What actions do I take? 1. Read around and decide on a tool use Jasmine 2. Set up a project use rails or jasmine-archetype 3. Create an HTML runner file (yuck!) use jasmine-gem or jasmine-maven-plugin 4. Refresh a browser to execute a test as you go 5. Figure out how to integrate it into your CI build use jasmine-gem or jasmine-maven-plugin
  95. 95. play
  96. 96. Tool Links • Code analysis JSLint http://www.jslint.com • Code coverage JSCoverage http://siliconforks.com/jscoverage • Compression Packer http://dean.edwards.name/packer
  97. 97. Learning Links • Book: “JavaScript: The Good Parts,” Crockford, 2008 • Book: “Pro JavaScript Techniques,” Resig, 2006 • Functional JavaScript koans JsTestDriver - github.com/mrdavidlaing/functional-koans Jasmine - github.com/gregmalcolm/functional-koans • SproutCore Framework (and Greenhouse) • Brendan Eich at JSConf 2010 on ECMAScript 5
  98. 98. Inspirational Blog Links • “JavaScript: It’s Grown Up to be Taken Seriously” • “Why JavaScript is AWESOME”
  99. 99. Discussion • What cool things have you seen/done lately? • What’s blocking you from stepping up your JS game? • How do you think this topic will be perceived in two years?
  100. 100. “...everyone who’s ever written some object-oriented JavaScript has built their own scheme of doing this, which can be rather confusing.” - John Resig, Pro JavaScript (2006) Let’s make a Ninja object!
  101. 101. //Trivial function Ninja(weaponOfChoice) { this.weaponOfChoice = weaponOfChoice; }; Ninja.prototype.attack = function() { return "*thwack* goes the "+this.weaponOfChoice; }; var michelangelo = new Ninja('nanchaku'); document.write(michelangelo.weaponOfChoice); //nanchaku document.write(michelangelo.attack()); //*thwack* goes the nanchaku
  102. 102. //Module Pattern function Ninja(weaponOfChoice) { return { weaponOfChoice:weaponOfChoice, attack: function() { return "*thwack* goes the"+this.weaponOfChoice; } }; }; var michelangelo = new Ninja('nanchaku'); document.write(michelangelo.weaponOfChoice); //nanchaku document.write(michelangelo.attack()); //*thwack* goes the nanchaku
  103. 103. //Using instanceof to guard against user forgetting `new` function Ninja(weaponOfChoice) { if(this instanceof Ninja) { this.weaponOfChoice = weaponOfChoice; } else { return new Ninja(weaponOfChoice) } }; Ninja.prototype.attack = function() { return "*thwack* goes the "+this.weaponOfChoice; }; var michelangelo = Ninja('nanchaku'); //forgot `new`, but that's okay! document.write(michelangelo.weaponOfChoice); //nanchaku document.write(michelangelo.attack()); //*thwack* goes the nanchaku
  104. 104. //An abstraction to eliminate the redundant constructor // call within the initialization block // makeClass - By John Resig (MIT Licensed) function makeClass(){ return function(args){ if ( this instanceof arguments.callee ) { if ( typeof this.init == "function" ) this.init.apply( this, args.callee ? args : arguments ); } else return new arguments.callee( arguments ); }; } //Now for our ninja: var Ninja = makeClass(); Ninja.prototype.init = function(weaponOfChoice) { this.weaponOfChoice = weaponOfChoice; } Ninja.prototype.attack = function() { return "*thwack* goes the "+this.weaponOfChoice; }; var michelangelo = Ninja('nanchaku'); document.write(michelangelo.weaponOfChoice); //nanchaku document.write(michelangelo.attack()); //*thwack* goes the nanchaku
  105. 105. //Mootools Ninja var Ninja = new Class({ initialize: function(weaponOfChoice) { this.weaponOfChoice = weaponOfChoice; }, attack: function() { return "*thwack* goes the "+this.weaponOfChoice; } }); var NoisyNinja = new Class({ Extends: Ninja, initialize: function(weaponOfChoice,battleCry) { this.parent(weaponOfChoice); this.battleCry = battleCry; }, attack: function() { return '"'+this.battleCry+'!" '+this.parent(); } }); var michelangelo = new NoisyNinja('nanchaku','...'); document.write(michelangelo.weaponOfChoice); //nanchaku document.write(michelangelo.attack()); //"...!" *thwack* goes the nanchaku
  106. 106. //Using the prototype.js framework var Ninja = Class.create({ initialize: function(weaponOfChoice) { this.weaponOfChoice = weaponOfChoice; }, attack: function() { return "*thwack* goes the "+this.weaponOfChoice; } }); var NoisyNinja = Class.create(Ninja, { initialize: function($super,weaponOfChoice,battleCry) { $super(weaponOfChoice); this.battleCry = battleCry; }, attack: function($super) { return '"'+this.battleCry+'!" '+$super(); } }); var michelangelo = new NoisyNinja('nanchaku','...'); document.write(michelangelo.weaponOfChoice); //nanchaku document.write(michelangelo.attack()); //"...!" *thwack* goes the nanchaku
  107. 107. //Using Dean Edwards' Base.js var Ninja = Base.extend({ constructor: function(weaponOfChoice) { this.weaponOfChoice = weaponOfChoice; }, weaponOfChoice:'', attack: function() { return "*thwack* goes the "+this.weaponOfChoice; } }); var NoisyNinja = Ninja.extend({ constructor: function(weaponOfChoice,battleCry) { this.base(weaponOfChoice); if(battleCry) { this.battleCry = battleCry; } }, battleCry:'default -- O NOES IM BEING TOO LOUD', attack: function() { return '"'+this.battleCry+'!" '+this.base(); } }); var michelangelo = new NoisyNinja('nanchaku','...'); document.write(michelangelo.weaponOfChoice); //nanchaku document.write(michelangelo.attack()); //"...!" *thwack* goes the nanchaku
  108. 108. Final Bonus Slide "JavaScript already has most of the features people complain about not having, in ways that aren't really that ugly or intrusive, despite popular belief." - Scott S. McCoy

×