SlideShare una empresa de Scribd logo
1 de 23
Descargar para leer sin conexión
ADVANCED JASMINE
FRONT-END JAVASCRIPT UNIT TESTING
/Lars Thorup, ZeaLake @larsthorup
WHO IS LARS THORUP
Software developer/architect
C++, C# and JavaScript
Test Driven Development
Coach: Teaching agile and automated testing
Advisor: Assesses software projects and companies
Founder and CEO of ZeaLake
AGENDA
Unit tests gives quality feedback
Make them fast
Make them precise
Run thousands of unit tests in seconds
We will look at
Mocking techniques
Front-end specific testing patterns
Assuming knowledge about JavaScript and unit testing
JASMINE BASICS
describe('Calculator', function () {
var calc;
beforeEach(function () {
calc = new Calculator();
});
it('should multiply', function () {
expect(calc.multiply(6, 7)).toBe(42);
});
});
MOCKING, SPYING AND STUBBING
HOW TO TEST IN ISOLATION?
We want to test code in isolation
here the code is the 'keypress' event handler
and isolation means not invoking the getMatch() method
'keypress': function (element, event) {
var pattern = this.element.val();
pattern += String.fromCharCode(event.charCode);
var match = this.getMatch(pattern);
if (match) {
event.preventDefault();
this.element.val(match);
}
}
MOCKING METHODS
We can mock the getMatch() method
decide how the mock should behave
verify that the mocked method was called correctly
spyOn(autoComplete, 'getMatch').andReturn('monique');
$('#name').trigger($.Event('keypress', {charCode: 109}));
expect(autoComplete.getMatch).toHaveBeenCalledWith('m');
expect($('#name')).toHaveValue('monique');
MOCKING GLOBAL FUNCTIONS
Global functions are properties of the window object
openPopup: function (url) {
var popup = window.open(url, '_blank', 'resizable');
popup.focus();
}
var popup;
spyOn(window, 'open').andCallFake(function () {
popup = {
focus: jasmine.createSpy()
};
return popup;
});
autoComplete.openPopup('zealake.com');
expect(window.open).toHaveBeenCalledWith('zealake.com', '_blank', 'resizable');
expect(popup.focus).toHaveBeenCalledWith();
MOCKING CONSTRUCTORS
Constructors are functions
with thisbeing the object to construct
this.input = new window.AutoComplete(inputElement, {
listUrl: this.options.listUrl
});
this.input.focus();
spyOn(window, 'AutoComplete').andCallFake(function () {
this.focus = jasmine.createSpy();
});
expect(window.AutoComplete.callCount).toBe(1);
var args = window.AutoComplete.mostRecentCall.args;
expect(args[0]).toBe('#name');
expect(args[1]).toEqual({listUrl: '/someUrl'});
var object = window.AutoComplete.mostRecentCall.object;
expect(object.focus).toHaveBeenCalledWith();
HOW TO AVOID WAITING?
We want the tests to be fast
So don't use Jasmine waitsFor()
But we often need to wait
For animations to complete
For AJAX responses to return
delayHide: function () {
var self = this;
setTimeout(function () {
self.element.hide();
}, this.options.hideDelay);
}
MOCKING TIMERS
Use Jasmine's mock clock
Control the clock explicitly
Now the test completes in milliseconds
without waiting
jasmine.Clock.useMock();
autoComplete.delayHide();
expect($('#name')).toBeVisible();
jasmine.Clock.tick(500);
expect($('#name')).not.toBeVisible();
MOCKING TIME
new Date()tends to return different values over time
Actually, that's the whole point :)
But how do we test code that does that?
We cannot expecton a value that changes on every run
We can mock the Date()constructor!
var then = new Date();
jasmine.Clock.tick(42000);
var now = new Date();
expect(now.getTime() - then.getTime()).toBe(42000);
MOCKING DATE() WITH JASMINE
Keep Date() and setTimeout() in sync
jasmine.GlobalDate = window.Date;
var MockDate = function () {
var now = jasmine.Clock.defaultFakeTimer.nowMillis;
return new jasmine.GlobalDate(now);
};
MockDate.prototype = jasmine.GlobalDate.prototype;
window.Date = MockDate;
jasmine.getEnv().currentSpec.after(function () {
window.Date = jasmine.GlobalDate;
});
MOCKING AJAX REQUESTS
To test in isolation
To vastly speed up the tests
Many options
can.fixture
Mockjax
Sinon
can.fixture('/getNames', function (original, respondWith) {
respondWith({list: ['rachel', 'lakshmi']});
});
autoComplete = new AutoComplete('#name', {
listUrl: '/getNames'
});
jasmine.Clock.tick(can.fixture.delay);
respondWith(500); // Internal server error
DOM FIXTURES
Supply the markup required by the code
Automatically cleanup markup after every test
Various solutions
Built into QUnit as #qunit-fixture
Use jasmine-jquery
var fixtures = jasmine.getFixtures();
fixtures.set(fixtures.sandbox());
$('<input id="name">').appendTo('#sandbox');
autoComplete = new AutoComplete('#name');
SPYING ON EVENTS
How do we test that an event was triggered?
Or prevented from bubbling?
Use jasmine-jquery!
'keypress': function (element, event) {
var pattern = this.element.val() +
String.fromCharCode(event.charCode);
var match = this.getMatch(pattern);
if(match) {
event.preventDefault();
this.element.val(match);
}
}
keypressEvent = spyOnEvent('#name', 'keypress');
$('#name').trigger($.Event('keypress', {charCode: 109}));
expect(keypressEvent).toHaveBeenPrevented();
SIMULATING CSS TRANSITIONS
JASMINE MATCHERS
EXPRESSIVE MATCHERS
Make your tests more readable
Use jasmine-jquery for jQuery-specific matchers
Instead of:
Prefer:
expect($('#name').is(':visible')).toBeFalsy();
expect($('#name')).not.toBeVisible();
ROLL YOUR OWN MATCHERS
Make your tests even more readable
Like this can.js specific matcher:
Defined like this:
github.com/pivotal/jasmine/wiki/Matchers
expect($('#name')).toHaveControlOfType(AutoComplete);
jasmine.getEnv().currentSpec.addMatchers({
toHaveControlOfType: function (expected) {
var actual = this.actual.controls(expected);
return actual.length > 0;
}
});
STRUCTURE OF TEST CODE
Reuse common setup code
By nesting Jasmine's describe()functions
describe('delayHide', function () {
beforeEach(function () {
autoComplete.delayHide();
});
it('should initially stay visible', function () {
expect($('#name')).toBeVisible();
});
describe('after a delay', function () {
beforeEach(function () {
jasmine.Clock.tick(500);
});
it('should be invisible', function () {
expect($('#name')).not.toBeVisible();
});
});
});
BROWSER-SPECIFIC TESTS
Some code is browser specific
maybe using a browser specific API
and might only be testable in that browser
Tests can be conditioned
Or iterated...
can.each([
{
response: {list: ['rachel', 'lakshmi']},
expected: ['rachel', 'lakshmi']
},
{
response: 500,
expected: []
}
], function (scenario) {
describe('when ' + JSON.stringify(scenario.response), function () {
it('should ' + JSON.stringify(scenario.expected), function () {
});
});
});
RESOURCES
github.com/larsthorup/jasmine-demo-advanced
@larsthorup
pivotal.github.io/jasmine
github.com/velesin/jasmine-jquery
canjs.com
github.com/hakimel/reveal.js

