SlideShare a Scribd company logo
JavaScript Testing
                 John Resig
http://ejohn.org/ - http://twitter.com/jeresig
Why Test JavaScript?
✦   Cross-browser issues.
✦   The possibility for causing an unforeseen
    problem is simply too great.
What should I use?
Looong Tail

250.0


187.5


125.0


 62.5


   0


               Other
People don’t test. :-(

900


675


450


225


  0


                         None
Basic Components
✦   Writing and understanding a JavaScript
    test suite is easy.
✦   Test Suite
    ✦ Tests
      ✦ Assertions
    ✦ Async Tests

✦   Test Runner
Assertions
   <html> 
   <head> 
     <title>Test Suite</title> 
     <script> 
     function assert( value, desc ) { 
       var li = document.createElement("li"); 
       li.className = value ? "pass" : "fail"; 
       li.appendChild( document.createTextNode( desc ) ); 
       document.getElementById("results").appendChild( li ); 
     } 
                                    
     window.onload = function(){ 
       assert( true, "The test suite is running." ); 
     }; 
     </script> 
     <style> 
       #results li.pass { color: green; } 
       #results li.fail { color: red; } 
     </style> 
   </head> 
   <body> 
     <ul id="results"></ul> 
   </body> 
   </html> 
Tests
      test("A test.", function(){ 
        assert( true, "First assertion completed" ); 
        assert( true, "Second assertion completed" ); 
        assert( true, "Third assertion completed" ); 
      }); 
                                  
      test("Another test.", function(){ 
        assert( true, "First test completed" ); 
        assert( false, "Second test failed" ); 
        assert( true, "Third assertion completed" ); 
      }); 
Tests
    var results; 
                                  
    function assert( value, desc ) { 
      var li = document.createElement("li"); 
      li.className = value ? "pass" : "fail"; 
      li.appendChild( document.createTextNode( desc ) ); 
      results.appendChild( li ); 
      if ( !value ) { 
        li.parentNode.parentNode.className = "fail"; 
      } 
      return li; 
    } 
                                  
    function test(name, fn){ 
      results = document.getElementById("results"); 
      results = assert( true, name ).appendChild( 
        document.createElement("ul") ); 
      fn(); 
    } 
Async Tests
    test(function(){ 
      pause(); 
      setTimeout(function(){ 
        assert( true, "First test completed" ); 
        resume(); 
      }, 100); 
    }); 
                            
    test(function(){ 
      pause(); 
      setTimeout(function(){ 
        assert( true, "Second test completed" ); 
        resume(); 
      }, 200); 
    }); 
Async Tests
      (function(){ 
        var queue = [], paused = false; 
                             
        this.test = function(fn){ 
          queue.push( fn ); 
          runTest(); 
        }; 
                             
        this.pause = function(){ 
          paused = true; 
        }; 
                             
        this.resume = function(){ 
          paused = false; 
          setTimeout(runTest, 1); 
        }; 
                             
        function runTest(){ 
          if ( !paused && queue.length ) { 
            queue.shift()(); 
            if ( !paused ) { 
              resume(); 
            } 
          } 
        } 
      })(); 
TestRunner
✦   Responsible for loading an executing tests.
✦   Sometimes individual test groups can run
    standalone (Dojo) sometimes they require
    the test runner (QUnit, JSUnit).
Popular Test Frameworks

250.0


187.5


125.0


 62.5


   0
        QUnit   JSUnit   Selenium YUITest FireUnit Screw.Unit JSSpec
Unit Testing
✦   Break code into logical chucks for testing.
✦   Focus on one method at a time.
✦   Popular Frameworks:
    ✦ QUnit
    ✦ JSUnit
    ✦ YUITest
QUnit
✦   Unit Testing framework built for jQuery.
✦   Additional features:
    ✦ Supports asynchronous testing.
    ✦ Can break code into modules.
    ✦ Supports test timeouts.

✦   http://docs.jquery.com/QUnit
QUnit Style
   test("a basic test example", function() { 
     ok( true, "this test is fine" ); 
     var value = "hello"; 
     equals( "hello", value, "We expect value to be hello" ); 
   }); 
                                  
   module("Module A"); 
                                  
   test("first test within module", function() { 
     ok( true, "all pass" ); 
   }); 
                                  
   test("second test within module", function() { 
     ok( true, "all pass" ); 
   }); 
                                  
   module("Module B"); 
                                  
   test("some other test", function() { 
     expect(2); 
     equals( true, false, "failing test" ); 
     equals( true, true, "passing test" ); 
   }); 
QUnit
JSUnit
✦   One of the oldest JavaScript testing
    frameworks.
✦   A port of JUnit to JavaScript, circa 2001.
✦   Code feels very 2001 (frames!)
✦   http://www.jsunit.net/
JSUnit
        function coreSuite() { 
            var result = new top.jsUnitTestSuite(); 
            result.addTestPage("tests/jsUnitAssertionTests.html"); 
            result.addTestPage("tests/jsUnitSetUpTearDownTests.html"); 
            result.addTestPage("tests/jsUnitRestoredHTMLDivTests.html"); 
            result.addTestPage("tests/jsUnitFrameworkUtilityTests.html"); 
            result.addTestPage("tests/jsUnitOnLoadTests.html"); 
            result.addTestPage("tests/jsUnitUtilityTests.html"); 
            return result; 
        } 
                                               
        function serverSuite() { 
            var result = new top.jsUnitTestSuite(); 
            result.addTestPage("tests/server/jsUnitVersionCheckTests.html"); 
            result.addTestPage("tests/server/jsUnitServerAjaxTests.html"); 
            return result; 
        } 
                                               
        function librariesSuite() { 
            var result = new top.jsUnitTestSuite(); 
            result.addTestPage("tests/jsUnitMockTimeoutTest.html"); 
            return result; 
        } 
                                               
        function suite() { 
            var newsuite = new top.jsUnitTestSuite(); 
            newsuite.addTestSuite(coreSuite()); 
            newsuite.addTestSuite(serverSuite()); 
            newsuite.addTestSuite(librariesSuite()); 
            return newsuite; 
        }
JSUnit
   function testAssertNotUndefined() { 
       assertNotUndefined("1 should not be undefined", 1); 
       assertNotUndefined(1); 
   } 
                                             
   function testAssertNaN() { 
       assertNaN("a string should not be a number", "string"); 
       assertNaN("string"); 
   } 
                                             
   function testAssertNotNaN() { 
       assertNotNaN("1 should not be not a number", 1); 
       assertNotNaN(1); 
   } 
                                             
   function testFail() { 
       var excep = null; 
       try { 
           fail("Failure message"); 
       } catch (e) { 
           excep = e; 
       } 
       assertJsUnitException("fail(string) should throw a JsUnitException", excep); 
   } 
                                             
   function testTooFewArguments() { 
       var excep = null; 
       try { 
           assert(); 
       } catch (e1) { 
           excep = e1; 
       } 
       assertNonJsUnitException("Calling an assertion function with too 
         few arguments should throw an exception", excep); 
   }
JSUnit
YUITest (2 & 3)
✦   Testing framework built and developed by
    Yahoo (released Oct 2008).
✦   Completely overhauled to go with YUI v3.
✦   Features:
    ✦ Supports async tests.
    ✦ Has good event simulation.

✦   v2: http://developer.yahoo.com/yui/
    examples/yuitest/
✦   v3: http://developer.yahoo.com/yui/3/test/
YUITest 2
   YAHOO.example.yuitest.ArrayTestCase = new YAHOO.tool.TestCase({ 
      name : "Array Tests", 
                                         
      setUp : function () { 
          this.data = [0,1,2,3,4] 
      }, 
                                         
      tearDown : function () { 
          delete this.data; 
      }, 
                                           
      testPop : function () { 
          var Assert = YAHOO.util.Assert;          
          var value = this.data.pop(); 
                                             
          Assert.areEqual(4, this.data.length); 
          Assert.areEqual(4, value);             
      },         
                                         
      testPush : function () { 
          var Assert = YAHOO.util.Assert; 
                                             
          this.data.push(5); 
                                             
          Assert.areEqual(6, this.data.length); 
          Assert.areEqual(5, this.data[5]);             
      }
  }); 
YUITest 2
YUITest 3
    Y.example.test.DataTestCase = new Y.Test.Case({ 
        name : "Data Tests", 
                                        
        setUp : function () { 
            this.data = { 
                name: "test", 
                year: 2007, 
                beta: true 
            }; 
        }, 
         
        tearDown : function () { 
            delete this.data; 
        }, 
                                        
        testName : function () { 
            var Assert = Y.Assert; 
                                            
            Assert.isObject(this.data); 
            Assert.isString(this.data.name); 
            Assert.areEqual("test", this.data.name);             
        }, 
                                        
        testYear : function () { 
            var Assert = Y.Assert; 
                                            
            Assert.isObject(this.data); 
            Assert.isNumber(this.data.year); 
            Assert.areEqual(2007, this.data.year);             
        }
    }); 
YUITest 3
Behavior Testing
✦   Similar to unit testing, but broken up by
    task.
✦   Functionally very similar to unit testing,
    uses different terminology
✦   Popular frameworks:
    ✦ Screw.Unit
    ✦ JSSpec
Screw.Unit
✦   Popular BDD framework.
✦   http://github.com/nathansobo/screw-unit/
    tree/master
Screw.Unit
 describe("a nested describe", function() { 
   var invocations = []; 
                                     
   before(function() { 
     invocations.push("before"); 
   }); 
                                     
   describe("a doubly nested describe", function() { 
     before(function() { 
       invocations.push('inner before'); 
     }); 
                                     
     it("runs befores in all ancestors prior to an it", function() { 
       expect(invocations).to(equal, ["before", "inner before"]); 
     }); 
   }); 
 }); 
Screw.Unit
JSSpec
✦   Used by MooTools as their testing
    framework.
✦   http://jania.pe.kr/aw/moin.cgi/JSSpec
JSSpec
   describe('"Should have"s', { 
     'String length': function() { 
       expect("Hello").should_have(4, "characters"); 
     }, 
     'Array length': function() { 
       expect([1,2,3]).should_have(4, "items"); 
     }, 
     'Object's item length': function() { 
       expect({name:'Alan Kang', email:'jania902@gmail.com',
         accounts:['A', 'B']}).should_have(3, "accounts"); 
     }, 
     'No match': function() { 
       expect("This is a string").should_have(5, "players"); 
     }, 
     'Exactly': function() { 
       expect([1,2,3]).should_have_exactly(2, "items"); 
     }, 
     'At least': function() { 
       expect([1,2,3]).should_have_at_least(4, "items"); 
     }, 
     'At most': function() { 
       expect([1,2,3]).should_have_at_most(2, "items"); 
     } 
   }) 
JSSpec
Automation
✦   Functional Testing
✦   Browser launching
✦   Server-Side
Functional Testing
✦   Selenium IDE
✦   There may be others by Selenium is far
    and away the best.
Selenium IDE
✦   Records and automates actions performed
    by a user.
✦   An extension for Firefox that records the
    actions.
✦   Can play them back in all browsers
    (limited by cross-domain issues).
✦   Primarily for testing web applications -
    everyone should use it, though!
✦   http://seleniumhq.org/projects/ide/
Selenium IDE
Browser Launching
✦   Automates the process of opening browser
    windows, running tests, and getting results.
✦   Frequently require a specific framework.
✦   Popular frameworks:
    ✦ WebDriver http://code.google.com/p/
      webdriver/ (Java)
    ✦ Waitr http://wtr.rubyforge.org/ (Ruby)
    ✦ JsTestDriver http://code.google.com/p/
      js-test-driver/ (Java)
    ✦ Selenium RC http://seleniumhq.org/
      projects/remote-control/ (Java)
Browser Launching
Server-Side
✦   Ignore the browser! Simulate it on the
    server-side.
✦   Almost always uses Java + Rhino to
    construct a browser.
✦   Some frameworks:
    ✦ Crosscheck
    ✦ Env.js
    ✦ Blueridge
Server-Side
✦   Crosscheck
    ✦ Pure Java, even simulates browser bugs.
    ✦ http://www.thefrontside.net/crosscheck

✦   Env.js
    ✦ Pure JavaScript, focuses on standards
      support.
    ✦ http://github.com/thatcher/env-js/tree/
      master
✦   Blueridge
    ✦ Env.js + Screw.Unit + Rhino
    ✦ http://github.com/relevance/blue-ridge/
Env.js
  $ java -jar build/js.jar
  Rhino 1.6 release 6 2007 06 28
  js> load('build/runtest/env.js');

  js> window.location = 'test/index.html';
  test/index.html

  js> load('dist/jquery.js');

  // Add pretty printing to jQuery objects:
  js> jQuery.fn.toString = DOMNodeList.prototype.toString;

  js> $('span').remove();
  [ <span#å°åŒ—Taibei>, <span#å°åŒ—>, <span#utf8class1>,
    <span#utf8class2>, <span#foo:bar>, <span#test.foo[5]bar> ]

  // Yes - UTF-8 is supported in DOM documents!
  js> $('span')
  [ ]

  js> $('div').append('<span><b>hello!</b> world</span>');
  [ <div#main>, <div#foo> ]

  js> $('span')
  [ <span>, <span> ]

  js> $('span').text()
  hello! worldhello! world
Distributed
✦   Selenium Grid
    ✦ Push Selenium tests out to many
      machines (that you manage),
      simultaneously.
    ✦ Collect and store the results.
    ✦ http://selenium-grid.seleniumhq.org/

✦   TestSwarm
    ✦ Push tests to a distributed swarm of
      clients.
    ✦ Results viewable on the server.
    ✦ http://testswarm.com/
TestSwarm
Choose Your Browsers
Cost / Benefit




  IE 7     IE 6          FF 3    Safari 3   Opera 9.5
                  Cost          Benefit


         Draw a line in the sand.
Graded Support




   Yahoo Browser Compatibility
Browser Support Grid
           IE      Firefox   Safari   Opera Chrome


Previous   6.0       2.0      3.0      9.5


Current    7.0       3.0      3.2      9.6    1.0


 Next      8.0       3.1      4.0     10.0    2.0

                 jQuery Browser Support
Browser Support Grid
           IE       Firefox   Safari   Opera Chrome


Previous   6.0        2.0      3.0      9.5


Current    7.0        3.0      3.2      9.6    1.0


 Next      8.0        3.1      4.0     10.0    2.0

                jQuery 1.3 Browser Support
The Scaling Problem
✦   The Problem:
    ✦ jQuery has 6 test suites
    ✦ Run in 11 browsers
    ✦ (Not even including multiple platforms!)

✦   All need to be run for every commit,
    patch, and plugin.
✦   JavaScript testing doesn’t scale well.
Distributed Testing
✦   Hub server
✦   Clients connect and help run tests
✦   A simple JavaScript client that can be run
    in all browsers
    ✦ Including mobile browsers!


✦ TestSwarm
FF 3.5 FF 3.5 FF 3.5
                                                  IE 6
                                                         IE 6
       FF 3                                                      IE 6
                                           Op 9
FF 3

                                                                 IE 7

                               TestSwarm
                                                                  IE 7




              Test Suite        Test Suite          Test Suite
Manual Testing
✦   Push tests to users who follow pre-defined
    steps
✦   Answer ‘Yes’/’No’ questions which are
    pushed back to the server.
✦   An effective way to distribute manual test
    load to dozens of clients.
TestSwarm.com
✦   Incentives for top testers (t-shirts, books)
✦   Will be opening for alpha testing very soon
✦   Help your favorite JavaScript library
    become better tested!
✦   http://testswarm.com
Questions
✦   Contact:
    ✦ John Resig
    ✦ http://ejohn.org/
    ✦ http://twitter.com/jeresig

✦   More info:
    ✦ http://jsninja.com/Overview
    ✦ http://ejohn.org/blog/javascript-testing-
      does-not-scale/

More Related Content

PPTX
Understanding JavaScript Testing
PDF
Adventures In JavaScript Testing
PDF
Testing, Performance Analysis, and jQuery 1.4
PDF
Testing JavaScript Applications
PPTX
Qunit Java script Un
PDF
Stop Making Excuses and Start Testing Your JavaScript
PPTX
Testing with VS2010 - A Bugs Life
PDF
Developer Test - Things to Know
Understanding JavaScript Testing
Adventures In JavaScript Testing
Testing, Performance Analysis, and jQuery 1.4
Testing JavaScript Applications
Qunit Java script Un
Stop Making Excuses and Start Testing Your JavaScript
Testing with VS2010 - A Bugs Life
Developer Test - Things to Know

What's hot (20)

PDF
An introduction to Google test framework
PDF
GeeCON 2012 Bad Tests, Good Tests
PDF
Confitura 2012 Bad Tests, Good Tests
PDF
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
PDF
Testing javascript in the frontend
PDF
Painless JavaScript Testing with Jest
PDF
Agile Swift
PDF
Agile Android
PDF
JS and patterns
PDF
Redux for ReactJS Programmers
PDF
33rd Degree 2013, Bad Tests, Good Tests
PDF
Jasmine - why JS tests don't smell fishy
PDF
Advanced Jasmine - Front-End JavaScript Unit Testing
PPT
xUnit Style Database Testing
PDF
JUnit Kung Fu: Getting More Out of Your Unit Tests
PDF
C++ Unit Test with Google Testing Framework
PDF
Unit tests in node.js
PPT
2012 JDays Bad Tests Good Tests
PDF
PL/SQL Unit Testing Can Be Fun!
ODP
Unit testing with Easymock
An introduction to Google test framework
GeeCON 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good Tests
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Testing javascript in the frontend
Painless JavaScript Testing with Jest
Agile Swift
Agile Android
JS and patterns
Redux for ReactJS Programmers
33rd Degree 2013, Bad Tests, Good Tests
Jasmine - why JS tests don't smell fishy
Advanced Jasmine - Front-End JavaScript Unit Testing
xUnit Style Database Testing
JUnit Kung Fu: Getting More Out of Your Unit Tests
C++ Unit Test with Google Testing Framework
Unit tests in node.js
2012 JDays Bad Tests Good Tests
PL/SQL Unit Testing Can Be Fun!
Unit testing with Easymock
Ad

Viewers also liked (20)

PPT
JavaScript Unit Testing
PDF
JavaScript Libraries (Ajax Exp 2006)
PDF
Processing and Processing.js
PDF
JavaScript Libraries (Kings of Code)
PDF
jQuery Internals + Cool Stuff
PDF
Testing Mobile JavaScript (Fall 2010
PDF
Secrets of JavaScript Libraries
PDF
Khan Academy Computer Science
PPTX
Testing React Applications
PDF
War of Attrition: AWS vs. Google, IBM and Microsoft Azure
PDF
Javascript Unit Testting (PHPBenelux 2011-05-04)
PPTX
Testing of React JS app
PPTX
Modular development with redux
PDF
Workshop 23: ReactJS, React & Redux testing
PDF
Advanced QUnit - Front-End JavaScript Unit Testing
PDF
Building a JavaScript Library
PDF
JavaScript Test-Driven Development (TDD) with QUnit
PDF
Unit testing JavaScript using Mocha and Node
PDF
The Many Ways to Test Your React App
PDF
Unit Testing in JavaScript with MVC and QUnit
JavaScript Unit Testing
JavaScript Libraries (Ajax Exp 2006)
Processing and Processing.js
JavaScript Libraries (Kings of Code)
jQuery Internals + Cool Stuff
Testing Mobile JavaScript (Fall 2010
Secrets of JavaScript Libraries
Khan Academy Computer Science
Testing React Applications
War of Attrition: AWS vs. Google, IBM and Microsoft Azure
Javascript Unit Testting (PHPBenelux 2011-05-04)
Testing of React JS app
Modular development with redux
Workshop 23: ReactJS, React & Redux testing
Advanced QUnit - Front-End JavaScript Unit Testing
Building a JavaScript Library
JavaScript Test-Driven Development (TDD) with QUnit
Unit testing JavaScript using Mocha and Node
The Many Ways to Test Your React App
Unit Testing in JavaScript with MVC and QUnit
Ad

Similar to Understanding JavaScript Testing (20)

PDF
Js 单元测试框架介绍
KEY
Unittesting JavaScript with Evidence
PPTX
Junit 5 - Maior e melhor
PDF
How to write clean tests
PPTX
TestNG vs Junit
PPT
3 j unit
PDF
Unit testing with PHPUnit
PDF
Google guava
PDF
Test driven node.js
PPTX
Pragmatic unittestingwithj unit
PDF
PPT
Junit and testNG
PDF
Good Tests Bad Tests
PPTX
Testing basics for developers
PDF
Unit Testing Front End JavaScript
ODP
Data-Driven Unit Testing for Java
ODP
Good Practices On Test Automation
PDF
We Are All Testers Now: The Testing Pyramid and Front-End Development
PDF
PPTX
A Test of Strength
Js 单元测试框架介绍
Unittesting JavaScript with Evidence
Junit 5 - Maior e melhor
How to write clean tests
TestNG vs Junit
3 j unit
Unit testing with PHPUnit
Google guava
Test driven node.js
Pragmatic unittestingwithj unit
Junit and testNG
Good Tests Bad Tests
Testing basics for developers
Unit Testing Front End JavaScript
Data-Driven Unit Testing for Java
Good Practices On Test Automation
We Are All Testers Now: The Testing Pyramid and Front-End Development
A Test of Strength

More from jeresig (20)

PDF
Does Coding Every Day Matter?
PDF
Accidentally Becoming a Digital Librarian
PDF
2014: John's Favorite Thing (Neo4j)
PDF
Computer Vision as Art Historical Investigation
PDF
Hacking Art History
PDF
Using JS to teach JS at Khan Academy
PDF
Applying Computer Vision to Art History
PDF
NYARC 2014: Frick/Zeri Results
PDF
EmpireJS: Hacking Art with Node js and Image Analysis
PDF
Applying Computer Vision to Art History
PDF
Introduction to jQuery (Ajax Exp 2006)
PDF
jQuery Recommendations to the W3C (2011)
PDF
jQuery Open Source Process (RIT 2011)
PDF
jQuery Open Source Process (Knight Foundation 2011)
PDF
jQuery Mobile
PDF
jQuery Open Source (Fronteer 2011)
PDF
Holistic JavaScript Performance
PDF
New Features Coming in Browsers (RIT '09)
PDF
Introduction to jQuery (Ajax Exp 2007)
PDF
Advanced jQuery (Ajax Exp 2007)
Does Coding Every Day Matter?
Accidentally Becoming a Digital Librarian
2014: John's Favorite Thing (Neo4j)
Computer Vision as Art Historical Investigation
Hacking Art History
Using JS to teach JS at Khan Academy
Applying Computer Vision to Art History
NYARC 2014: Frick/Zeri Results
EmpireJS: Hacking Art with Node js and Image Analysis
Applying Computer Vision to Art History
Introduction to jQuery (Ajax Exp 2006)
jQuery Recommendations to the W3C (2011)
jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (Knight Foundation 2011)
jQuery Mobile
jQuery Open Source (Fronteer 2011)
Holistic JavaScript Performance
New Features Coming in Browsers (RIT '09)
Introduction to jQuery (Ajax Exp 2007)
Advanced jQuery (Ajax Exp 2007)

Recently uploaded (20)

PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
A Presentation on Artificial Intelligence
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Big Data Technologies - Introduction.pptx
PDF
KodekX | Application Modernization Development
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
Chapter 3 Spatial Domain Image Processing.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
A Presentation on Artificial Intelligence
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Unlocking AI with Model Context Protocol (MCP)
Big Data Technologies - Introduction.pptx
KodekX | Application Modernization Development
Review of recent advances in non-invasive hemoglobin estimation
Digital-Transformation-Roadmap-for-Companies.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Per capita expenditure prediction using model stacking based on satellite ima...
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Encapsulation_ Review paper, used for researhc scholars
The Rise and Fall of 3GPP – Time for a Sabbatical?
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Understanding_Digital_Forensics_Presentation.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf

Understanding JavaScript Testing

  • 1. JavaScript Testing John Resig http://ejohn.org/ - http://twitter.com/jeresig
  • 2. Why Test JavaScript? ✦ Cross-browser issues. ✦ The possibility for causing an unforeseen problem is simply too great.
  • 5. People don’t test. :-( 900 675 450 225 0 None
  • 6. Basic Components ✦ Writing and understanding a JavaScript test suite is easy. ✦ Test Suite ✦ Tests ✦ Assertions ✦ Async Tests ✦ Test Runner
  • 7. Assertions  <html>   <head>     <title>Test Suite</title>     <script>     function assert( value, desc ) {       var li = document.createElement("li");       li.className = value ? "pass" : "fail";       li.appendChild( document.createTextNode( desc ) );       document.getElementById("results").appendChild( li );     }          window.onload = function(){       assert( true, "The test suite is running." );     };     </script>     <style>       #results li.pass { color: green; }       #results li.fail { color: red; }     </style>   </head>   <body>     <ul id="results"></ul>   </body>   </html> 
  • 8. Tests      test("A test.", function(){         assert( true, "First assertion completed" );         assert( true, "Second assertion completed" );         assert( true, "Third assertion completed" );       });              test("Another test.", function(){         assert( true, "First test completed" );         assert( false, "Second test failed" );         assert( true, "Third assertion completed" );       }); 
  • 9. Tests    var results;          function assert( value, desc ) {       var li = document.createElement("li");       li.className = value ? "pass" : "fail";       li.appendChild( document.createTextNode( desc ) );       results.appendChild( li );       if ( !value ) {         li.parentNode.parentNode.className = "fail";       }       return li;     }          function test(name, fn){       results = document.getElementById("results");       results = assert( true, name ).appendChild(         document.createElement("ul") );       fn();     } 
  • 10. Async Tests  test(function(){     pause();     setTimeout(function(){       assert( true, "First test completed" );       resume();     }, 100);   });      test(function(){     pause();     setTimeout(function(){       assert( true, "Second test completed" );       resume();     }, 200);   }); 
  • 11. Async Tests  (function(){     var queue = [], paused = false;          this.test = function(fn){       queue.push( fn );       runTest();     };          this.pause = function(){       paused = true;     };          this.resume = function(){       paused = false;       setTimeout(runTest, 1);     };          function runTest(){       if ( !paused && queue.length ) {         queue.shift()();         if ( !paused ) {           resume();         }       }     }   })(); 
  • 12. TestRunner ✦ Responsible for loading an executing tests. ✦ Sometimes individual test groups can run standalone (Dojo) sometimes they require the test runner (QUnit, JSUnit).
  • 13. Popular Test Frameworks 250.0 187.5 125.0 62.5 0 QUnit JSUnit Selenium YUITest FireUnit Screw.Unit JSSpec
  • 14. Unit Testing ✦ Break code into logical chucks for testing. ✦ Focus on one method at a time. ✦ Popular Frameworks: ✦ QUnit ✦ JSUnit ✦ YUITest
  • 15. QUnit ✦ Unit Testing framework built for jQuery. ✦ Additional features: ✦ Supports asynchronous testing. ✦ Can break code into modules. ✦ Supports test timeouts. ✦ http://docs.jquery.com/QUnit
  • 16. QUnit Style  test("a basic test example", function() {     ok( true, "this test is fine" );     var value = "hello";     equals( "hello", value, "We expect value to be hello" );   });      module("Module A");      test("first test within module", function() {     ok( true, "all pass" );   });      test("second test within module", function() {     ok( true, "all pass" );   });      module("Module B");      test("some other test", function() {     expect(2);     equals( true, false, "failing test" );     equals( true, true, "passing test" );   }); 
  • 17. QUnit
  • 18. JSUnit ✦ One of the oldest JavaScript testing frameworks. ✦ A port of JUnit to JavaScript, circa 2001. ✦ Code feels very 2001 (frames!) ✦ http://www.jsunit.net/
  • 19. JSUnit        function coreSuite() {             var result = new top.jsUnitTestSuite();             result.addTestPage("tests/jsUnitAssertionTests.html");             result.addTestPage("tests/jsUnitSetUpTearDownTests.html");             result.addTestPage("tests/jsUnitRestoredHTMLDivTests.html");             result.addTestPage("tests/jsUnitFrameworkUtilityTests.html");             result.addTestPage("tests/jsUnitOnLoadTests.html");             result.addTestPage("tests/jsUnitUtilityTests.html");             return result;         }                  function serverSuite() {             var result = new top.jsUnitTestSuite();             result.addTestPage("tests/server/jsUnitVersionCheckTests.html");             result.addTestPage("tests/server/jsUnitServerAjaxTests.html");             return result;         }                  function librariesSuite() {             var result = new top.jsUnitTestSuite();             result.addTestPage("tests/jsUnitMockTimeoutTest.html");             return result;         }                  function suite() {             var newsuite = new top.jsUnitTestSuite();             newsuite.addTestSuite(coreSuite());             newsuite.addTestSuite(serverSuite());             newsuite.addTestSuite(librariesSuite());             return newsuite;         }
  • 20. JSUnit  function testAssertNotUndefined() {       assertNotUndefined("1 should not be undefined", 1);       assertNotUndefined(1);   }      function testAssertNaN() {       assertNaN("a string should not be a number", "string");       assertNaN("string");   }      function testAssertNotNaN() {       assertNotNaN("1 should not be not a number", 1);       assertNotNaN(1);   }      function testFail() {       var excep = null;       try {           fail("Failure message");       } catch (e) {           excep = e;       }       assertJsUnitException("fail(string) should throw a JsUnitException", excep);   }      function testTooFewArguments() {       var excep = null;       try {           assert();       } catch (e1) {           excep = e1;       }       assertNonJsUnitException("Calling an assertion function with too  few arguments should throw an exception", excep);   }
  • 22. YUITest (2 & 3) ✦ Testing framework built and developed by Yahoo (released Oct 2008). ✦ Completely overhauled to go with YUI v3. ✦ Features: ✦ Supports async tests. ✦ Has good event simulation. ✦ v2: http://developer.yahoo.com/yui/ examples/yuitest/ ✦ v3: http://developer.yahoo.com/yui/3/test/
  • 23. YUITest 2   YAHOO.example.yuitest.ArrayTestCase = new YAHOO.tool.TestCase({       name : "Array Tests",              setUp : function () {           this.data = [0,1,2,3,4]       },              tearDown : function () {           delete this.data;       },                testPop : function () {           var Assert = YAHOO.util.Assert;                    var value = this.data.pop();                      Assert.areEqual(4, this.data.length);           Assert.areEqual(4, value);                   },                      testPush : function () {           var Assert = YAHOO.util.Assert;                      this.data.push(5);                      Assert.areEqual(6, this.data.length);           Assert.areEqual(5, this.data[5]);                   }  }); 
  • 25. YUITest 3  Y.example.test.DataTestCase = new Y.Test.Case({       name : "Data Tests",              setUp : function () {           this.data = {               name: "test",               year: 2007,               beta: true           };       },              tearDown : function () {           delete this.data;       },              testName : function () {           var Assert = Y.Assert;                      Assert.isObject(this.data);           Assert.isString(this.data.name);           Assert.areEqual("test", this.data.name);                   },              testYear : function () {           var Assert = Y.Assert;                      Assert.isObject(this.data);           Assert.isNumber(this.data.year);           Assert.areEqual(2007, this.data.year);                   }  }); 
  • 27. Behavior Testing ✦ Similar to unit testing, but broken up by task. ✦ Functionally very similar to unit testing, uses different terminology ✦ Popular frameworks: ✦ Screw.Unit ✦ JSSpec
  • 28. Screw.Unit ✦ Popular BDD framework. ✦ http://github.com/nathansobo/screw-unit/ tree/master
  • 29. Screw.Unit  describe("a nested describe", function() {     var invocations = [];        before(function() {       invocations.push("before");     });        describe("a doubly nested describe", function() {       before(function() {         invocations.push('inner before');       });          it("runs befores in all ancestors prior to an it", function() {         expect(invocations).to(equal, ["before", "inner before"]);       });     });   }); 
  • 31. JSSpec ✦ Used by MooTools as their testing framework. ✦ http://jania.pe.kr/aw/moin.cgi/JSSpec
  • 32. JSSpec  describe('"Should have"s', {     'String length': function() {       expect("Hello").should_have(4, "characters");     },     'Array length': function() {       expect([1,2,3]).should_have(4, "items");     },     'Object's item length': function() {       expect({name:'Alan Kang', email:'jania902@gmail.com', accounts:['A', 'B']}).should_have(3, "accounts");     },     'No match': function() {       expect("This is a string").should_have(5, "players");     },     'Exactly': function() {       expect([1,2,3]).should_have_exactly(2, "items");     },     'At least': function() {       expect([1,2,3]).should_have_at_least(4, "items");     },     'At most': function() {       expect([1,2,3]).should_have_at_most(2, "items");     }   }) 
  • 34. Automation ✦ Functional Testing ✦ Browser launching ✦ Server-Side
  • 35. Functional Testing ✦ Selenium IDE ✦ There may be others by Selenium is far and away the best.
  • 36. Selenium IDE ✦ Records and automates actions performed by a user. ✦ An extension for Firefox that records the actions. ✦ Can play them back in all browsers (limited by cross-domain issues). ✦ Primarily for testing web applications - everyone should use it, though! ✦ http://seleniumhq.org/projects/ide/
  • 38. Browser Launching ✦ Automates the process of opening browser windows, running tests, and getting results. ✦ Frequently require a specific framework. ✦ Popular frameworks: ✦ WebDriver http://code.google.com/p/ webdriver/ (Java) ✦ Waitr http://wtr.rubyforge.org/ (Ruby) ✦ JsTestDriver http://code.google.com/p/ js-test-driver/ (Java) ✦ Selenium RC http://seleniumhq.org/ projects/remote-control/ (Java)
  • 40. Server-Side ✦ Ignore the browser! Simulate it on the server-side. ✦ Almost always uses Java + Rhino to construct a browser. ✦ Some frameworks: ✦ Crosscheck ✦ Env.js ✦ Blueridge
  • 41. Server-Side ✦ Crosscheck ✦ Pure Java, even simulates browser bugs. ✦ http://www.thefrontside.net/crosscheck ✦ Env.js ✦ Pure JavaScript, focuses on standards support. ✦ http://github.com/thatcher/env-js/tree/ master ✦ Blueridge ✦ Env.js + Screw.Unit + Rhino ✦ http://github.com/relevance/blue-ridge/
  • 42. Env.js $ java -jar build/js.jar Rhino 1.6 release 6 2007 06 28 js> load('build/runtest/env.js'); js> window.location = 'test/index.html'; test/index.html js> load('dist/jquery.js'); // Add pretty printing to jQuery objects: js> jQuery.fn.toString = DOMNodeList.prototype.toString; js> $('span').remove(); [ <span#å°åŒ—Taibei>, <span#å°åŒ—>, <span#utf8class1>, <span#utf8class2>, <span#foo:bar>, <span#test.foo[5]bar> ] // Yes - UTF-8 is supported in DOM documents! js> $('span') [ ] js> $('div').append('<span><b>hello!</b> world</span>'); [ <div#main>, <div#foo> ] js> $('span') [ <span>, <span> ] js> $('span').text() hello! worldhello! world
  • 43. Distributed ✦ Selenium Grid ✦ Push Selenium tests out to many machines (that you manage), simultaneously. ✦ Collect and store the results. ✦ http://selenium-grid.seleniumhq.org/ ✦ TestSwarm ✦ Push tests to a distributed swarm of clients. ✦ Results viewable on the server. ✦ http://testswarm.com/
  • 46. Cost / Benefit IE 7 IE 6 FF 3 Safari 3 Opera 9.5 Cost Benefit Draw a line in the sand.
  • 47. Graded Support Yahoo Browser Compatibility
  • 48. Browser Support Grid IE Firefox Safari Opera Chrome Previous 6.0 2.0 3.0 9.5 Current 7.0 3.0 3.2 9.6 1.0 Next 8.0 3.1 4.0 10.0 2.0 jQuery Browser Support
  • 49. Browser Support Grid IE Firefox Safari Opera Chrome Previous 6.0 2.0 3.0 9.5 Current 7.0 3.0 3.2 9.6 1.0 Next 8.0 3.1 4.0 10.0 2.0 jQuery 1.3 Browser Support
  • 50. The Scaling Problem ✦ The Problem: ✦ jQuery has 6 test suites ✦ Run in 11 browsers ✦ (Not even including multiple platforms!) ✦ All need to be run for every commit, patch, and plugin. ✦ JavaScript testing doesn’t scale well.
  • 51. Distributed Testing ✦ Hub server ✦ Clients connect and help run tests ✦ A simple JavaScript client that can be run in all browsers ✦ Including mobile browsers! ✦ TestSwarm
  • 52. FF 3.5 FF 3.5 FF 3.5 IE 6 IE 6 FF 3 IE 6 Op 9 FF 3 IE 7 TestSwarm IE 7 Test Suite Test Suite Test Suite
  • 53. Manual Testing ✦ Push tests to users who follow pre-defined steps ✦ Answer ‘Yes’/’No’ questions which are pushed back to the server. ✦ An effective way to distribute manual test load to dozens of clients.
  • 54. TestSwarm.com ✦ Incentives for top testers (t-shirts, books) ✦ Will be opening for alpha testing very soon ✦ Help your favorite JavaScript library become better tested! ✦ http://testswarm.com
  • 55. Questions ✦ Contact: ✦ John Resig ✦ http://ejohn.org/ ✦ http://twitter.com/jeresig ✦ More info: ✦ http://jsninja.com/Overview ✦ http://ejohn.org/blog/javascript-testing- does-not-scale/