SlideShare uma empresa Scribd logo
1 de 42
Baixar para ler offline
Writing Easy-ToTest Code
Ynon Perek	

ynon@ynonperek.com	

http://ynonperek.com
Problem #1	

How do you write hard
to test code ?
Code Flags
• Use global state	

• Use static methods	

• Mix object construction with business logic	

• Mixing find-what-i-need logic with business logic	

• Write LONG functions	

• Use many conditionals	

• Dependency hell	

• Long inheritance hierarchies
Isolating Logic
ItemWidget

jQuery
Parser

TreeWidget

Button
Array.sort
Data Supplier
Data Object
Isolating Logic
ItemWidget

jQuery
Parser

TreeWidget

Button
Array.sort
Data Supplier
Data Object
Isolating Logic
ItemWidget
Test

TreeWidget

Button
Data Supplier
Isolating Logic
Main

ItemWidget
TreeWidget

Test

Button
Data Supplier
The Code
function TreeWidget(ItemWidget, dataSupplier) {

// ...

}

function TreeWidget() {

var dataSupplier = new
DataSupplier('/music/collection');

}
If you can isolate it, you
can test it
What Can You Test ?
colors = ['red', 'blue', 'green', 'yellow', 'cyan', 'magenta'];




$('#btn').html('Click Me');







$('#btn').on('click', function() {

var idx = $('body').attr('data-color');

idx = Number(idx) + 1 || 0;

$('body').attr('data-color', idx);

if ( Number(idx) >= 0 ) {

$('body').css("background", colors[idx]);

} else {

$('body').css('background', colors[0]);

}

});
Dependencies
• Colors array	

• DOM structure	

• jQuery
Let’s Try This One
function ColorChanger(colors_array, $btn_el, $body_el) {

var self = this;

var _current_color = 0;




self.init = function() {

$btn_el.html('Click Me');

$btn_el.on('click', self.apply_next_color);

};







}


self.apply_next_color = function() {

$body_el.css('backgroundColor', colors_array[_current_color]);

_current_color += 1;

};


var c = new ColorChanger(colors, $('#btn'), $('body'));

c.init();
Now you can easily test:
• Code iterates over all colours	

• Code works well on all possible colours
array	


• Colour iteration is circular
Takeaways
• Refactoring code can make it easier to test	

• The goal:	

• Isolated logic	

• Clear replaceable dependencies
Agenda
• Dependency Injection	

• Data / DOM separation	

• Component based architecture	

• Design Patterns
Dependency Injection
• State all your dependencies at the top	

• Separate object creation and lookup from
business logic
DI Framework
• A framework that does object creation for
you	


• Some frameworks also manage object
lifecycle
Famous DI
global.myapp.controller(

'Home', 

['$scope', '$routeParams', 'Notebooks', 

function($scope, $routeParams, Notebooks) {

// ...

}]);
Famous DI



require(["helper/util"], function(util) {

});
Vanilla DI
• You don’t really need a framework
Q &A
Data / DOM
Business logic
JS

write
read 	

(event handlers)

DOM API
HTMLDivElement
Event Handlers
• Get the data	

• Call testable handler function
$('#username').on('input', function() {

var newValue = this.value;

self.checkUsername(newValue);

});

Mixing Lookups
$('#btn').on("click", function() {

if ( $('#page1').is(':hidden') == true ) {

$('#page1').show();

$('#page2').hide();

} else {

$('#page1').hide();

$('#page2').show();

}

});

$('#page1').show();
Non Mixed Version
function Toggle(pages) {

var active = 0;




function toggle() {

pages[active].hide();

active = (active + 1) % pages;

pages[active].show();

}




pages[0].show();

return toggle;




}

$('#btn').on('click', Toggle([$('#page1'), $('#page2')]));

Testing Non-Mixed Version
• Setup fake dependencies
var FakePage = function() {

_visible = false;

return {

show: function() { _visible = true; },

hide: function() { _visible = false; },

visible: function() { return _visible; }

}

} ;

Testing Non-Mixed Version
• Inject and test
var toggle = Toggle([p1, p2]);




expect(p1.visible).to.be.true;

expect(p2.visible).to.be.false;





toggle();

expect(p1.visible).to.be.false;

expect(p2.visible).to.be.true;
Mixing Lookups
• Separate lookup code from business logic	

• Test interesting parts -> business logic
Components Based Architecture
Guidelines
• Well defined components with a clear API	

• Dependencies for each component are
injected upon creation	


• System is a tree of components
Components
Home Page

Sidebar

Content
Reducing Dependencies
• Task: Clicking a menu item in the sidebar
should change active item in $content	


• Is $content a dependency for $sidebar ?
Code From Sidebar
$('.menu .item').on('click', function() {

var item_id = $(this).data('id');

$content.set_active_item(item_id);

});
Direct Connection Problems

• It doesn’t scale	

• Requires tester to mock many components
Solution: Observer Pattern
• All components share a “hub”	