Más contenido relacionado

La actualidad más candente

CPP Language Basics - Reference
CPP Language Basics - ReferenceCPP Language Basics - Reference
CPP Language Basics - ReferenceMohammed Sikander
 
React Context API
React Context APIReact Context API
React Context APINodeXperts
 
codecept.js introduce - front end test E2E tool introduce
codecept.js introduce - front end test E2E tool introducecodecept.js introduce - front end test E2E tool introduce
codecept.js introduce - front end test E2E tool introduceCaesar Chi
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Steve Pember
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP FunctionsAhmed Swilam
 
ADO.NET Entity Framework
ADO.NET Entity FrameworkADO.NET Entity Framework
ADO.NET Entity FrameworkDoncho Minkov
 
Reactjs workshop (1)
Reactjs workshop (1)Reactjs workshop (1)
Reactjs workshop (1)Ahmed rebai
 
A Deeper look into Javascript Basics
A Deeper look into Javascript BasicsA Deeper look into Javascript Basics
A Deeper look into Javascript BasicsMindfire Solutions
 
Type script - advanced usage and practices
Type script  - advanced usage and practicesType script  - advanced usage and practices
Type script - advanced usage and practicesIwan van der Kleijn
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code PrinciplesYeurDreamin'
 
ES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptWojciech Dzikowski
 

