SlideShare a Scribd company logo
1 of 35
Test-Driven JavaScript
with ScrewUnit &
BlueRidge	
Andy Peterson
Jonah Williams
Carbon Five
Introductions
Carbon Five

Boutique software consulting
  20 people, all developers
  Agile development, collaboration, transparency
  Mix of projects: start-ups / non-profits / enterprise
  History of Java, but now RoR + misc.
Agenda

 JavaScript unit testing: how & why
  BDD, jQuery, plugins
Demo TDD with a simple test
Problems & lessons learned
Q&A
Why NOT JS Unit Testing?
Can’t get started
We don’t; nobody else does
Patterns unclear-- what does it look like
Too many tools (and arch.) to choose from
  ... lack of tool & infrastructure support
Flakey/bad experiences
Why JS Unit Testing?

Tests => Confidence => Ambition
Take on more challenging requirements
More homogenous architecture (w/o Flash)
Push logic into browser... scalability
Refactor reliably
JS Testing Universe
 Styles of Tests:
   xUnit: JSUnit, QUnit, YUITest, etc.
   BDD: JSSpec, ScrewUnit
 Automation:
   In-browser w/ Selenium, WebDriver, JSTestDriver
   Out of browser: Env.js + Rhino
Blue Ridge
Ruby on Rails plugin (therefore conventions!)
Integrates
  ScrewUnit (BDD) and Smoke (mocking)
  Glue code and scripts
  Rhino & Env.js to run out of browser
from Larry Karnowski, Runcoderun
BDD
Language closer to user stories
Popularized by RSpec in Ruby
describe -- organize
before / after blocks
Nesting describes -- to DRY
One assert should per test example
describe Stack do
  before(:each) do
    @stack = Stack.new
    @stack.push :item
  end
  describe "#peek" do
    it "should return the top element" do
      @stack.peek.should == :item
    end
    it "should not remove the top element" do
      @stack.peek
      @stack.size.should == 1
    end
  end
  describe "#pop" do                        Stack (generated docs)
    it "should return the top element" do    #peek
      @stack.pop.should == :item             - should return the top element
    end
    it "should remove the top element" do
                                             - should not remove the top
      @stack.pop                            element
      @stack.size.should == 0                #pop
    end                                      - should return the top element
  end
end                                          - should remove the top element
BDD	 in RSpec
describe 'a man' {
  before {
    @man = Man.new :luck=>5
  }

  describe '#decrement_luck' {
    it "decrements the luck field by the given amount" {
      @man.decrement_luck(3)
      @man.luck.should == 2
    }
  }
  ...

});
BDD	 in ScrewUnit
describe('Man', function() {
  var man;
  before(function() {
    man = new Man({luck: 5});
  });

  describe('#decrement_luck', function() {
    it("decrements the luck field by the given amount", function() {
      man.decrement_luck(3);
      expect(man.luck()).to(equal, 2)
    });
  });
  ...

});
Let’s See It
Wizard-izer (our example)

 Given a form comprised of fieldsets
   Creates a “panel” for each fieldset
   Hides all but the first panel
   Adds buttons to navigate panels
   etc.
Blue Ridge Installation
http://github.com/relevance/blue-ridge/tree/master




   # Within a rails project

   > ./script/plugin install git://
   github.com/relevance/blueridge.git
   > ./script/generate blue_ridge
   > ./script/generate javascript_spec wiz
Maven Installation
http://code.google.com/p/javascript-test-maven-plugin/

   <plugin>
  <executions><execution>
  <goals>
    <goal>javascript-test</goal>
  </goals>
  </execution></executions>
  <groupId>com.carbonfive.javascript-test</groupId>
  <artifactId>javascript-test-maven-plugin</artifactId>
  <version>1.0-beta1</version>
  <configuration>
    <includes>
       <include>src/test/javascript/suite*.html</include>
    </includes>
  </configuration>
</plugin>
3 Components
Fixture - markup that JS requires
  test/javascript/widget.html
Spec - tests
  test/javascript/specs/widget_spec.js)
Code to test - independent JS
  <public>/javascript/widget.js
jQuery

Functional DOM manipulation
One function $: $(selector) eg. $(‘p.cls’)
Chainable -- $
(‘p.cls’).addClass(‘abc’).removeClass(‘cls’).etc(...)

