SlideShare a Scribd company logo

Testing JavaScript/CoffeeScript with Mocha and Chai

Mark
Mark

Presented at the Burlington Ruby Conference on July 28th. Learn just how easy it is to test your JavaScript and CoffeeScript code. Don't be scared by events, DOM interactions, or AJAX requests any more!

1 of 71
Download to read offline
TESTING RICH *SCRIPT
APPLICATIONS WITH RAILS
         @markbates
Testing JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and Chai
Finished in 4.41041 seconds
108 examples, 0 failures
Testing JavaScript/CoffeeScript with Mocha and Chai

Recommended

Testing Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with JasmineTesting Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with JasmineMark
 
Testing Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScriptTesting Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScriptMark
 
Tom Lazar Using Zope3 Views And Viewlets For Plone 3.0 Product Development
Tom Lazar   Using Zope3 Views And Viewlets For Plone 3.0 Product DevelopmentTom Lazar   Using Zope3 Views And Viewlets For Plone 3.0 Product Development
Tom Lazar Using Zope3 Views And Viewlets For Plone 3.0 Product DevelopmentVincenzo Barone
 
Refactoring group 1 - chapter 3,4,6
Refactoring   group 1 - chapter 3,4,6Refactoring   group 1 - chapter 3,4,6
Refactoring group 1 - chapter 3,4,6Duy Lâm
 
Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Juriy Zaytsev
 
Implementing CQRS and Event Sourcing with RavenDB
Implementing CQRS and Event Sourcing with RavenDBImplementing CQRS and Event Sourcing with RavenDB
Implementing CQRS and Event Sourcing with RavenDBOren Eini
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 

More Related Content

What's hot

G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門Tsuyoshi Yamamoto
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyRaimonds Simanovskis
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with JasmineLeon van der Grient
 
descriptive programming
descriptive programmingdescriptive programming
descriptive programmingAnand Dhana
 
運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScripttaobao.com
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmineRubyc Slides
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mockskenbot
 
Javascript basics
Javascript basicsJavascript basics
Javascript basicsFin Chen
 
Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020Jerry Liao
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
Doc Parsers Api Cheatsheet 1 0
Doc Parsers Api Cheatsheet 1 0Doc Parsers Api Cheatsheet 1 0
Doc Parsers Api Cheatsheet 1 0Oleh Burkhay
 

What's hot (20)

G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn Ruby
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with Jasmine
 
Specs2
Specs2Specs2
Specs2
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
 
descriptive programming
descriptive programmingdescriptive programming
descriptive programming
 
運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmine
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Spine JS
Spine JSSpine JS
Spine JS
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Java and xml
Java and xmlJava and xml
Java and xml
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 
Javascript basics
Javascript basicsJavascript basics
Javascript basics
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
 
Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Doc Parsers Api Cheatsheet 1 0
Doc Parsers Api Cheatsheet 1 0Doc Parsers Api Cheatsheet 1 0
Doc Parsers Api Cheatsheet 1 0
 

Similar to Testing JavaScript/CoffeeScript with Mocha and Chai

Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bitsChris Saylor
 
Rails2 Pr
Rails2 PrRails2 Pr
Rails2 Prxibbar
 
Intro to Scala.js - Scala UG Cologne
Intro to Scala.js - Scala UG CologneIntro to Scala.js - Scala UG Cologne
Intro to Scala.js - Scala UG CologneMarius Soutier
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to KotlinPatrick Yin
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
EPiServer report generation
EPiServer report generationEPiServer report generation
EPiServer report generationPaul Graham
 
MongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲームMongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲームSuguru Namura
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to NodejsGabriele Lana
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performanceYehuda Katz
 
Rails 2010 Workshop
Rails 2010 WorkshopRails 2010 Workshop
Rails 2010 Workshopdtsadok
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - GuilinJackson Tian
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescriptDavid Furber
 

Similar to Testing JavaScript/CoffeeScript with Mocha and Chai (20)

Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Refactoring
RefactoringRefactoring
Refactoring
 