La actualidad más candente (20)

React render props
React render propsReact render props
React render props
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
CPP Language Basics - Reference
CPP Language Basics - ReferenceCPP Language Basics - Reference
CPP Language Basics - Reference
 
React Context API
React Context APIReact Context API
React Context API
 
codecept.js introduce - front end test E2E tool introduce
codecept.js introduce - front end test E2E tool introducecodecept.js introduce - front end test E2E tool introduce
codecept.js introduce - front end test E2E tool introduce
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
 
React for Beginners
React for BeginnersReact for Beginners
React for Beginners
 
ADO.NET Entity Framework
ADO.NET Entity FrameworkADO.NET Entity Framework
ADO.NET Entity Framework
 
Reactjs workshop (1)
Reactjs workshop (1)Reactjs workshop (1)
Reactjs workshop (1)
 
A Deeper look into Javascript Basics
A Deeper look into Javascript BasicsA Deeper look into Javascript Basics
A Deeper look into Javascript Basics
 
Learning typescript
Learning typescriptLearning typescript
Learning typescript
 
Junit
JunitJunit
Junit
 
Type script - advanced usage and practices
Type script  - advanced usage and practicesType script  - advanced usage and practices
Type script - advanced usage and practices
 
Spring Core
Spring CoreSpring Core
Spring Core
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
JavaScript Basic
JavaScript BasicJavaScript Basic
JavaScript Basic
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code Principles
 
ES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern Javascript
 

Similar a Advanced Jasmine Front-End JavaScript Unit Testing

Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeJosh Mock
 
Unit testing with mocha
Unit testing with mochaUnit testing with mocha
Unit testing with mochaRevath S Kumar
 
Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Anna Khabibullina
 
JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014DA-14
 
In search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingIn search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingAnna Khabibullina
 
The Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScriptThe Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScriptHazelcast
 
Testing JavaScript with Jasmine in Rails Applications
Testing JavaScript with Jasmine in Rails Applications Testing JavaScript with Jasmine in Rails Applications
Testing JavaScript with Jasmine in Rails Applications Hector Correa
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineGil Fink
 
An Introduction to AngularJs Unittesting
An Introduction to AngularJs UnittestingAn Introduction to AngularJs Unittesting
An Introduction to AngularJs UnittestingInthra onsap
 
Testing JavaScript Applications
Testing JavaScript ApplicationsTesting JavaScript Applications
Testing JavaScript ApplicationsThe Rolling Scopes
 
Testing Web Applications
Testing Web ApplicationsTesting Web Applications
Testing Web ApplicationsSeth McLaughlin
 
JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven PractisesRobert MacLean
 
Advanced Javascript Unit Testing
Advanced Javascript Unit TestingAdvanced Javascript Unit Testing
Advanced Javascript Unit TestingLars Thorup
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentAll Things Open
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 
Cappuccino @ JSConf 2009
Cappuccino @ JSConf 2009Cappuccino @ JSConf 2009
Cappuccino @ JSConf 2009tolmasky
 

Similar a Advanced Jasmine Front-End JavaScript Unit Testing (20)

Jason code testing framework
Jason code testing frameworkJason code testing framework
Jason code testing framework
 
Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and Node
 
Unit testing with mocha
Unit testing with mochaUnit testing with mocha
Unit testing with mocha
 
Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)
 
JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014
 
In search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingIn search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testing
 
The Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScriptThe Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScript
 
Testing JavaScript with Jasmine in Rails Applications
Testing JavaScript with Jasmine in Rails Applications Testing JavaScript with Jasmine in Rails Applications
Testing JavaScript with Jasmine in Rails Applications
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
 
An Introduction to AngularJs Unittesting
An Introduction to AngularJs UnittestingAn Introduction to AngularJs Unittesting
An Introduction to AngularJs Unittesting
 
Testing JavaScript Applications
Testing JavaScript ApplicationsTesting JavaScript Applications
Testing JavaScript Applications
 
