SlideShare a Scribd company logo
1 of 27
JavaScript Testing
      for rubyists
Jasmine

• http://pivotal.github.com/jasmine/
• will be most familiar to Rubyists
• similar syntax to RSpec
• gem install jasmine
• integrates with rails
What I’m using


• jQuery (http://jquery.com)
• Web Mooch (http://github.com/kernow/
  webmooch)
var my_cool_loader = function(post_data){

  $.ajax({
    type:      'POST',
    url:       'load_some_data.html',
    data:      post_data,
    success: function(data){
       $('.result').html(data);
    },
    error:     function(){
       $('.notification').text('Something bad happened!');
    }
  });

};
var set_result_html = function(data){
   $('.result').html(data);
};

var set_notification_text = function(text){
   $('.notification').text(text);
};

var my_cool_loader = function(post_data){

  $.ajax({
    type:      'POST',
    url:       'load_some_data.html',
    data:      post_data,
    success: function(data){
       set_result_html(data);
    },
    error:     function(){
       set_notification_text('Something bad happened!');
    }
  });

};
var set_result_html = function(data){
   $('.result').html(data);
};

var set_notification_text = function(text){
   $('.notification').text(text);
};

var my_cool_loader = function(post_data){

  $.ajax({
    type:      'POST',
    url:       'load_some_data.html',
    data:      post_data,
    success: function(data){
       set_result_html(data);
    },
    error:     function(){
       set_notification_text('Something bad happened!');
    }
  });

};
describe("calling a function", function() {

  beforeEach(function() {
    set_result_html('<p>Hello World</p>');
  });

  it("should set the text of the .result element", function() {
    expect($('.result').html()).toEqual('<p>Hello World</p>');
  });

});
var my_cool_loader = function(post_data){

  $.ajax({
    type:      'POST',
    url:       'load_some_data.html',
    data:      post_data,
    success: function(data){
       $('.result').html(data);
    },
    error:     function(){
       $('.notification').text('Something bad happened!');
    }
  });

};
describe("my sweet feature", function() {

 beforeEach(function() {
  $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     my_cool_loader();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
describe("my sweet feature", function() {

 beforeEach(function() {
  $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     my_cool_loader();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
describe("my sweet feature", function() {

 beforeEach(function() {
  $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     my_cool_loader();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
describe("my sweet feature", function() {

 beforeEach(function() {
  $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     my_cool_loader();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
describe("my sweet feature", function() {

 beforeEach(function() {
  $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     my_cool_loader();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
describe("my sweet feature", function() {

  describe("when unsuccessful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ status: 404, statusText: 'File Not Found' });

     my_cool_loader();
   });

   it("should notify the user there was a problem", function() {
     expect($('.notification').text()).toEqual('Something bad happened!');
   });

  });
});
describe("my sweet feature", function() {

  describe("when unsuccessful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ status: 404, statusText: 'File Not Found' });

     my_cool_loader();
   });

   it("should notify the user there was a problem", function() {
     expect($('.notification').text()).toEqual('Something bad happened!');
   });

  });
});
var my_cool_loader = function(post_data){

  $.ajax({
    type:      'POST',
    url:       'load_some_data.html',
    data:      post_data,
    success: function(data){
       $('.result').html(data);
    },
    error:     function(){
       $('.notification').text('Something bad happened!');
    }
  });

};
$('#my-button').click(function(){
  my_cool_loader({ foo: 'bar' });
});
describe("my sweet click feature", function() {

 beforeEach(function() {
   setup_button();
   $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     $('#my-button').click();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
describe("my sweet click feature", function() {

 beforeEach(function() {
   setup_button();
   $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     $('#my-button').click();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
describe("my sweet click feature", function() {

 beforeEach(function() {
   setup_button();
   $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>');
 });

 afterEach(function() {
   $('#jasmine_content').empty();
 });

 describe("when successful", function() {

   beforeEach(function() {
     Mooch.stub_request('POST', 'load_some_data.html').
       returns({ body: '<p>loaded html</p>' });

     $('#my-button').click();
   });

   it("should insert the received html into the result element", function() {
     expect($('.result').html()).toEqual('<p>loaded html</p>');
   });

  });
});
$('#text-input').keyup(function(e){
  if(e.which == 13){
    my_cool_loader({ foo: 'bar' });
  }
});
describe("when successful", function() {

 beforeEach(function() {
   Mooch.stub_request('POST', 'load_some_data.html').
     returns({ body: '<p>loaded html</p>' });

      // create a new keyup event
      var e = jQuery.Event("keyup");

      // set the key that was pressed to the enter key
      e.which = 13;

   // trigger the event on the textarea element
   $("#text-input").trigger(e);
 });

 it("should insert the received html into the result element", function() {
   expect($('.result').html()).toEqual('<p>loaded html</p>');
 });

});
describe("when successful", function() {

 beforeEach(function() {
   Mooch.stub_request('POST', 'load_some_data.html').
     returns({ body: '<p>loaded html</p>' });

      // create a new keyup event
      var e = jQuery.Event("keyup");

      // set the key that was pressed to the enter key
      e.which = 13;

   // trigger the event on the textarea element
   $("#text-input").trigger(e);
 });

 it("should insert the received html into the result element", function() {
   expect($('.result').html()).toEqual('<p>loaded html</p>');
 });

});
describe("when successful", function() {

 beforeEach(function() {
   Mooch.stub_request('POST', 'load_some_data.html').
     returns({ body: '<p>loaded html</p>' });

      // create a new keyup event
      var e = jQuery.Event("keyup");

      // set the key that was pressed to the enter key
      e.which = 13;

   // trigger the event on the textarea element
   $("#text-input").trigger(e);
 });

 it("should insert the received html into the result element", function() {
   expect($('.result').html()).toEqual('<p>loaded html</p>');
 });

});
describe("when successful", function() {

 beforeEach(function() {
   Mooch.stub_request('POST', 'load_some_data.html').
     returns({ body: '<p>loaded html</p>' });

      // create a new keyup event
      var e = jQuery.Event("keyup");

      // set the key that was pressed to the enter key
      e.which = 13;

   // trigger the event on the textarea element
   $("#text-input").trigger(e);
 });

 it("should insert the received html into the result element", function() {
   expect($('.result').html()).toEqual('<p>loaded html</p>');
 });

});
Whats different with JS
      testing?

• need to test in all your target browsers
• test suites don’t clean up (much) for you
• event driven programming can be hard to
  test
Multi Browser Testing

• Selenium
• Sauce Labs (http://saucelabs.com)
• saucelabs-adapter (http://github.com/
  pivotal/saucelabs-adapter)

More Related Content

What's hot

HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranRobert Nyman
 
Learning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User InterfacesLearning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User InterfacesKen Wheeler
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceIvan Chepurnyi
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript PromisesTomasz Bak
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Incremental Type Safety in React Apollo
Incremental Type Safety in React Apollo Incremental Type Safety in React Apollo
Incremental Type Safety in React Apollo Evans Hauser
 
Angular promises and http
Angular promises and httpAngular promises and http
Angular promises and httpAlexe Bogdan
 
AngularJS Services
AngularJS ServicesAngularJS Services
AngularJS ServicesEyal Vardi
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performanceYehuda Katz
 

What's hot (20)

HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - Altran
 
Learning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User InterfacesLearning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User Interfaces
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Frontin like-a-backer
Frontin like-a-backerFrontin like-a-backer
Frontin like-a-backer
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Incremental Type Safety in React Apollo
Incremental Type Safety in React Apollo Incremental Type Safety in React Apollo
Incremental Type Safety in React Apollo
 
Angular promises and http
Angular promises and httpAngular promises and http
Angular promises and http
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
AngularJS Services
AngularJS ServicesAngularJS Services
AngularJS Services
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
 

Similar to JavaScript Testing for Rubyists with Jasmine

Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applicationsSteve Smith
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page ApplicationsSteve Smith
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web ModuleMorgan Cheng
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptRyan Anklam
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for JoomlaLuke Summerfield
 
[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docxgerardkortney
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyHuiyi Yan
 
amsterdamjs - jQuery 1.5
amsterdamjs - jQuery 1.5amsterdamjs - jQuery 1.5
amsterdamjs - jQuery 1.5mennovanslooten
 

Similar to JavaScript Testing for Rubyists with Jasmine (20)

jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Alert
AlertAlert
Alert
 
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applications
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page Applications
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web Module
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for Joomla
 
[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx
 
jQuery
jQueryjQuery
jQuery
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
 
Javascript - Beyond-jQuery
Javascript - Beyond-jQueryJavascript - Beyond-jQuery
Javascript - Beyond-jQuery
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
BVJS
BVJSBVJS
BVJS
 
amsterdamjs - jQuery 1.5
amsterdamjs - jQuery 1.5amsterdamjs - jQuery 1.5
amsterdamjs - jQuery 1.5
 
Intoduction to php restful web service
Intoduction to php  restful web serviceIntoduction to php  restful web service
Intoduction to php restful web service
 

JavaScript Testing for Rubyists with Jasmine

  • 1. JavaScript Testing for rubyists
  • 2. Jasmine • http://pivotal.github.com/jasmine/ • will be most familiar to Rubyists • similar syntax to RSpec • gem install jasmine • integrates with rails
  • 3. What I’m using • jQuery (http://jquery.com) • Web Mooch (http://github.com/kernow/ webmooch)
  • 4. var my_cool_loader = function(post_data){ $.ajax({ type: 'POST', url: 'load_some_data.html', data: post_data, success: function(data){ $('.result').html(data); }, error: function(){ $('.notification').text('Something bad happened!'); } }); };
  • 5. var set_result_html = function(data){ $('.result').html(data); }; var set_notification_text = function(text){ $('.notification').text(text); }; var my_cool_loader = function(post_data){ $.ajax({ type: 'POST', url: 'load_some_data.html', data: post_data, success: function(data){ set_result_html(data); }, error: function(){ set_notification_text('Something bad happened!'); } }); };
  • 6. var set_result_html = function(data){ $('.result').html(data); }; var set_notification_text = function(text){ $('.notification').text(text); }; var my_cool_loader = function(post_data){ $.ajax({ type: 'POST', url: 'load_some_data.html', data: post_data, success: function(data){ set_result_html(data); }, error: function(){ set_notification_text('Something bad happened!'); } }); };
  • 7. describe("calling a function", function() { beforeEach(function() { set_result_html('<p>Hello World</p>'); }); it("should set the text of the .result element", function() { expect($('.result').html()).toEqual('<p>Hello World</p>'); }); });
  • 8. var my_cool_loader = function(post_data){ $.ajax({ type: 'POST', url: 'load_some_data.html', data: post_data, success: function(data){ $('.result').html(data); }, error: function(){ $('.notification').text('Something bad happened!'); } }); };
  • 9. describe("my sweet feature", function() { beforeEach(function() { $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); my_cool_loader(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 10. describe("my sweet feature", function() { beforeEach(function() { $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); my_cool_loader(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 11. describe("my sweet feature", function() { beforeEach(function() { $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); my_cool_loader(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 12. describe("my sweet feature", function() { beforeEach(function() { $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); my_cool_loader(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 13. describe("my sweet feature", function() { beforeEach(function() { $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); my_cool_loader(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 14. describe("my sweet feature", function() { describe("when unsuccessful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ status: 404, statusText: 'File Not Found' }); my_cool_loader(); }); it("should notify the user there was a problem", function() { expect($('.notification').text()).toEqual('Something bad happened!'); }); }); });
  • 15. describe("my sweet feature", function() { describe("when unsuccessful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ status: 404, statusText: 'File Not Found' }); my_cool_loader(); }); it("should notify the user there was a problem", function() { expect($('.notification').text()).toEqual('Something bad happened!'); }); }); });
  • 16. var my_cool_loader = function(post_data){ $.ajax({ type: 'POST', url: 'load_some_data.html', data: post_data, success: function(data){ $('.result').html(data); }, error: function(){ $('.notification').text('Something bad happened!'); } }); };
  • 18. describe("my sweet click feature", function() { beforeEach(function() { setup_button(); $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); $('#my-button').click(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 19. describe("my sweet click feature", function() { beforeEach(function() { setup_button(); $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); $('#my-button').click(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 20. describe("my sweet click feature", function() { beforeEach(function() { setup_button(); $('#jasmine_content').append('<div class="result"></div><div class="notification"></div>'); }); afterEach(function() { $('#jasmine_content').empty(); }); describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); $('#my-button').click(); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); }); });
  • 21. $('#text-input').keyup(function(e){ if(e.which == 13){ my_cool_loader({ foo: 'bar' }); } });
  • 22. describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); // create a new keyup event var e = jQuery.Event("keyup"); // set the key that was pressed to the enter key e.which = 13; // trigger the event on the textarea element $("#text-input").trigger(e); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); });
  • 23. describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); // create a new keyup event var e = jQuery.Event("keyup"); // set the key that was pressed to the enter key e.which = 13; // trigger the event on the textarea element $("#text-input").trigger(e); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); });
  • 24. describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); // create a new keyup event var e = jQuery.Event("keyup"); // set the key that was pressed to the enter key e.which = 13; // trigger the event on the textarea element $("#text-input").trigger(e); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); });
  • 25. describe("when successful", function() { beforeEach(function() { Mooch.stub_request('POST', 'load_some_data.html'). returns({ body: '<p>loaded html</p>' }); // create a new keyup event var e = jQuery.Event("keyup"); // set the key that was pressed to the enter key e.which = 13; // trigger the event on the textarea element $("#text-input").trigger(e); }); it("should insert the received html into the result element", function() { expect($('.result').html()).toEqual('<p>loaded html</p>'); }); });
  • 26. Whats different with JS testing? • need to test in all your target browsers • test suites don’t clean up (much) for you • event driven programming can be hard to test
  • 27. Multi Browser Testing • Selenium • Sauce Labs (http://saucelabs.com) • saucelabs-adapter (http://github.com/ pivotal/saucelabs-adapter)

Editor's Notes