Rails2 Pr
Rails2 PrRails2 Pr
Rails2 Pr
 
Intro to Scala.js - Scala UG Cologne
Intro to Scala.js - Scala UG CologneIntro to Scala.js - Scala UG Cologne
Intro to Scala.js - Scala UG Cologne
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to Kotlin
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
EPiServer report generation
EPiServer report generationEPiServer report generation
EPiServer report generation
 
MongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲームMongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲーム
 
Testing with Node.js
Testing with Node.jsTesting with Node.js
Testing with Node.js
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to Nodejs
 
Spock
SpockSpock
Spock
 
Little Big Ruby
Little Big RubyLittle Big Ruby
Little Big Ruby
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
 
Rails 2010 Workshop
Rails 2010 WorkshopRails 2010 Workshop
Rails 2010 Workshop
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - Guilin
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 

More from Mark

Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web AppsMark
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js FundamentalsMark
 
Go(lang) for the Rubyist
Go(lang) for the RubyistGo(lang) for the Rubyist
Go(lang) for the RubyistMark
 
Mangling Ruby with TracePoint
Mangling Ruby with TracePointMangling Ruby with TracePoint
Mangling Ruby with TracePointMark
 
AngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.jsAngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.jsMark
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTestMark
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTestMark
 
GET /better
GET /betterGET /better
GET /betterMark
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScriptMark
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing ItMark
 
