SlideShare a Scribd company logo
1 of 20
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
1
Unit-Testing Your
Legacy
JavaScript
Rob Myers & Lars Thorup
for
Mile High Agile 2013
19 Apr 2013
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
2
characterization tests
• We don‟t add or change behavior.
• We‟re not bug-hunting.
• We aim for coverage.
• We must see GREEN.
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
3
technique:
“The Three Questions”
• What behavior needs test coverage?
• What‟s preventing us from writing a
test?
• What can we do about that?
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
4
MessTrek lab, part 1:
list scenarios that need testing
• Let‟s focus on game.js.
• Look for behavior that needs testing.
Write a description of as many
scenarios as you can find.
• Also record anything you notice that
will make testing difficult.
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
5
technique:
separate code from data
• It‟s easier to maintain JavaScript
when it‟s not mixed up with HTML.
• Use „Name Anonymous Function‟ as a
first step, if necessary.
• Then move the function into a .js file
associated with the .html file.
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
6
before
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
7
<script>
$(function() {
$('.new_address_form').hide();
$('.countrySelect').change(function() {
$('.new_address_form').hide();
var country = $(".countrySelect").val();
if (country === "JP") {
$('.address_jp').show();
}
else {
$('.address_generic').show();
}
});
});
</script>
after „Name Anonymous Function‟
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
8
<script>
$(function() {
$('.new_address_form').hide();
$('.countrySelect').change(onCountryChange);
});
function onCountryChange() {
$('.new_address_form').hide();
var country = $(".countrySelect").val();
if (country === "JP") {
$('.address_jp').show();
}
else {
$('.address_generic').show();
}
}
</script>
technique:
pass globals into the method
• It‟s easier to test a JavaScript method‟s
various behaviors when it can operate on all
or part of a document.
• First use „Pass Whole Document‟.
• Then have your unit tests pass in minimal
DOM fragments (by varying <qunit-fixture>
as shown earlier) to test discrete behaviors.
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
9
before
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
10
<script>
$(function() {
$('.new_address_form').hide();
$('.countrySelect').change(onCountryChange);
});
function onCountryChange() {
$('.new_address_form').hide();
var country = $(".countrySelect").val();
if (country === "JP") {
$('.address_jp').show();
}
else {
$('.address_generic').show();
}
}
</script>
after „Pass Whole Document‟
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
11
<script>
$(function() {
$('.new_address_form').hide();
$('.countrySelect').change(
function () { onCountryChange(document); });
});
function onCountryChange(form) {
$('.new_address_form’, form).hide();
var country = $(".countrySelect”, form).val();
if (country === "JP") {
$('.address_jp’, form).show();
}
else {
$('.address_generic’, form).show();
}
}
</script>
technique:
separate behavior from initialization
• It‟s easier to test behavior when not
coupled to initialization code.
• Use „Extract Method‟ to preserve
existing interfaces.
• You then have a “seam” where you
can test by injecting mocks.
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
12
before
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
13
var openOrderReport = function(output, accountNumber) {
var account = LunExData.queryAccount(accountNumber);
var openOrders =
LunExData.queryOrders("open", account, new Date());
for (var i = 0; i < openOrders.length; ++i) {
var order = openOrders[i];
// ...
output.Write("Order ...");
// ...
}
}
after „Extract Method‟
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
14
var openOrderReport = function(output, accountNumber) {
var account = LunExData.queryAccount(accountNumber);
var openOrders =
LunExData.queryOrders("open", account, new Date());
formatOpenOrderReport(output, account, openOrders);
}
var formatOpenOrderReport =
function(output, account, openOrders) {
for (var i = 0; i < openOrders.length; ++i) {
var order = openOrders[i];
// ...
output.Write("Order ...");
// ...
}
}
technique:
mock dependencies
• Results (and test performance) often depend
heavily on externals, yet we want
fast, predictable results.
• You can easily stub out the behaviors of
dependencies and libraries.
• You are then characterizing the particular
behaviors of your code, not external libraries.
• To avoid impacting other tests, be sure to undo
the stub after each test.
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
15
sinon.js basics
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
16
// to stub a behavior, e.g., Math.random()
sinon.stub(Math, 'random', function () { return 0.5; });
// to undo the stub
Math.random.restore();
MessTrek lab, part 2:
write a characterization test
• Start in (and be inspired by) test/game.test.html
• Focus on weapons.
• Use safe, careful refactorings where necessary.
• Do as little refactoring as possible.
• For now just get one characterization test to
pass, then let us know you are DONE!
• Be sure to read and understand the rules on the
next slide…
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
17
a few rules for part 2
• You must not alter (or add to) anything in the
Untouchables folder
(userInterface.js, sampleclient.html).
• You must not alter the results of anything in the
Untouchables folder (sampleclient.html).
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
18
23 May 2013
© 2008-2013 Agile Institute.
All Rights Reserved.
19
reflection
23 May 2013
© 2008-2013 Agile Institute. All
Rights Reserved.
20
lars@zealake.com
http://www.zealake.com/blog/
@larsthorup
Rob.Myers@agileInstitute.com
http://PowersOfTwo.agileInstitute.com/
@agilecoach

More Related Content

What's hot

Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and CheckstyleMarc Prengemann
 
A low Overhead Per Object Write Barrier for Smalltalk
A low Overhead Per Object Write Barrier for SmalltalkA low Overhead Per Object Write Barrier for Smalltalk
A low Overhead Per Object Write Barrier for SmalltalkESUG
 
Maintainable JavaScript 2011
Maintainable JavaScript 2011Maintainable JavaScript 2011
Maintainable JavaScript 2011Nicholas Zakas
 
Dynamically Composing Collection Operations through Collection Promises
Dynamically Composing Collection Operations through Collection PromisesDynamically Composing Collection Operations through Collection Promises
Dynamically Composing Collection Operations through Collection PromisesMarcus Denker
 
JavaScript Conditional Statements
JavaScript Conditional StatementsJavaScript Conditional Statements
JavaScript Conditional StatementsMarlon Jamera
 
Unit testing in xcode 8 with swift
Unit testing in xcode 8 with swiftUnit testing in xcode 8 with swift
Unit testing in xcode 8 with swiftallanh0526
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
Understanding solid principles
Understanding solid principlesUnderstanding solid principles
Understanding solid principlesBabatunde Otaru
 
Implement Search Screen Using Knockoutjs
Implement Search Screen Using KnockoutjsImplement Search Screen Using Knockoutjs
Implement Search Screen Using KnockoutjsNeeraj Kaushik
 
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and AssertionsCore Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and AssertionsWebStackAcademy
 
Attacks against Microsoft network web clients
Attacks against Microsoft network web clients Attacks against Microsoft network web clients
Attacks against Microsoft network web clients Positive Hack Days
 

What's hot (18)

Testing the unpredictable
Testing the unpredictableTesting the unpredictable
Testing the unpredictable
 
Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and Checkstyle
 
Test doubles
Test doublesTest doubles
Test doubles
 
Mock your way with Mockito
Mock your way with MockitoMock your way with Mockito
Mock your way with Mockito
 
A low Overhead Per Object Write Barrier for Smalltalk
A low Overhead Per Object Write Barrier for SmalltalkA low Overhead Per Object Write Barrier for Smalltalk
A low Overhead Per Object Write Barrier for Smalltalk
 
Maintainable JavaScript 2011
Maintainable JavaScript 2011Maintainable JavaScript 2011
Maintainable JavaScript 2011
 
Dynamically Composing Collection Operations through Collection Promises
Dynamically Composing Collection Operations through Collection PromisesDynamically Composing Collection Operations through Collection Promises
Dynamically Composing Collection Operations through Collection Promises
 
Testing in JavaScript
Testing in JavaScriptTesting in JavaScript
Testing in JavaScript
 
JavaScript Conditional Statements
JavaScript Conditional StatementsJavaScript Conditional Statements
JavaScript Conditional Statements
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Unit testing in xcode 8 with swift
Unit testing in xcode 8 with swiftUnit testing in xcode 8 with swift
Unit testing in xcode 8 with swift
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Understanding solid principles
Understanding solid principlesUnderstanding solid principles
Understanding solid principles
 
Introduction to JavaScript Programming
Introduction to JavaScript ProgrammingIntroduction to JavaScript Programming
Introduction to JavaScript Programming
 
Testing
TestingTesting
Testing
 
Implement Search Screen Using Knockoutjs
Implement Search Screen Using KnockoutjsImplement Search Screen Using Knockoutjs
Implement Search Screen Using Knockoutjs
 
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and AssertionsCore Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
 
Attacks against Microsoft network web clients
Attacks against Microsoft network web clients Attacks against Microsoft network web clients
Attacks against Microsoft network web clients
 

Similar to Unit-Testing Your Legacy JavaScript

Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Knowvilniusjug
 
A la découverte des google/mock (aka gmock)
A la découverte des google/mock (aka gmock)A la découverte des google/mock (aka gmock)
A la découverte des google/mock (aka gmock)Thierry Gayet
 
Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)vilniusjug
 
Intro to JavaScript Testing
Intro to JavaScript TestingIntro to JavaScript Testing
Intro to JavaScript TestingRan Mizrahi
 
Testing Spark and Scala
Testing Spark and ScalaTesting Spark and Scala
Testing Spark and Scaladatamantra
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profilerIhor Bobak
 
Advance unittest
Advance unittestAdvance unittest
Advance unittestReza Arbabi
 
Error handling in XPages
Error handling in XPagesError handling in XPages
Error handling in XPagesdominion
 
Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Dror Helper
 
Introduction to JavaScript
Introduction to JavaScriptIntroduction to JavaScript
Introduction to JavaScriptMarlon Jamera
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchMats Bryntse
 
Testing the Untestable
Testing the UntestableTesting the Untestable
Testing the UntestableMark Baker
 
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...WebStackAcademy
 
Sequential Concurrency ... WHAT ???
Sequential Concurrency ... WHAT ???Sequential Concurrency ... WHAT ???
Sequential Concurrency ... WHAT ???Jitendra Chittoda
 
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@Alex Borsuk
 
An Introduction to AngularJS
An Introduction to AngularJSAn Introduction to AngularJS
An Introduction to AngularJSFalk Hartmann
 

Similar to Unit-Testing Your Legacy JavaScript (20)

Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Know
 
A la découverte des google/mock (aka gmock)
A la découverte des google/mock (aka gmock)A la découverte des google/mock (aka gmock)
A la découverte des google/mock (aka gmock)
 
Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)
 
Intro to JavaScript Testing
Intro to JavaScript TestingIntro to JavaScript Testing
Intro to JavaScript Testing
 
Unit testing basic
Unit testing basicUnit testing basic
Unit testing basic
 
Testing Spark and Scala
Testing Spark and ScalaTesting Spark and Scala
Testing Spark and Scala
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profiler
 
Advance unittest
Advance unittestAdvance unittest
Advance unittest
 
Error handling in XPages
Error handling in XPagesError handling in XPages
Error handling in XPages
 
Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013
 
Unit testing
Unit testingUnit testing
Unit testing
 
Frontend training
Frontend trainingFrontend training
Frontend training
 
Introduction to JavaScript
Introduction to JavaScriptIntroduction to JavaScript
Introduction to JavaScript
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha Touch
 
Testing the Untestable
Testing the UntestableTesting the Untestable
Testing the Untestable
 
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
 
Sequential Concurrency ... WHAT ???
Sequential Concurrency ... WHAT ???Sequential Concurrency ... WHAT ???
Sequential Concurrency ... WHAT ???
 
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@
 
An Introduction to AngularJS
An Introduction to AngularJSAn Introduction to AngularJS
An Introduction to AngularJS
 
Wt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technologyWt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technology
 

More from Rob Myers

The Business Value of Agile Engineering Practices
The Business Value of Agile Engineering PracticesThe Business Value of Agile Engineering Practices
The Business Value of Agile Engineering PracticesRob Myers
 
The Business Value of Test-Driven Development
The Business Value of Test-Driven DevelopmentThe Business Value of Test-Driven Development
The Business Value of Test-Driven DevelopmentRob Myers
 
Roots of Agility - Better Software Agile Dev Practices East 2014 Keynote
Roots of Agility - Better Software Agile Dev Practices East 2014 KeynoteRoots of Agility - Better Software Agile Dev Practices East 2014 Keynote
Roots of Agility - Better Software Agile Dev Practices East 2014 KeynoteRob Myers
 
Assessing the business value of Agile Engineering Practices
Assessing the business value of Agile Engineering PracticesAssessing the business value of Agile Engineering Practices
Assessing the business value of Agile Engineering PracticesRob Myers
 
The Business Value of Agile Engineering Practices
The Business Value of Agile Engineering PracticesThe Business Value of Agile Engineering Practices
The Business Value of Agile Engineering PracticesRob Myers
 
Mock Objects from Concept to Code
Mock Objects from Concept to CodeMock Objects from Concept to Code
Mock Objects from Concept to CodeRob Myers
 
Technical Debt
Technical DebtTechnical Debt
Technical DebtRob Myers
 
Successful Teams are TDD Teams
Successful Teams are TDD TeamsSuccessful Teams are TDD Teams
Successful Teams are TDD TeamsRob Myers
 
TDD? Sure, but What About My Legacy Code?
TDD? Sure, but What About My Legacy Code?TDD? Sure, but What About My Legacy Code?
TDD? Sure, but What About My Legacy Code?Rob Myers
 
Test-Driven Development Overview
Test-Driven Development OverviewTest-Driven Development Overview
Test-Driven Development OverviewRob Myers
 
Metrics In An Agile World
Metrics In An Agile WorldMetrics In An Agile World
Metrics In An Agile WorldRob Myers
 
The Value of Refactoring on an Agile Team
The Value of Refactoring on an Agile TeamThe Value of Refactoring on an Agile Team
The Value of Refactoring on an Agile TeamRob Myers
 
Successful Teams are Test-Driven Teams
Successful Teams are Test-Driven TeamsSuccessful Teams are Test-Driven Teams
Successful Teams are Test-Driven TeamsRob Myers
 
Agile Testing: Solving the Agilist\'s Dilemma
Agile Testing: Solving the Agilist\'s DilemmaAgile Testing: Solving the Agilist\'s Dilemma
Agile Testing: Solving the Agilist\'s DilemmaRob Myers
 

More from Rob Myers (14)

The Business Value of Agile Engineering Practices
The Business Value of Agile Engineering PracticesThe Business Value of Agile Engineering Practices
The Business Value of Agile Engineering Practices
 
The Business Value of Test-Driven Development
The Business Value of Test-Driven DevelopmentThe Business Value of Test-Driven Development
The Business Value of Test-Driven Development
 
Roots of Agility - Better Software Agile Dev Practices East 2014 Keynote
Roots of Agility - Better Software Agile Dev Practices East 2014 KeynoteRoots of Agility - Better Software Agile Dev Practices East 2014 Keynote
Roots of Agility - Better Software Agile Dev Practices East 2014 Keynote
 
Assessing the business value of Agile Engineering Practices
Assessing the business value of Agile Engineering PracticesAssessing the business value of Agile Engineering Practices
Assessing the business value of Agile Engineering Practices
 
The Business Value of Agile Engineering Practices
The Business Value of Agile Engineering PracticesThe Business Value of Agile Engineering Practices
The Business Value of Agile Engineering Practices
 
Mock Objects from Concept to Code
Mock Objects from Concept to CodeMock Objects from Concept to Code
Mock Objects from Concept to Code
 
Technical Debt
Technical DebtTechnical Debt
Technical Debt
 
Successful Teams are TDD Teams
Successful Teams are TDD TeamsSuccessful Teams are TDD Teams
Successful Teams are TDD Teams
 
TDD? Sure, but What About My Legacy Code?
TDD? Sure, but What About My Legacy Code?TDD? Sure, but What About My Legacy Code?
TDD? Sure, but What About My Legacy Code?
 
Test-Driven Development Overview
Test-Driven Development OverviewTest-Driven Development Overview
Test-Driven Development Overview
 
Metrics In An Agile World
Metrics In An Agile WorldMetrics In An Agile World
Metrics In An Agile World
 
The Value of Refactoring on an Agile Team
The Value of Refactoring on an Agile TeamThe Value of Refactoring on an Agile Team
The Value of Refactoring on an Agile Team
 
Successful Teams are Test-Driven Teams
Successful Teams are Test-Driven TeamsSuccessful Teams are Test-Driven Teams
Successful Teams are Test-Driven Teams
 
Agile Testing: Solving the Agilist\'s Dilemma
Agile Testing: Solving the Agilist\'s DilemmaAgile Testing: Solving the Agilist\'s Dilemma
Agile Testing: Solving the Agilist\'s Dilemma
 

Recently uploaded

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 

Recently uploaded (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 

Unit-Testing Your Legacy JavaScript

  • 1. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 1 Unit-Testing Your Legacy JavaScript Rob Myers & Lars Thorup for Mile High Agile 2013 19 Apr 2013
  • 2. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 2
  • 3. characterization tests • We don‟t add or change behavior. • We‟re not bug-hunting. • We aim for coverage. • We must see GREEN. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 3
  • 4. technique: “The Three Questions” • What behavior needs test coverage? • What‟s preventing us from writing a test? • What can we do about that? 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 4
  • 5. MessTrek lab, part 1: list scenarios that need testing • Let‟s focus on game.js. • Look for behavior that needs testing. Write a description of as many scenarios as you can find. • Also record anything you notice that will make testing difficult. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 5
  • 6. technique: separate code from data • It‟s easier to maintain JavaScript when it‟s not mixed up with HTML. • Use „Name Anonymous Function‟ as a first step, if necessary. • Then move the function into a .js file associated with the .html file. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 6
  • 7. before 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 7 <script> $(function() { $('.new_address_form').hide(); $('.countrySelect').change(function() { $('.new_address_form').hide(); var country = $(".countrySelect").val(); if (country === "JP") { $('.address_jp').show(); } else { $('.address_generic').show(); } }); }); </script>
  • 8. after „Name Anonymous Function‟ 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 8 <script> $(function() { $('.new_address_form').hide(); $('.countrySelect').change(onCountryChange); }); function onCountryChange() { $('.new_address_form').hide(); var country = $(".countrySelect").val(); if (country === "JP") { $('.address_jp').show(); } else { $('.address_generic').show(); } } </script>
  • 9. technique: pass globals into the method • It‟s easier to test a JavaScript method‟s various behaviors when it can operate on all or part of a document. • First use „Pass Whole Document‟. • Then have your unit tests pass in minimal DOM fragments (by varying <qunit-fixture> as shown earlier) to test discrete behaviors. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 9
  • 10. before 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 10 <script> $(function() { $('.new_address_form').hide(); $('.countrySelect').change(onCountryChange); }); function onCountryChange() { $('.new_address_form').hide(); var country = $(".countrySelect").val(); if (country === "JP") { $('.address_jp').show(); } else { $('.address_generic').show(); } } </script>
  • 11. after „Pass Whole Document‟ 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 11 <script> $(function() { $('.new_address_form').hide(); $('.countrySelect').change( function () { onCountryChange(document); }); }); function onCountryChange(form) { $('.new_address_form’, form).hide(); var country = $(".countrySelect”, form).val(); if (country === "JP") { $('.address_jp’, form).show(); } else { $('.address_generic’, form).show(); } } </script>
  • 12. technique: separate behavior from initialization • It‟s easier to test behavior when not coupled to initialization code. • Use „Extract Method‟ to preserve existing interfaces. • You then have a “seam” where you can test by injecting mocks. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 12
  • 13. before 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 13 var openOrderReport = function(output, accountNumber) { var account = LunExData.queryAccount(accountNumber); var openOrders = LunExData.queryOrders("open", account, new Date()); for (var i = 0; i < openOrders.length; ++i) { var order = openOrders[i]; // ... output.Write("Order ..."); // ... } }
  • 14. after „Extract Method‟ 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 14 var openOrderReport = function(output, accountNumber) { var account = LunExData.queryAccount(accountNumber); var openOrders = LunExData.queryOrders("open", account, new Date()); formatOpenOrderReport(output, account, openOrders); } var formatOpenOrderReport = function(output, account, openOrders) { for (var i = 0; i < openOrders.length; ++i) { var order = openOrders[i]; // ... output.Write("Order ..."); // ... } }
  • 15. technique: mock dependencies • Results (and test performance) often depend heavily on externals, yet we want fast, predictable results. • You can easily stub out the behaviors of dependencies and libraries. • You are then characterizing the particular behaviors of your code, not external libraries. • To avoid impacting other tests, be sure to undo the stub after each test. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 15
  • 16. sinon.js basics 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 16 // to stub a behavior, e.g., Math.random() sinon.stub(Math, 'random', function () { return 0.5; }); // to undo the stub Math.random.restore();
  • 17. MessTrek lab, part 2: write a characterization test • Start in (and be inspired by) test/game.test.html • Focus on weapons. • Use safe, careful refactorings where necessary. • Do as little refactoring as possible. • For now just get one characterization test to pass, then let us know you are DONE! • Be sure to read and understand the rules on the next slide… 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 17
  • 18. a few rules for part 2 • You must not alter (or add to) anything in the Untouchables folder (userInterface.js, sampleclient.html). • You must not alter the results of anything in the Untouchables folder (sampleclient.html). 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 18
  • 19. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 19 reflection
  • 20. 23 May 2013 © 2008-2013 Agile Institute. All Rights Reserved. 20 lars@zealake.com http://www.zealake.com/blog/ @larsthorup Rob.Myers@agileInstitute.com http://PowersOfTwo.agileInstitute.com/ @agilecoach

Editor's Notes

  1. This isn’t TDD. But you won’t be able to proceed with TDD without these techniques.If we find a bug, record it: In a bug tracker, or as a story.Not isolation. These are not “unit tests” - These tests can cover as much behavior as possible (though they must still be deterministic and pretty fast). And they don’t have to be pretty!characterization tests should pass.The test is trying to “pin” behavior so we can refactor further.
  2. What needs testing?
  3. now move the newly named function into a .js fileTODO: one more, where we pass in the DOM element to make it more testable in various circumstances, with various fixtures
  4. now move the newly named function into a .js fileTODO: one more, where we pass in the DOM element to make it more testable in various circumstances, with various fixtures
  5. What needs testing?
  6. What needs testing?
  7. Very easyLean on the compiler
  8. Under TDD Resources\\JavaScript\\lib
  9. Open the MessTrek files and look at them.What needs testing?What’s stopping you?If you get stuck, there is another set of code available, with tests. Read over the tests and become familiar with the techniques used. Note that the code is still very ugly.
  10. sampleclient.html depends on Game’s interface, and represents your customer’s UI developers. UserInterface represents some third-party vendor, and you *can’t* change the code!
  11. Thank you!