• No direct messages between components	

• Easy on the testing
Using Events
$('.menu .item').on('click', function() {

var item_id = $(this).data('id');

$hub.trigger('active_item_changed', item_id);

});

Sidebar

$hub.on('active_item_changed', set_active_item);

Content
Testing Events
for ( var i=0; i < items.length; i++ ) {

hub.trigger('active_item_change', i);

expect($('#content').html()).to.eq(items[i]);
}


The Pattern
JS Observer
• Observer is just a function	

• Notify by calling it
Q &A
Code Flags
• Use global state	

• Use static methods	

• Mix object construction with business logic	

• Mixing find-what-i-need logic with business logic	

• Write LONG functions	

• Use many conditionals	

• Dependency hell	

• Long inheritance hierarchies
Thanks For Listening
• Ynon Perek	

• http://ynonperek.com	

• ynon@ynonperek.com

Mais conteúdo relacionado

Mais procurados

Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
Yehuda Katz
 

Mais procurados (20)

Introduction to Selenium and Ruby
Introduction to Selenium and RubyIntroduction to Selenium and Ruby
Introduction to Selenium and Ruby
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
 
Prototype & jQuery
Prototype & jQueryPrototype & jQuery
Prototype & jQuery
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
jQuery Fundamentals
jQuery FundamentalsjQuery Fundamentals
jQuery Fundamentals
 
jQuery basics
jQuery basicsjQuery basics
jQuery basics
 
jQuery
jQueryjQuery
jQuery
 
SilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript RefactoringSilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript Refactoring
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
 
Kiss PageObjects [01-2017]
Kiss PageObjects [01-2017]Kiss PageObjects [01-2017]
Kiss PageObjects [01-2017]
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe TestingGetting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
 
jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014
 
jQuery
jQueryjQuery
jQuery
 
Take Data Validation Seriously - Paul Milham, WildWorks
Take Data Validation Seriously - Paul Milham, WildWorksTake Data Validation Seriously - Paul Milham, WildWorks
Take Data Validation Seriously - Paul Milham, WildWorks
 

Semelhante a How to write easy-to-test JavaScript

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
smueller_sandsmedia
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1
saydin_soft
 
appengine java night #1
appengine java night #1appengine java night #1
appengine java night #1
Shinichi Ogawa
 
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
David Giard
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片
cfc
 

Semelhante a How to write easy-to-test JavaScript (20)

Jquery
JqueryJquery
Jquery
 
Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tips
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Utilising the data attribute
Utilising the data attributeUtilising the data attribute
Utilising the data attribute
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
 
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
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1
 
appengine java night #1
appengine java night #1appengine java night #1
appengine java night #1
 
Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
 
Jquery fundamentals
Jquery fundamentalsJquery fundamentals
Jquery fundamentals
 
jQuery Rescue Adventure
jQuery Rescue AdventurejQuery Rescue Adventure
jQuery Rescue Adventure
 
J querypractice
J querypracticeJ querypractice
J querypractice
 
J query training
J query trainingJ query training
J query training
 
jQuery
jQueryjQuery
jQuery
 
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片
 
Introduction to jQuery - The basics
Introduction to jQuery - The basicsIntroduction to jQuery - The basics
Introduction to jQuery - The basics
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
 

Mais de Ynon Perek

Mobile Devices
Mobile DevicesMobile Devices
Mobile Devices
Ynon Perek
 

Mais de Ynon Perek (20)

Regexp
RegexpRegexp
Regexp
 
Html5 intro
Html5 introHtml5 intro
Html5 intro
 
09 performance
09 performance09 performance
09 performance
 
Mobile Web Intro
Mobile Web IntroMobile Web Intro
Mobile Web Intro
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Vimperl
VimperlVimperl
Vimperl
 
Syllabus
SyllabusSyllabus
Syllabus
 
Mobile Devices
Mobile DevicesMobile Devices
Mobile Devices
 
Network
NetworkNetwork
Network
 
Architecture app
Architecture appArchitecture app
Architecture app
 
Cryptography
CryptographyCryptography
Cryptography
 
Introduction To Web Application Testing
Introduction To Web Application TestingIntroduction To Web Application Testing
Introduction To Web Application Testing
 
Accessibility
AccessibilityAccessibility
Accessibility
 
Angularjs
AngularjsAngularjs
Angularjs
 
Js memory
Js memoryJs memory
Js memory
 
Qt Design Patterns
Qt Design PatternsQt Design Patterns
Qt Design Patterns
 
Web Application Security
Web Application SecurityWeb Application Security
Web Application Security
 
JavaScript DOM Manipulations
JavaScript DOM ManipulationsJavaScript DOM Manipulations
JavaScript DOM Manipulations
 
Mongodb Intro
Mongodb IntroMongodb Intro
Mongodb Intro
 
Node JS
Node JSNode JS
Node JS
 

Último

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 

How to write easy-to-test JavaScript