Testing Web Applications
Testing Web ApplicationsTesting Web Applications
Testing Web Applications
 
Agile Android
Agile AndroidAgile Android
Agile Android
 
JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven Practises
 
Advanced Javascript Unit Testing
Advanced Javascript Unit TestingAdvanced Javascript Unit Testing
Advanced Javascript Unit Testing
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
JavaFX Overview
JavaFX OverviewJavaFX Overview
JavaFX Overview
 
JavaFX Pitfalls
JavaFX PitfallsJavaFX Pitfalls
JavaFX Pitfalls
 
Cappuccino @ JSConf 2009
Cappuccino @ JSConf 2009Cappuccino @ JSConf 2009
Cappuccino @ JSConf 2009
 

Más de Lars Thorup

100 tests per second - 40 releases per week
100 tests per second - 40 releases per week100 tests per second - 40 releases per week
100 tests per second - 40 releases per weekLars Thorup
 
SQL or NoSQL - how to choose
SQL or NoSQL - how to chooseSQL or NoSQL - how to choose
SQL or NoSQL - how to chooseLars Thorup
 
Super fast end-to-end-tests
Super fast end-to-end-testsSuper fast end-to-end-tests
Super fast end-to-end-testsLars Thorup
 
Extreme Programming - to the next-level
Extreme Programming - to the next-levelExtreme Programming - to the next-level
Extreme Programming - to the next-levelLars Thorup
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy codeLars Thorup
 
Advanced QUnit - Front-End JavaScript Unit Testing
Advanced QUnit - Front-End JavaScript Unit TestingAdvanced QUnit - Front-End JavaScript Unit Testing
Advanced QUnit - Front-End JavaScript Unit TestingLars Thorup
 
Put "fast" back in "fast feedback"
Put "fast" back in "fast feedback"Put "fast" back in "fast feedback"
Put "fast" back in "fast feedback"Lars Thorup
 
Database Schema Evolution
Database Schema EvolutionDatabase Schema Evolution
Database Schema EvolutionLars Thorup
 
Javascript unit testing with QUnit and Sinon
Javascript unit testing with QUnit and SinonJavascript unit testing with QUnit and Sinon
Javascript unit testing with QUnit and SinonLars Thorup
 
Continuous Integration for front-end JavaScript
Continuous Integration for front-end JavaScriptContinuous Integration for front-end JavaScript
Continuous Integration for front-end JavaScriptLars Thorup
 
Automated Performance Testing
Automated Performance TestingAutomated Performance Testing
Automated Performance TestingLars Thorup
 
Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)Lars Thorup
 
High Performance Software Engineering Teams
High Performance Software Engineering TeamsHigh Performance Software Engineering Teams
High Performance Software Engineering TeamsLars Thorup
 
Elephant Carpaccio
Elephant CarpaccioElephant Carpaccio
Elephant CarpaccioLars Thorup
 
Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++Lars Thorup
 
Unit Testing in JavaScript with MVC and QUnit
Unit Testing in JavaScript with MVC and QUnitUnit Testing in JavaScript with MVC and QUnit
Unit Testing in JavaScript with MVC and QUnitLars Thorup
 
Introduction to Automated Testing
Introduction to Automated TestingIntroduction to Automated Testing
Introduction to Automated TestingLars Thorup
 

Más de Lars Thorup (18)

100 tests per second - 40 releases per week
100 tests per second - 40 releases per week100 tests per second - 40 releases per week
100 tests per second - 40 releases per week
 
SQL or NoSQL - how to choose
SQL or NoSQL - how to chooseSQL or NoSQL - how to choose
SQL or NoSQL - how to choose
 
Super fast end-to-end-tests
Super fast end-to-end-testsSuper fast end-to-end-tests
Super fast end-to-end-tests
 
Extreme Programming - to the next-level
Extreme Programming - to the next-levelExtreme Programming - to the next-level
Extreme Programming - to the next-level
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy code
 
Advanced QUnit - Front-End JavaScript Unit Testing
Advanced QUnit - Front-End JavaScript Unit TestingAdvanced QUnit - Front-End JavaScript Unit Testing
Advanced QUnit - Front-End JavaScript Unit Testing
 