Plugins
jQuery Plugin
Add function to         jQuery.fn.reverse() = function() {
jQuery object
                            // “this” is list of nodes
Receive list of nodes
                            $(this).each(function() {
                               var t = $(this).text();
Do your stuff                  $(this).text(t);
                            }
Return “this”
                            return this;
Good tutorials online   }
DOM cleanup	

Tools don’t reset your DOM automatically
They are writing status back to the page (yuck!)
Solution
  Wrap fixtures (in #fixture container)
  before function that restores DOM state
DOM cleanup fn
// before(function() { $('#fixture).fixture(); });
jQuery.fn.fixture = function() {
    this.each(function() {
      if (this.original) {
          $(this).html(this.original);
      } else {
          this.original = $(this).html();
      }
    });
}
Put CSS in Fixture


 Helps with debugging
 Use FireBug to inspect
Structure as a jQuery plugin

jQuery is not required-- but really helps you organize
code
Separate document.ready() from code--
dependency injection
Use as organizing principal, and dependency injection
Write modular code, instead page-specific code
Learnings
Not Hard to Make JS
Testing a Part of Your
Process
Markup Design


Generated in JS? On the server? Hybrid?
Unit testing encourages generating more markup in
JavaScript
Will affect SEO and accessibility (good or bad)
When to test

Some JS can be experimental
Test-drive when you have a good sense of what he
component is
Testing is a refactoring tool
  As code gets complicated, pull into testable units
Don’t Be Afraid of JS


 Reminder wizard
 Method chooser demo-- data driven JS, with ajax
 structure
What to Unit Test /
Limitations
                                     AJAX
     JavaScript Unit Testing
                                  setTimeout()
                                  setInterval()
   DOM                 Business
 Manipulation           Logic     Animations

                                  Computed sizes
It’s Not Browser Testing

 ...it’s JS unit testing
   Not cross-browser testing
   Not your production markup
   Functional test framework still have a place
Our Testing Stack

  Selenium Integration & Browser Testing 1/10th

 Controller/View Integration
          Tests 1/5th
                                  Javascript Unit
                                     Testing
Model Unit     Controller Unit          1/10th

  Tests            Tests
JavaScript Testing
Yes We Can!	
Andy Peterson        Jonah Williams
andy@carbonfive.com   jonah@carbonfive.com
skype: ndpsoft
Blue Ridge TODOs
Run in more browsers (not just Firefox)
Speed
Events
Driving in multiple browsers
Using code served from app
Shenandoah
Other Options


ScrewUnit Server
Selenium + JSUnit
testswarm (?)
References (Bibliography)
 http://github.com/relevance/blue-ridge
 http://pivotallabs.com/users/nick/blog/articles/455-
 better-javascript-testing-through-screwunit
 http://github.com/ndp/wizardize
 http://www.slideshare.net/jeresig/understanding-
 javascript-testing
 http://code.google.com/p/javascript-test-maven-
 plugin/

More Related Content

What's hot

Unit Testing JavaScript Applications
Unit Testing JavaScript ApplicationsUnit Testing JavaScript Applications
Unit Testing JavaScript ApplicationsYnon Perek
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJSPeter Drinnan
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaExoLeaders.com
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF SummitOrtus Solutions, Corp
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Roy Yu
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with JestMichał Pierzchała
 
Jasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyJasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyIgor Napierala
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with JasmineTim Tyrrell
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersDavid Rodenas
 
Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJSBoris Dinkevich
 
Web ui tests examples with selenide, nselene, selene & capybara
Web ui tests examples with  selenide, nselene, selene & capybaraWeb ui tests examples with  selenide, nselene, selene & capybara
Web ui tests examples with selenide, nselene, selene & capybaraIakiv Kramarenko
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
Testing JS with Jasmine
Testing JS with JasmineTesting JS with Jasmine
Testing JS with JasmineEvgeny Gurin
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS ArchitectureEyal Vardi
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmineTimothy Oxley
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projectsIgnacio Martín
 
SilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript RefactoringSilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript RefactoringIngo Schommer
 
Clojure in the Wild
Clojure in the WildClojure in the Wild
Clojure in the Wildsuitzero
 

What's hot (20)

Unit Testing JavaScript Applications
Unit Testing JavaScript ApplicationsUnit Testing JavaScript Applications
Unit Testing JavaScript Applications
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJS
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
 
Jasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyJasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishy
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
 
Jasmine BDD for Javascript
Jasmine BDD for JavascriptJasmine BDD for Javascript
Jasmine BDD for Javascript
 
Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for Programmers
 
Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJS
 
Web ui tests examples with selenide, nselene, selene & capybara
Web ui tests examples with  selenide, nselene, selene & capybaraWeb ui tests examples with  selenide, nselene, selene & capybara
Web ui tests examples with selenide, nselene, selene & capybara
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Testing JS with Jasmine
Testing JS with JasmineTesting JS with Jasmine
Testing JS with Jasmine
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmine
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
SilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript RefactoringSilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript Refactoring
 
Clojure in the Wild
Clojure in the WildClojure in the Wild
Clojure in the Wild
 

Similar to Javascript unit testing, yes we can e big

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
Javascript ui for rest services
Javascript ui for rest servicesJavascript ui for rest services
Javascript ui for rest servicesIoan Eugen Stan
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETBen Hall
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Yevgeniy Brikman
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebJames Rakich
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
Reliable Javascript
Reliable Javascript Reliable Javascript
Reliable Javascript Glenn Stovall
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
Security testing of YUI powered applications
Security testing of YUI powered applicationsSecurity testing of YUI powered applications
Security testing of YUI powered applicationsdimisec
 
High Performance Ajax Applications 1197671494632682 2
High Performance Ajax Applications 1197671494632682 2High Performance Ajax Applications 1197671494632682 2
High Performance Ajax Applications 1197671494632682 2Niti Chotkaew
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax ApplicationsJulien Lecomte
 
Automation - web testing with selenium
Automation - web testing with seleniumAutomation - web testing with selenium
Automation - web testing with seleniumTzirla Rozental
 

Similar to Javascript unit testing, yes we can e big (20)

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Javascript ui for rest services
Javascript ui for rest servicesJavascript ui for rest services
Javascript ui for rest services
 
Java scriptforjavadev part2a
Java scriptforjavadev part2aJava scriptforjavadev part2a
Java scriptforjavadev part2a
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NET
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the Web
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Reliable Javascript
Reliable Javascript Reliable Javascript
Reliable Javascript
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Security testing of YUI powered applications
Security testing of YUI powered applicationsSecurity testing of YUI powered applications
Security testing of YUI powered applications
 
Oojs 1.1
Oojs 1.1Oojs 1.1
Oojs 1.1
 
High Performance Ajax Applications 1197671494632682 2
High Performance Ajax Applications 1197671494632682 2High Performance Ajax Applications 1197671494632682 2
High Performance Ajax Applications 1197671494632682 2
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
 
Automation - web testing with selenium
Automation - web testing with seleniumAutomation - web testing with selenium
Automation - web testing with selenium
 
前端概述
前端概述前端概述
前端概述
 

Javascript unit testing, yes we can e big

  • 1. Test-Driven JavaScript with ScrewUnit & BlueRidge Andy Peterson Jonah Williams Carbon Five
  • 3. Carbon Five Boutique software consulting 20 people, all developers Agile development, collaboration, transparency Mix of projects: start-ups / non-profits / enterprise History of Java, but now RoR + misc.
  • 4. Agenda JavaScript unit testing: how & why BDD, jQuery, plugins Demo TDD with a simple test Problems & lessons learned Q&A
  • 5. Why NOT JS Unit Testing? Can’t get started We don’t; nobody else does Patterns unclear-- what does it look like Too many tools (and arch.) to choose from ... lack of tool & infrastructure support Flakey/bad experiences
  • 6. Why JS Unit Testing? Tests => Confidence => Ambition Take on more challenging requirements More homogenous architecture (w/o Flash) Push logic into browser... scalability Refactor reliably
  • 7. JS Testing Universe Styles of Tests: xUnit: JSUnit, QUnit, YUITest, etc. BDD: JSSpec, ScrewUnit Automation: In-browser w/ Selenium, WebDriver, JSTestDriver Out of browser: Env.js + Rhino
  • 8. Blue Ridge Ruby on Rails plugin (therefore conventions!) Integrates ScrewUnit (BDD) and Smoke (mocking) Glue code and scripts Rhino & Env.js to run out of browser from Larry Karnowski, Runcoderun
  • 9. BDD Language closer to user stories Popularized by RSpec in Ruby describe -- organize before / after blocks Nesting describes -- to DRY One assert should per test example
  • 10. describe Stack do before(:each) do @stack = Stack.new @stack.push :item end describe "#peek" do it "should return the top element" do @stack.peek.should == :item end it "should not remove the top element" do @stack.peek @stack.size.should == 1 end end describe "#pop" do Stack (generated docs) it "should return the top element" do #peek @stack.pop.should == :item - should return the top element end it "should remove the top element" do - should not remove the top @stack.pop element @stack.size.should == 0 #pop end - should return the top element end end - should remove the top element
  • 11. BDD in RSpec describe 'a man' { before { @man = Man.new :luck=>5 } describe '#decrement_luck' { it "decrements the luck field by the given amount" { @man.decrement_luck(3) @man.luck.should == 2 } } ... });
  • 12. BDD in ScrewUnit describe('Man', function() { var man; before(function() { man = new Man({luck: 5}); }); describe('#decrement_luck', function() { it("decrements the luck field by the given amount", function() { man.decrement_luck(3); expect(man.luck()).to(equal, 2) }); }); ... });
  • 14. Wizard-izer (our example) Given a form comprised of fieldsets Creates a “panel” for each fieldset Hides all but the first panel Adds buttons to navigate panels etc.
  • 15. Blue Ridge Installation http://github.com/relevance/blue-ridge/tree/master # Within a rails project > ./script/plugin install git:// github.com/relevance/blueridge.git > ./script/generate blue_ridge > ./script/generate javascript_spec wiz
  • 16. Maven Installation http://code.google.com/p/javascript-test-maven-plugin/ <plugin> <executions><execution> <goals> <goal>javascript-test</goal> </goals> </execution></executions> <groupId>com.carbonfive.javascript-test</groupId> <artifactId>javascript-test-maven-plugin</artifactId> <version>1.0-beta1</version> <configuration> <includes> <include>src/test/javascript/suite*.html</include> </includes> </configuration> </plugin>
  • 17. 3 Components Fixture - markup that JS requires test/javascript/widget.html Spec - tests test/javascript/specs/widget_spec.js) Code to test - independent JS <public>/javascript/widget.js
  • 18. jQuery Functional DOM manipulation One function $: $(selector) eg. $(‘p.cls’) Chainable -- $ (‘p.cls’).addClass(‘abc’).removeClass(‘cls’).etc(...) Plugins
  • 19. jQuery Plugin Add function to jQuery.fn.reverse() = function() { jQuery object // “this” is list of nodes Receive list of nodes $(this).each(function() { var t = $(this).text(); Do your stuff $(this).text(t); } Return “this” return this; Good tutorials online }
  • 20. DOM cleanup Tools don’t reset your DOM automatically They are writing status back to the page (yuck!) Solution Wrap fixtures (in #fixture container) before function that restores DOM state
  • 21. DOM cleanup fn // before(function() { $('#fixture).fixture(); }); jQuery.fn.fixture = function() { this.each(function() { if (this.original) { $(this).html(this.original); } else { this.original = $(this).html(); } }); }
  • 22. Put CSS in Fixture Helps with debugging Use FireBug to inspect
  • 23. Structure as a jQuery plugin jQuery is not required-- but really helps you organize code Separate document.ready() from code-- dependency injection Use as organizing principal, and dependency injection Write modular code, instead page-specific code
  • 25. Not Hard to Make JS Testing a Part of Your Process
  • 26. Markup Design Generated in JS? On the server? Hybrid? Unit testing encourages generating more markup in JavaScript Will affect SEO and accessibility (good or bad)
  • 27. When to test Some JS can be experimental Test-drive when you have a good sense of what he component is Testing is a refactoring tool As code gets complicated, pull into testable units
  • 28. Don’t Be Afraid of JS Reminder wizard Method chooser demo-- data driven JS, with ajax structure
  • 29. What to Unit Test / Limitations AJAX JavaScript Unit Testing setTimeout() setInterval() DOM Business Manipulation Logic Animations Computed sizes
  • 30. It’s Not Browser Testing ...it’s JS unit testing Not cross-browser testing Not your production markup Functional test framework still have a place
  • 31. Our Testing Stack Selenium Integration & Browser Testing 1/10th Controller/View Integration Tests 1/5th Javascript Unit Testing Model Unit Controller Unit 1/10th Tests Tests
  • 32. JavaScript Testing Yes We Can! Andy Peterson Jonah Williams andy@carbonfive.com jonah@carbonfive.com skype: ndpsoft
  • 33. Blue Ridge TODOs Run in more browsers (not just Firefox) Speed Events Driving in multiple browsers Using code served from app Shenandoah
  • 34. Other Options ScrewUnit Server Selenium + JSUnit testswarm (?)
  • 35. References (Bibliography) http://github.com/relevance/blue-ridge http://pivotallabs.com/users/nick/blog/articles/455- better-javascript-testing-through-screwunit http://github.com/ndp/wizardize http://www.slideshare.net/jeresig/understanding- javascript-testing http://code.google.com/p/javascript-test-maven- plugin/

Editor's Notes

  1. Ask everyone to introduce themselves quickly.
  2. Who Writes Java? Write Unit tests? Who Writes Ruby Who Writes JavaScript? Do you write unit tests? BDD? jQuery?
  3. John Resig Survey: http://www.slideshare.net/jeresig/understanding-javascript-testing Counter each of these!!!!
  4. we wrote something we otherwise would have outsourced to Flash developers-- demo method explorer
  5. # nested describes--- # need button to go to next fieldset it(&quot;should add &apos;next&apos; button to first fieldset&quot;, function() { expect($(&quot;form fieldset:first a&quot;).text()).to(equal, &apos;Next&apos;); }); it(&quot;should add &apos;next&apos; class to next button&quot;, function() { expect($(&quot;form fieldset:first a&quot;).hasClass(&apos;next&apos;)).to(equal, true); }); it(&quot;should add &apos;next&apos; button to second fieldset&quot;, function() { expect($(&quot;form fieldset:nth(1) a:last&quot;).text()).to(equal, &apos;Next&apos;); }); it(&quot;should not add &apos;next&apos; buttons to last fieldset&quot;, function() { expect($(&quot;form fieldset:last a&quot;).text()).to(equal, &apos;&apos;); }); # code $(&apos;fieldset:not(:last)&apos;).each(function() { $(this).append(&apos;&lt;a class=&quot;next&quot;&gt;Next&lt;/a&gt;&apos;) });
  6. ./script/generate javascript_spec wiz # create fixture &lt;form action=&quot;application.html&quot;&gt; &lt;fieldset title=&quot;A&quot;&gt;&lt;input type=&quot;text&quot; value=&quot;a&quot;/&gt;&lt;/fieldset&gt; &lt;fieldset title=&quot;B&quot;&gt;&lt;input type=&quot;text&quot; value=&quot;b&quot;/&gt;&lt;/fieldset&gt; &lt;fieldset title=&quot;C&quot;&gt;&lt;input type=&quot;text&quot; value=&quot;c&quot;/&gt;&lt;/fieldset&gt; &lt;/form&gt; # create simple test describe(&apos;initialization&apos;, function() { it(&quot;shows the first fieldset&quot;, function(){ expect($(&quot;form fieldset:first&quot;).is(&apos;:visible&apos;)).to(equal, true); }); }); # run from command line # tests that fail it(&quot;hides the second and third fieldset&quot;, function(){ expect($(&quot;form fieldset:not(:first)&quot;).is(&apos;:visible&apos;)).to(equal, false); }); # run from command line # write code in before block var wizardize = function() { $(&apos;form&apos;).each(function() { $(&apos;fieldset&apos;, this).hide(); $(&apos;fieldset:first&apos;, this).show(); });
  7. mkdir demo cd demo rails demo cd demo ./script/plugin install git://github.com/relevance/blue-ridge.git ./script/generate blue_ridge
  8. mkdir demo cd demo rails demo cd demo ./script/plugin install git://github.com/relevance/blue-ridge.git ./script/generate blue_ridge