5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(Mark
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the RubyistMark
 
RubyMotion
RubyMotionRubyMotion
RubyMotionMark
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the RubyistMark
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and RindaMark
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairMark
 
Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Mark
 

More from Mark (17)

Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web Apps
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
 
Go(lang) for the Rubyist
Go(lang) for the RubyistGo(lang) for the Rubyist
Go(lang) for the Rubyist
 
Mangling Ruby with TracePoint
Mangling Ruby with TracePointMangling Ruby with TracePoint
Mangling Ruby with TracePoint
 
AngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.jsAngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.js
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
 
GET /better
GET /betterGET /better
GET /better
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing It
 
5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
 
RubyMotion
RubyMotionRubyMotion
RubyMotion
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and Rinda
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010
 

Recently uploaded

How to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response PlanHow to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response PlanDatabarracks
 
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...Product School
 
Apex Replay Debugger and Salesforce Platform Events.pptx
Apex Replay Debugger and Salesforce Platform Events.pptxApex Replay Debugger and Salesforce Platform Events.pptx
Apex Replay Debugger and Salesforce Platform Events.pptxmohayyudin7826
 
21ST CENTURY LITERACY FROM TRADITIONAL TO MODERN
21ST CENTURY LITERACY FROM TRADITIONAL TO MODERN21ST CENTURY LITERACY FROM TRADITIONAL TO MODERN
21ST CENTURY LITERACY FROM TRADITIONAL TO MODERNRonnelBaroc
 
"Platform Engineering with Development Containers", Igor Fesenko
"Platform Engineering with Development Containers", Igor Fesenko"Platform Engineering with Development Containers", Igor Fesenko
"Platform Engineering with Development Containers", Igor FesenkoFwdays
 
LF Energy Webinar: Introduction to TROLIE
LF Energy Webinar: Introduction to TROLIELF Energy Webinar: Introduction to TROLIE
LF Energy Webinar: Introduction to TROLIEDanBrown980551
 
Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...
Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...
Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...Product School
 
Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24
Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24
Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24Umar Saif
 
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...UiPathCommunity
 
"Testing of Helm Charts or There and Back Again", Yura Rochniak
"Testing of Helm Charts or There and Back Again", Yura Rochniak"Testing of Helm Charts or There and Back Again", Yura Rochniak
"Testing of Helm Charts or There and Back Again", Yura RochniakFwdays
 
"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, Google
"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, Google"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, Google
"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, GoogleISPMAIndia
 
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...Product School
 
Are Human-generated Demonstrations Necessary for In-context Learning?
Are Human-generated Demonstrations Necessary for In-context Learning?Are Human-generated Demonstrations Necessary for In-context Learning?
Are Human-generated Demonstrations Necessary for In-context Learning?MENGSAYLOEM1
 
Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsEvangelia Mitsopoulou
 
Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...
Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...
Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...Adrian Sanabria
 
"Running Open-Source LLM models on Kubernetes", Volodymyr Tsap
"Running Open-Source LLM models on Kubernetes",  Volodymyr Tsap"Running Open-Source LLM models on Kubernetes",  Volodymyr Tsap
"Running Open-Source LLM models on Kubernetes", Volodymyr TsapFwdays
 
AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...
AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...
AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...ISPMAIndia
 
"How we created an SRE team in Temabit as a part of FOZZY Group in conditions...
"How we created an SRE team in Temabit as a part of FOZZY Group in conditions..."How we created an SRE team in Temabit as a part of FOZZY Group in conditions...
"How we created an SRE team in Temabit as a part of FOZZY Group in conditions...Fwdays
 
Enterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book ReviewEnterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book ReviewAshraf Fouad
 
Introducing the New FME Community Webinar - Feb 21, 2024 (2).pdf
Introducing the New FME Community Webinar - Feb 21, 2024 (2).pdfIntroducing the New FME Community Webinar - Feb 21, 2024 (2).pdf
Introducing the New FME Community Webinar - Feb 21, 2024 (2).pdfSafe Software
 

Recently uploaded (20)

How to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response PlanHow to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response Plan
 
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
 
Apex Replay Debugger and Salesforce Platform Events.pptx
Apex Replay Debugger and Salesforce Platform Events.pptxApex Replay Debugger and Salesforce Platform Events.pptx
Apex Replay Debugger and Salesforce Platform Events.pptx
 
21ST CENTURY LITERACY FROM TRADITIONAL TO MODERN
21ST CENTURY LITERACY FROM TRADITIONAL TO MODERN21ST CENTURY LITERACY FROM TRADITIONAL TO MODERN
21ST CENTURY LITERACY FROM TRADITIONAL TO MODERN
 
"Platform Engineering with Development Containers", Igor Fesenko
"Platform Engineering with Development Containers", Igor Fesenko"Platform Engineering with Development Containers", Igor Fesenko
"Platform Engineering with Development Containers", Igor Fesenko
 
LF Energy Webinar: Introduction to TROLIE
LF Energy Webinar: Introduction to TROLIELF Energy Webinar: Introduction to TROLIE
LF Energy Webinar: Introduction to TROLIE
 
Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...
Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...
Harnessing the Power of GenAI for Exceptional Product Outcomes by Booking.com...
 
Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24
Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24
Progress Report: Ministry of IT under Dr. Umar Saif Aug 23-Feb'24
 
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
 
"Testing of Helm Charts or There and Back Again", Yura Rochniak
"Testing of Helm Charts or There and Back Again", Yura Rochniak"Testing of Helm Charts or There and Back Again", Yura Rochniak
"Testing of Helm Charts or There and Back Again", Yura Rochniak
 
"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, Google
"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, Google"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, Google
"The Transformative Power of AI and Open Challenges" by Dr. Manish Gupta, Google
 
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
 
Are Human-generated Demonstrations Necessary for In-context Learning?
Are Human-generated Demonstrations Necessary for In-context Learning?Are Human-generated Demonstrations Necessary for In-context Learning?
Are Human-generated Demonstrations Necessary for In-context Learning?
 
Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applications
 
Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...
Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...
Early Tech Adoption: Foolish or Pragmatic? - 17th ISACA South Florida WOW Con...
 
"Running Open-Source LLM models on Kubernetes", Volodymyr Tsap
"Running Open-Source LLM models on Kubernetes",  Volodymyr Tsap"Running Open-Source LLM models on Kubernetes",  Volodymyr Tsap
"Running Open-Source LLM models on Kubernetes", Volodymyr Tsap
 
AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...
AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...
AI MODELS USAGE IN FINTECH PRODUCTS: PM APPROACH & BEST PRACTICES by Kasthuri...
 
"How we created an SRE team in Temabit as a part of FOZZY Group in conditions...
"How we created an SRE team in Temabit as a part of FOZZY Group in conditions..."How we created an SRE team in Temabit as a part of FOZZY Group in conditions...
"How we created an SRE team in Temabit as a part of FOZZY Group in conditions...
 
Enterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book ReviewEnterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book Review
 
Introducing the New FME Community Webinar - Feb 21, 2024 (2).pdf
Introducing the New FME Community Webinar - Feb 21, 2024 (2).pdfIntroducing the New FME Community Webinar - Feb 21, 2024 (2).pdf
Introducing the New FME Community Webinar - Feb 21, 2024 (2).pdf
 

Testing JavaScript/CoffeeScript with Mocha and Chai

  • 1. TESTING RICH *SCRIPT APPLICATIONS WITH RAILS @markbates
  • 5. Finished in 4.41041 seconds 108 examples, 0 failures
  • 9. app/models/todo.rb class Todo < ActiveRecord::Base validates :body, presence: true attr_accessible :body, :completed end
  • 10. spec/models/todo_spec.rb require 'spec_helper' describe Todo do it "requires a body" do todo = Todo.new todo.should_not be_valid todo.errors[:body].should include("can't be blank") todo.body = "Do something" todo.should be_valid end end
  • 11. app/controllers/todos_controller.rb class TodosController < ApplicationController respond_to :html, :json def index respond_to do |format| format.html {} format.json do @todos = Todo.order("created_at asc") respond_with @todos end end end def show @todo = Todo.find(params[:id]) respond_with @todo end def create @todo = Todo.create(params[:todo]) respond_with @todo end def update @todo = Todo.find(params[:id]) @todo.update_attributes(params[:todo]) respond_with @todo end def destroy @todo = Todo.find(params[:id]) @todo.destroy respond_with @todo end end
  • 12. spec/controllers/todos_controller_spec.rb require 'spec_helper' it "responds with errors" do expect { describe TodosController do post :create, todo: {}, format: 'json' let(:todo) { Factory(:todo) } response.should_not be_successful json = decode_json(response.body) describe 'index' do json.errors.should have(1).error json.errors.body.should include("can't be blank") context "HTML" do }.to_not change(Todo, :count) end it "renders the HTML page" do get :index end response.should render_template(:index) end assigns(:todos).should be_nil end describe 'update' do end context "JSON" do context "JSON" do it "updates a todo" do put :update, id: todo.id, todo: {body: "do something else"}, format: 'json' it "returns JSON for the todos" do get :index, format: "json" response.should be_successful todo.reload response.should_not render_template(:index) todo.body.should eql "do something else" assigns(:todos).should_not be_nil end end it "responds with errors" do end put :update, id: todo.id, todo: {body: ""}, format: 'json' end response.should_not be_successful json = decode_json(response.body) describe 'show' do json.errors.should have(1).error json.errors.body.should include("can't be blank") context "JSON" do end it "returns the todo" do end get :show, id: todo.id, format: 'json' end response.should be_successful response.body.should eql todo.to_json describe 'destroy' do end context "JSON" do end it "destroys the todo" do end todo.should_not be_nil expect { describe 'create' do delete :destroy, id: todo.id, format: 'JSON' }.to change(Todo, :count).by(-1) context "JSON" do end it "creates a new todo" do end expect { post :create, todo: {body: "do something"}, format: 'json' end response.should be_successful end }.to change(Todo, :count).by(1) end
  • 13. app/views/todos/index.html.erb <form class='form-horizontal' id='todo_form'></form> <ul id='todos' class="unstyled"></ul> <script> $(function() { new OMG.Views.TodosApp(); }) </script>
  • 15. app/assets/javascripts/views/todo_view.js.coffee class OMG.Views.TodoView extends OMG.Views.BaseView tagName: 'li' template: JST['todos/_todo'] events: 'change [name=completed]': 'completedChecked' 'click .delete': 'deleteClicked' initialize: -> @model.on "change", @render @render() render: => $(@el).html(@template(todo: @model)) if @model.get("completed") is true @$(".todo-body").addClass("completed") @$("[name=completed]").attr("checked", true) return @ completedChecked: (e) => @model.save(completed: $(e.target).attr("checked")?) deleteClicked: (e) => e?.preventDefault() if confirm("Are you sure?") @model.destroy() $(@el).remove()
  • 16. HOW DO WE TEST THIS?
  • 23. JavaScript example: describe('panda', function(){ it('is happy', function(){ panda.should.be("happy") }); }); CoffeeScript example: describe 'panda', -> it 'is happy', -> panda.should.be("happy")
  • 27. ASSERTIONS/MATCHERS • to (should) • .ok • .instanceof(constructor) • be • .true • .property(name, [value]) • been • .false • .ownProperty(name) • is • .null • .length(value) • that • .undefined • .match(regexp) • and • .exist • .string(string) • have • .empty • .keys(key1, [key2], [...]) • with • .equal (.eql) • .throw(constructor) • .deep • .above(value) • .respondTo(method) • .a(type) • .below(value) • .satisfy(method) • .include(value) • .within(start, finish) • .closeTo(expected, delta)
  • 28. MOCHA/CHAI WITH RAILS • gem 'konacha' • gem 'poltergiest' (brew install phantomjs)
  • 29. config/initializers/konacha.rb if defined?(Konacha) require 'capybara/poltergeist' Konacha.configure do |config| config.spec_dir = "spec/javascripts" config.driver = :poltergeist end end
  • 34. spec/javascripts/spec_helper.coffee # Require the appropriate asset-pipeline files: #= require application # Any other testing specific code here... # Custom matchers, etc.... # Needed for stubbing out "window" properties # like the confirm dialog Konacha.mochaOptions.ignoreLeaks = true beforeEach -> @page = $("#konacha")
  • 35. app/assets/javascript/greeter.js.coffee class @Greeter constructor: (@name) -> unless @name? throw new Error("You need a name!") greet: -> "Hi #{@name}"
  • 36. spec/javascripts/greeter_spec.coffee #= require spec_helper describe "Greeter", -> describe "initialize", -> it "raises an error if no name", -> expect(-> new Greeter()).to.throw("You need a name!") describe "greet", -> it "greets someone", -> greeter = new Greeter("Mark") greeter.greet().should.eql("Hi Mark")
  • 38. NOW THE HARD STUFF
  • 41. MATCHERS • .attr(name[, value]) • .selected • .data(name[, value]) • .checked • .class(className) • .disabled • .id(id) • .exist • .html(html) • .match(selector) / .be(selector) • .text(text) • .contain(selector) • .value(value) • .have(selector) • .visible • .hidden
  • 42. spec/javascripts/spec_helper.coffee # Require the appropriate asset-pipeline files: #= require application #= require_tree ./support # Any other testing specific code here... # Custom matchers, etc.... # Needed for stubbing out "window" properties # like the confirm dialog Konacha.mochaOptions.ignoreLeaks = true beforeEach -> @page = $("#konacha")
  • 43. app/assets/javascripts/views/todo_view.js.coffee class OMG.Views.TodoView extends OMG.Views.BaseView tagName: 'li' template: JST['todos/_todo'] events: 'change [name=completed]': 'completedChecked' 'click .delete': 'deleteClicked' initialize: -> @model.on "change", @render @render() render: => $(@el).html(@template(todo: @model)) if @model.get("completed") is true @$(".todo-body").addClass("completed") @$("[name=completed]").attr("checked", true) return @ completedChecked: (e) => @model.save(completed: $(e.target).attr("checked")?) deleteClicked: (e) => e?.preventDefault() if confirm("Are you sure?") @model.destroy() $(@el).remove()
  • 44. spec/javascripts/views/todos/todo_view_spec.coffee #= require spec_helper describe "OMG.Views.TodoView", -> beforeEach -> @collection = new OMG.Collections.Todos() @model = new OMG.Models.Todo(id: 1, body: "Do something!", completed: false) @view = new OMG.Views.TodoView(model: @model, collection: @collection) @page.html(@view.el)
  • 45. spec/javascripts/views/todos/todo_view_spec.coffee describe "model bindings", -> it "re-renders on change", -> $('.todo-body').should.have.text("Do something!") @model.set(body: "Do something else!") $('.todo-body').should.have.text("Do something else!")
  • 46. spec/javascripts/views/todos/todo_view_spec.coffee describe "displaying of todos", -> it "contains the body of the todo", -> $('.todo-body').should.have.text("Do something!") it "is not marked as completed", -> $('[name=completed]').should.not.be.checked $('.todo-body').should.not.have.class("completed") describe "completed todos", -> beforeEach -> @model.set(completed: true) it "is marked as completed", -> $('[name=completed]').should.be.checked $('.todo-body').should.have.class("completed")
  • 47. spec/javascripts/views/todos/todo_view_spec.coffee describe "checking the completed checkbox", -> beforeEach -> $('[name=completed]').should.not.be.checked $('[name=completed]').click() it "marks it as completed", -> $('[name=completed]').should.be.checked $('.todo-body').should.have.class("completed") describe "unchecking the completed checkbox", -> beforeEach -> @model.set(completed: true) $('[name=completed]').should.be.checked $('[name=completed]').click() it "marks it as not completed", -> $('[name=completed]').should.not.be.checked $('.todo-body').should.not.have.class("completed")
  • 48. app/assets/javascripts/todos/todo_view.coffee class OMG.Views.TodoView extends OMG.Views.BaseView # ... deleteClicked: (e) => e?.preventDefault() if confirm("Are you sure?") @model.destroy() $(@el).remove()
  • 52. SINON.JS • spies • stubs • mocks • fake timers • fake XHR • fake servers • more
  • 53. spec/javascripts/spec_helper.coffee # Require the appropriate asset-pipeline files: #= require application #= require support/sinon #= require_tree ./support # Any other testing specific code here... # Custom matchers, etc.... # Needed for stubbing out "window" properties # like the confirm dialog Konacha.mochaOptions.ignoreLeaks = true beforeEach -> @page = $("#konacha") @sandbox = sinon.sandbox.create() afterEach -> @sandbox.restore()
  • 54. spec/javascripts/views/todos/todo_view_spec.coffee describe "clicking the delete button", -> describe "if confirmed", -> beforeEach -> @sandbox.stub(window, "confirm").returns(true) it "will remove the todo from the @page", -> @page.html().should.contain($(@view.el).html()) $(".delete").click() @page.html().should.not.contain($(@view.el).html()) describe "if not confirmed", -> beforeEach -> @sandbox.stub(window, "confirm").returns(false) it "will not remove the todo from the @page", -> @page.html().should.contain($(@view.el).html()) $(".delete").click() @page.html().should.contain($(@view.el).html())
  • 55. WHAT ABOUT AJAX REQUESTS?
  • 56. app/assets/javascripts/views/todos/todo_list_view.js.coffee class OMG.Views.TodosListView extends OMG.Views.BaseView el: "#todos" initialize: -> @collection.on "reset", @render @collection.on "add", @renderTodo @collection.fetch() render: => $(@el).html("") @collection.forEach (todo) => @renderTodo(todo) renderTodo: (todo) => view = new OMG.Views.TodoView(model: todo, collection: @collection) $(@el).prepend(view.el)
  • 57. spec/javascripts/views/todos/todo_list_view_spec.coffee #= require spec_helper describe "OMG.Views.TodosListView", -> beforeEach -> @page.html("<ul id='todos'></ul>") @collection = new OMG.Collections.Todos() @view = new OMG.Views.TodosListView(collection: @collection) it "fetches the collection", -> @collection.should.have.length(2) it "renders the todos from the collection", -> el = $(@view.el).html() el.should.match(/Do something!/) el.should.match(/Do something else!/) it "renders new todos added to the collection", -> @collection.add(new OMG.Models.Todo(body: "Do another thing!")) el = $(@view.el).html() el.should.match(/Do another thing!/)
  • 60. 1. DEFINE TEST RESPONSE(S)
  • 61. spec/javascripts/support/mock_responses.coffee window.MockServer ?= sinon.fakeServer.create() MockServer.respondWith( "GET", "/todos", [ 200, { "Content-Type": "application/json" }, ''' [ {"body":"Do something!","completed":false,"id":1}, {"body":"Do something else!","completed":false,"id":2} ]''' ] )
  • 63. spec/javascripts/views/todos/todo_list_view_spec.coffee #= require spec_helper describe "OMG.Views.TodosListView", -> beforeEach -> page.html(template("todos")) @collection = new OMG.Collections.Todos() @view = new OMG.Views.TodosListView(collection: @collection) it "fetches the collection", -> @collection.should.have.length(2) it "renders the todos from the collection", -> el = $(@view.el).html() el.should.match(/Do something!/) el.should.match(/Do something else!/) it "renders new todos added to the collection", -> @collection.add(new OMG.Models.Todo(body: "Do another thing!")) el = $(@view.el).html() el.should.match(/Do another thing!/)
  • 64. spec/javascripts/views/todos/todo_list_view_spec.coffee #= require spec_helper describe "OMG.Views.TodosListView", -> beforeEach -> @page.html("<ul id='todos'></ul>") @collection = new OMG.Collections.Todos() @view = new OMG.Views.TodosListView(collection: @collection) MockServer.respond() it "fetches the collection", -> @collection.should.have.length(2) it "renders the todos from the collection", -> el = $(@view.el).html() el.should.match(/Do something!/) el.should.match(/Do something else!/) it "renders new todos added to the collection", -> @collection.add(new OMG.Models.Todo(body: "Do another thing!")) el = $(@view.el).html() el.should.match(/Do another thing!/)
  • 66. APPROACH #2 STUBBING
  • 67. spec/javascripts/views/todos/todo_list_view_spec.coffee #= require spec_helper describe "OMG.Views.TodosListView (Alt.)", -> beforeEach -> @page.html("<ul id='todos'></ul>") @todo1 = new OMG.Models.Todo(id: 1, body: "Do something!") @todo2 = new OMG.Models.Todo(id: 2, body: "Do something else!") @collection = new OMG.Collections.Todos() @sandbox.stub @collection, "fetch", => @collection.add(@todo1, silent: true) @collection.add(@todo2, silent: true) @collection.trigger("reset") @view = new OMG.Views.TodosListView(collection: @collection) it "fetches the collection", -> @collection.should.have.length(2) it "renders the todos from the collection", -> el = $(@view.el).html() el.should.match(new RegExp(@todo1.get("body"))) el.should.match(new RegExp(@todo2.get("body")))
  • 70. rake konacha:run ......................... Finished in 6.77 seconds 25 examples, 0 failures rake konacha:run SPEC=views/todos/todo_list_view_spec ... Finished in 5.89 seconds 3 examples, 0 failures
  • 71. THANKS @markbates • mocha http://visionmedia.github.com/mocha/ • chai http://chaijs.com/ • konacha https://github.com/jfirebaugh/konacha • chai-jquery https://github.com/chaijs/chai-jquery • sinon.js http://sinonjs.org/ • poltergiest https://github.com/jonleighton/poltergeist • phantom.js http://phantomjs.org/ • Programming in CoffeeScript http://books.markbates.com

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n