Put "fast" back in "fast feedback"
Put "fast" back in "fast feedback"Put "fast" back in "fast feedback"
Put "fast" back in "fast feedback"
 
Database Schema Evolution
Database Schema EvolutionDatabase Schema Evolution
Database Schema Evolution
 
Javascript unit testing with QUnit and Sinon
Javascript unit testing with QUnit and SinonJavascript unit testing with QUnit and Sinon
Javascript unit testing with QUnit and Sinon
 
Continuous Integration for front-end JavaScript
Continuous Integration for front-end JavaScriptContinuous Integration for front-end JavaScript
Continuous Integration for front-end JavaScript
 
Automated Performance Testing
Automated Performance TestingAutomated Performance Testing
Automated Performance Testing
 
Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)
 
Agile Contracts
Agile ContractsAgile Contracts
Agile Contracts
 
High Performance Software Engineering Teams
High Performance Software Engineering TeamsHigh Performance Software Engineering Teams
High Performance Software Engineering Teams
 
Elephant Carpaccio
Elephant CarpaccioElephant Carpaccio
Elephant Carpaccio
 
Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++
 
Unit Testing in JavaScript with MVC and QUnit
Unit Testing in JavaScript with MVC and QUnitUnit Testing in JavaScript with MVC and QUnit
Unit Testing in JavaScript with MVC and QUnit
 
Introduction to Automated Testing
Introduction to Automated TestingIntroduction to Automated Testing
Introduction to Automated Testing
 

Último

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 

Último (20)

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 

Advanced Jasmine Front-End JavaScript Unit Testing

  • 1. ADVANCED JASMINE FRONT-END JAVASCRIPT UNIT TESTING /Lars Thorup, ZeaLake @larsthorup
  • 2. WHO IS LARS THORUP Software developer/architect C++, C# and JavaScript Test Driven Development Coach: Teaching agile and automated testing Advisor: Assesses software projects and companies Founder and CEO of ZeaLake
  • 3. AGENDA Unit tests gives quality feedback Make them fast Make them precise Run thousands of unit tests in seconds We will look at Mocking techniques Front-end specific testing patterns Assuming knowledge about JavaScript and unit testing
  • 4. JASMINE BASICS describe('Calculator', function () { var calc; beforeEach(function () { calc = new Calculator(); }); it('should multiply', function () { expect(calc.multiply(6, 7)).toBe(42); }); });
  • 6. HOW TO TEST IN ISOLATION? We want to test code in isolation here the code is the 'keypress' event handler and isolation means not invoking the getMatch() method 'keypress': function (element, event) { var pattern = this.element.val(); pattern += String.fromCharCode(event.charCode); var match = this.getMatch(pattern); if (match) { event.preventDefault(); this.element.val(match); } }
  • 7. MOCKING METHODS We can mock the getMatch() method decide how the mock should behave verify that the mocked method was called correctly spyOn(autoComplete, 'getMatch').andReturn('monique'); $('#name').trigger($.Event('keypress', {charCode: 109})); expect(autoComplete.getMatch).toHaveBeenCalledWith('m'); expect($('#name')).toHaveValue('monique');
  • 8. MOCKING GLOBAL FUNCTIONS Global functions are properties of the window object openPopup: function (url) { var popup = window.open(url, '_blank', 'resizable'); popup.focus(); } var popup; spyOn(window, 'open').andCallFake(function () { popup = { focus: jasmine.createSpy() }; return popup; }); autoComplete.openPopup('zealake.com'); expect(window.open).toHaveBeenCalledWith('zealake.com', '_blank', 'resizable'); expect(popup.focus).toHaveBeenCalledWith();
  • 9. MOCKING CONSTRUCTORS Constructors are functions with thisbeing the object to construct this.input = new window.AutoComplete(inputElement, { listUrl: this.options.listUrl }); this.input.focus(); spyOn(window, 'AutoComplete').andCallFake(function () { this.focus = jasmine.createSpy(); }); expect(window.AutoComplete.callCount).toBe(1); var args = window.AutoComplete.mostRecentCall.args; expect(args[0]).toBe('#name'); expect(args[1]).toEqual({listUrl: '/someUrl'}); var object = window.AutoComplete.mostRecentCall.object; expect(object.focus).toHaveBeenCalledWith();
  • 10. HOW TO AVOID WAITING? We want the tests to be fast So don't use Jasmine waitsFor() But we often need to wait For animations to complete For AJAX responses to return delayHide: function () { var self = this; setTimeout(function () { self.element.hide(); }, this.options.hideDelay); }
  • 11. MOCKING TIMERS Use Jasmine's mock clock Control the clock explicitly Now the test completes in milliseconds without waiting jasmine.Clock.useMock(); autoComplete.delayHide(); expect($('#name')).toBeVisible(); jasmine.Clock.tick(500); expect($('#name')).not.toBeVisible();
  • 12. MOCKING TIME new Date()tends to return different values over time Actually, that's the whole point :) But how do we test code that does that? We cannot expecton a value that changes on every run We can mock the Date()constructor! var then = new Date(); jasmine.Clock.tick(42000); var now = new Date(); expect(now.getTime() - then.getTime()).toBe(42000);
  • 13. MOCKING DATE() WITH JASMINE Keep Date() and setTimeout() in sync jasmine.GlobalDate = window.Date; var MockDate = function () { var now = jasmine.Clock.defaultFakeTimer.nowMillis; return new jasmine.GlobalDate(now); }; MockDate.prototype = jasmine.GlobalDate.prototype; window.Date = MockDate; jasmine.getEnv().currentSpec.after(function () { window.Date = jasmine.GlobalDate; });
  • 14. MOCKING AJAX REQUESTS To test in isolation To vastly speed up the tests Many options can.fixture Mockjax Sinon can.fixture('/getNames', function (original, respondWith) { respondWith({list: ['rachel', 'lakshmi']}); }); autoComplete = new AutoComplete('#name', { listUrl: '/getNames' }); jasmine.Clock.tick(can.fixture.delay); respondWith(500); // Internal server error
  • 15. DOM FIXTURES Supply the markup required by the code Automatically cleanup markup after every test Various solutions Built into QUnit as #qunit-fixture Use jasmine-jquery var fixtures = jasmine.getFixtures(); fixtures.set(fixtures.sandbox()); $('<input id="name">').appendTo('#sandbox'); autoComplete = new AutoComplete('#name');
  • 16. SPYING ON EVENTS How do we test that an event was triggered? Or prevented from bubbling? Use jasmine-jquery! 'keypress': function (element, event) { var pattern = this.element.val() + String.fromCharCode(event.charCode); var match = this.getMatch(pattern); if(match) { event.preventDefault(); this.element.val(match); } } keypressEvent = spyOnEvent('#name', 'keypress'); $('#name').trigger($.Event('keypress', {charCode: 109})); expect(keypressEvent).toHaveBeenPrevented();
  • 19. EXPRESSIVE MATCHERS Make your tests more readable Use jasmine-jquery for jQuery-specific matchers Instead of: Prefer: expect($('#name').is(':visible')).toBeFalsy(); expect($('#name')).not.toBeVisible();
  • 20. ROLL YOUR OWN MATCHERS Make your tests even more readable Like this can.js specific matcher: Defined like this: github.com/pivotal/jasmine/wiki/Matchers expect($('#name')).toHaveControlOfType(AutoComplete); jasmine.getEnv().currentSpec.addMatchers({ toHaveControlOfType: function (expected) { var actual = this.actual.controls(expected); return actual.length > 0; } });
  • 21. STRUCTURE OF TEST CODE Reuse common setup code By nesting Jasmine's describe()functions describe('delayHide', function () { beforeEach(function () { autoComplete.delayHide(); }); it('should initially stay visible', function () { expect($('#name')).toBeVisible(); }); describe('after a delay', function () { beforeEach(function () { jasmine.Clock.tick(500); }); it('should be invisible', function () { expect($('#name')).not.toBeVisible(); }); }); });
  • 22. BROWSER-SPECIFIC TESTS Some code is browser specific maybe using a browser specific API and might only be testable in that browser Tests can be conditioned Or iterated... can.each([ { response: {list: ['rachel', 'lakshmi']}, expected: ['rachel', 'lakshmi'] }, { response: 500, expected: [] } ], function (scenario) { describe('when ' + JSON.stringify(scenario.response), function () { it('should ' + JSON.stringify(scenario.expected), function () { }); }); });