SlideShare a Scribd company logo
1 of 34
linkedin/carmel-cohen-368470103github.com/carmelccarmelc@wix.com
Rich Angular Component Testing kit
TurnerJS
Carmel Cohen
Why Turner? That’s me
1 / Client Test Levels
Business Logic View
IT IS THE BRAIN OF
THE APPLICATION
IT HAS TO BE
STUNNING
Services
Page Component
Image Picker
Location Picker
Duration Picker
Date Picker
Unit tests verify a specific section of code
(i.e. functions)
Services
Page Component
Image Picker
Location Picker
Duration Picker
Date Picker
Component tests verify well, components
Services
Page Component
Image Picker
Location Picker
Duration Picker
Date Picker
Integration tests verify interfaces between components
Services
Page Component
Image Picker
Location Picker
Duration Picker
Date Picker
E2E tests verify a completely integrated system
Services
Page Component
Image Picker
Location Picker
Duration Picker
Date Picker
Unit
Component
Integration
E2E
Ease of
Maintenance
Running Speed Ease of
Creation
Level of
Confidence
Why not stick to a single level?
2 / Real life example
3 / Testing it (Live Demo)
'use strict';
describe('Directive: durationPicker', () => {
let scope, element;
beforeEach(function () {
module('schedulerOwnerAppInternal');
});
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new();
}));
it('should split duration into hours and minutes', inject(function ($compile) {
scope.item = {
duration: 65
};
element = angular.element(
'<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('1');
expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('5');
}));
it('should default the hours and minutes as 0 when duration is not defined', inject(function ($compile) {
scope.item = {
};
element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('0');
expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('0');
}));
it('should update the duration of the model', inject(function ($compile) {
scope.item = {
duration: 20
};
element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
element.find('[data-hook="duration-picker-hours"]').val('1').change();
element.find('[data-hook="duration-picker-minutes"]').val('35').change();
scope.$digest();
expect(scope.item.duration).toBe(95);
}));
it('should validate that at least one of the inputs should be 1 and above and the other is 0 and above', inject(function
($compile) {
scope.item = {};
element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
let hoursInput = element.find('[data-hook="duration-picker-hours"]');
let minutesInput = element.find('[data-hook="duration-picker-minutes"]');
expect(hoursInput.attr('ng-min')).toBe('1');
expect(minutesInput.attr('ng-min')).toBe('1');
hoursInput.val('2').change();
scope.$digest();
expect(minutesInput.attr('ng-min')).toBe('0');
minutesInput.val('2').change();
scope.$digest();
expect(hoursInput.attr('ng-min')).toBe('0');
}));
It’s nice, but…
• A mix of selectors and expectations
• Complex setup for each test
• Not reusable in the testing of component that wraps
the duration picker
Introducing
TurnerComponentDriver
• Component oriented testing kit
• Removes the hassle of having to
deal with compilation and rendering
of the templates
• Supports hierarchies
• Easy to use selectors and
appending/detaching from body
Made by Carmel
4 / Using Turner (Live Demo)
API
• renderFromTemplate – renders a template with attributes which
are loaded to the scope and initializes the driver and its child
drivers
• findByDataHook/ All – selectors by data-hook attribute
• connectToBody, disconnectFromBody – connects the template to
the html body – useful when testing height and position
• defineChild/defineChildren – define a child driver (single or array)
in order to reuse drivers
Documentation: https://github.com/wix-private/turnerjs/blob/master/README.md#base-driver-methods-members
class DurationPickDriver extends TurnerComponentDriver {
render(item: {duration?: number}) {
this.renderFromTemplate('<boost-duration-picker item="item"></boost-duration-picker>', {item});
}
get hours(): string {
return this.getHoursElement().val();
}
set hours(newVal) {
this.getHoursElement().val(newVal).change();
this.scope.$digest();
}
get minutes(): string {
return this.getMinutesElement().val();
}
set minutes(newVal) {
this.getMinutesElement().val(newVal).change();
this.scope.$digest();
}
getMinimumHours(): string {
return this.getHoursElement().attr('ng-min');
}
getMinimumMinutes(): string {
return this.getMinutesElement().attr('ng-min');
}
getHoursElement(): ng.IAugmentedJQuery {
return this.findByDataHook('duration-picker-hours');
}
getMinutesElement(): ng.IAugmentedJQuery {
return this.findByDataHook('duration-picker-minutes');
}
}
'use strict';
describe('Directive: durationPicker', () => {
let scope, element;
beforeEach(function () {
module('schedulerOwnerAppInternal');
});
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new();
}));
it('should split duration into hours and minutes', inject(function ($compile) {
scope.item = {
duration: 65
};
element = angular.element(
'<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('1');
expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('5');
}));
let driver: DurationPickDriver;
beforeEach(function () {
module('schedulerOwnerAppInternal');
driver = new DurationPickDriver();
});
it('should split duration into hours and minutes', (() => {
let item = {
duration: 65
};
driver.render(item);
expect(driver.hours).toBe('1');
expect(driver.minutes).toBe('5');
}));
it('should default the hours and minutes as 0 when duration is not defined', inject(function ($compile) {
scope.item = {
};
element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('0');
expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('0');
}));
it('should update the duration of the model', inject(function ($compile) {
scope.item = {
duration: 20
};
element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
element.find('[data-hook="duration-picker-hours"]').val('1').change();
element.find('[data-hook="duration-picker-minutes"]').val('35').change();
scope.$digest();
expect(scope.item.duration).toBe(95);
}));
it('should default the hours and minutes as 0 when duration is not defined', () => {
let item = {
};
driver.render(item);
expect(driver.hours).toBe('0');
expect(driver.minutes).toBe('0');
});
it('should update the duration of the model', () => {
let item = {
duration: 20
};
driver.render(item);
driver.minutes = '35';
driver.hours = '1';
expect(item.duration).toBe(95);
});
it('should validate that at least one of the inputs should be 1 and above and the other is 0 and above', inject(function
($compile) {
scope.item = {};
element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>');
element = $compile(element)(scope);
scope.$digest();
let hoursInput = element.find('[data-hook="duration-picker-hours"]');
let minutesInput = element.find('[data-hook="duration-picker-minutes"]');
expect(hoursInput.attr('ng-min')).toBe('1');
expect(minutesInput.attr('ng-min')).toBe('1');
hoursInput.val('2').change();
scope.$digest();
expect(minutesInput.attr('ng-min')).toBe('0');
minutesInput.val('2').change();
scope.$digest();
expect(hoursInput.attr('ng-min')).toBe('0');
}));
it('should validate that at least one of the inputs should be 1 and above and the other is 0
and above', () => {
let item = {};
driver.render(item);
expect(driver.getMinimumHours()).toBe('1');
expect(driver.getMinimumMinutes()).toBe('1');
driver.hours = '2';
expect(driver.getMinimumMinutes()).toBe('0');
driver.minutes = '2';
expect(driver.getMinimumHours()).toBe('0');
});
class ClassFormDriver extends TurnerComponentDriver {
private durationPickerDriver: DurationPickDriver;
constructor() {
super();
this.durationPickerDriver = this.defineChild(new DurationPickDriver());
}
render() {
this.renderFromTemplate('<class-form-page></class-form-page>')
}
fillForm() {
this.durationPickerDriver.hours = '1';
...
}
}
And it can be reused!
Known Limitations
• CSS classes – ng-hide is not really
hiding the element
○ ng-if works just fine
• Overlapping elements are clickable
• Page navigation - one can check the
route but not really run a flow
○ Selenium is still needed…
Know your limits
5 / Summary
Summary
• An AngularJS page should be considered as a set of components
○ Each component should be tested separately
• Component testing level is used in order to test the components
via the DOM rather than controller functions
• By utilizing component testing, one can minimize the amount of
tests needed in the higher levels which are heavy, slow and hard
to maintain
○ The ‘cone’ is maintained
TurnerJS is making it easy, maintainable and quick
Thank You!
Any Questions?
Carmel Cohen
Future FED

More Related Content

What's hot

Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSKnoldus Inc.
 
Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Ahmed Moawad
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1Ahmed Moawad
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Morris Singer
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava SchmidtJavaDayUA
 
Hidden Docs in Angular
Hidden Docs in AngularHidden Docs in Angular
Hidden Docs in AngularYadong Xie
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Codescidept
 
JavaFX8 TestFX - CDI
JavaFX8   TestFX - CDIJavaFX8   TestFX - CDI
JavaFX8 TestFX - CDISven Ruppert
 
Angular - Improve Runtime performance 2019
Angular - Improve Runtime performance 2019Angular - Improve Runtime performance 2019
Angular - Improve Runtime performance 2019Eliran Eliassy
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesFederico Feroldi
 
RSpock Testing Framework for Ruby
RSpock Testing Framework for RubyRSpock Testing Framework for Ruby
RSpock Testing Framework for RubyBrice Argenson
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Ontico
 

What's hot (20)

Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJS
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
 
Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava Schmidt
 
Angular Unit Testing
Angular Unit TestingAngular Unit Testing
Angular Unit Testing
 
Hidden Docs in Angular
Hidden Docs in AngularHidden Docs in Angular
Hidden Docs in Angular
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
JavaFX8 TestFX - CDI
JavaFX8   TestFX - CDIJavaFX8   TestFX - CDI
JavaFX8 TestFX - CDI
 
Angular - Improve Runtime performance 2019
Angular - Improve Runtime performance 2019Angular - Improve Runtime performance 2019
Angular - Improve Runtime performance 2019
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala Microservices
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
Tdd iPhone For Dummies
Tdd iPhone For DummiesTdd iPhone For Dummies
Tdd iPhone For Dummies
 
Alteryx SDK
Alteryx SDKAlteryx SDK
Alteryx SDK
 
RSpock Testing Framework for Ruby
RSpock Testing Framework for RubyRSpock Testing Framework for Ruby
RSpock Testing Framework for Ruby
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
 

Similar to Angular component testing kit makes testing faster, easier and more maintainable

Angular Application Testing
Angular Application TestingAngular Application Testing
Angular Application TestingTroy Miles
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018Justin James
 
Testing in Ballerina Language
Testing in Ballerina LanguageTesting in Ballerina Language
Testing in Ballerina LanguageLynn Langit
 
Test Driven Development for Microservices
Test Driven Development for MicroservicesTest Driven Development for Microservices
Test Driven Development for MicroservicesBallerina
 
Porting legacy apps to Griffon
Porting legacy apps to GriffonPorting legacy apps to Griffon
Porting legacy apps to GriffonJames Williams
 
Angular Unit Testing from the Trenches
Angular Unit Testing from the TrenchesAngular Unit Testing from the Trenches
Angular Unit Testing from the TrenchesJustin James
 
Ember testing internals with ember cli
Ember testing internals with ember cliEmber testing internals with ember cli
Ember testing internals with ember cliCory Forsyth
 
Protractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applicationsProtractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applicationsLudmila Nesvitiy
 
React for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectReact for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectAtlassian
 
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Ukraine
 
Commit University - Exploring Angular 2
Commit University - Exploring Angular 2Commit University - Exploring Angular 2
Commit University - Exploring Angular 2Commit University
 
Self healing test automation with Healenium and Minimization of regression su...
Self healing test automation with Healenium and Minimization of regression su...Self healing test automation with Healenium and Minimization of regression su...
Self healing test automation with Healenium and Minimization of regression su...Dmitriy Gumeniuk
 
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015Codemotion
 
Top100summit 谷歌-scott-improve your automated web application testing
Top100summit  谷歌-scott-improve your automated web application testingTop100summit  谷歌-scott-improve your automated web application testing
Top100summit 谷歌-scott-improve your automated web application testingdrewz lin
 
Surviving UI Automation Armageddon with BELLATRIX.pptx
Surviving UI Automation Armageddon with BELLATRIX.pptxSurviving UI Automation Armageddon with BELLATRIX.pptx
Surviving UI Automation Armageddon with BELLATRIX.pptxNikolayAvramov4
 
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018Wim Selles
 
Top 10 Mistakes AngularJS Developers Make
Top 10 Mistakes AngularJS Developers MakeTop 10 Mistakes AngularJS Developers Make
Top 10 Mistakes AngularJS Developers MakeMark Meyer
 
Angular JS2 Training Session #2
Angular JS2 Training Session #2Angular JS2 Training Session #2
Angular JS2 Training Session #2Paras Mendiratta
 

Similar to Angular component testing kit makes testing faster, easier and more maintainable (20)

Angular Application Testing
Angular Application TestingAngular Application Testing
Angular Application Testing
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018Angular Unit Testing NDC Minn 2018
Angular Unit Testing NDC Minn 2018
 
Testing in Ballerina Language
Testing in Ballerina LanguageTesting in Ballerina Language
Testing in Ballerina Language
 
Test Driven Development for Microservices
Test Driven Development for MicroservicesTest Driven Development for Microservices
Test Driven Development for Microservices
 
Porting legacy apps to Griffon
Porting legacy apps to GriffonPorting legacy apps to Griffon
Porting legacy apps to Griffon
 
Angular Unit Testing from the Trenches
Angular Unit Testing from the TrenchesAngular Unit Testing from the Trenches
Angular Unit Testing from the Trenches
 
Ember testing internals with ember cli
Ember testing internals with ember cliEmber testing internals with ember cli
Ember testing internals with ember cli
 
Protractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applicationsProtractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applications
 
React for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectReact for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence Connect
 
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
 
Commit University - Exploring Angular 2
Commit University - Exploring Angular 2Commit University - Exploring Angular 2
Commit University - Exploring Angular 2
 
mean stack
mean stackmean stack
mean stack
 
Self healing test automation with Healenium and Minimization of regression su...
Self healing test automation with Healenium and Minimization of regression su...Self healing test automation with Healenium and Minimization of regression su...
Self healing test automation with Healenium and Minimization of regression su...
 
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
 
Top100summit 谷歌-scott-improve your automated web application testing
Top100summit  谷歌-scott-improve your automated web application testingTop100summit  谷歌-scott-improve your automated web application testing
Top100summit 谷歌-scott-improve your automated web application testing
 
Surviving UI Automation Armageddon with BELLATRIX.pptx
Surviving UI Automation Armageddon with BELLATRIX.pptxSurviving UI Automation Armageddon with BELLATRIX.pptx
Surviving UI Automation Armageddon with BELLATRIX.pptx
 
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
 
Top 10 Mistakes AngularJS Developers Make
Top 10 Mistakes AngularJS Developers MakeTop 10 Mistakes AngularJS Developers Make
Top 10 Mistakes AngularJS Developers Make
 
Angular JS2 Training Session #2
Angular JS2 Training Session #2Angular JS2 Training Session #2
Angular JS2 Training Session #2
 

Recently uploaded

The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...Call Girls in Nagpur High Profile
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performancesivaprakash250
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSISrknatarajan
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxpranjaldaimarysona
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxupamatechverse
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130Suhani Kapoor
 
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).pptssuser5c9d4b1
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Dr.Costas Sachpazis
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSKurinjimalarL3
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 

Recently uploaded (20)

The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSIS
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptx
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptx
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
 
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 

Angular component testing kit makes testing faster, easier and more maintainable

  • 3. 1 / Client Test Levels
  • 4. Business Logic View IT IS THE BRAIN OF THE APPLICATION IT HAS TO BE STUNNING
  • 5. Services Page Component Image Picker Location Picker Duration Picker Date Picker
  • 6. Unit tests verify a specific section of code (i.e. functions) Services Page Component Image Picker Location Picker Duration Picker Date Picker
  • 7. Component tests verify well, components Services Page Component Image Picker Location Picker Duration Picker Date Picker
  • 8. Integration tests verify interfaces between components Services Page Component Image Picker Location Picker Duration Picker Date Picker
  • 9. E2E tests verify a completely integrated system Services Page Component Image Picker Location Picker Duration Picker Date Picker
  • 10. Unit Component Integration E2E Ease of Maintenance Running Speed Ease of Creation Level of Confidence Why not stick to a single level?
  • 11. 2 / Real life example
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18. 3 / Testing it (Live Demo)
  • 19. 'use strict'; describe('Directive: durationPicker', () => { let scope, element; beforeEach(function () { module('schedulerOwnerAppInternal'); }); beforeEach(inject(function ($rootScope) { scope = $rootScope.$new(); })); it('should split duration into hours and minutes', inject(function ($compile) { scope.item = { duration: 65 }; element = angular.element( '<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('1'); expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('5'); }));
  • 20. it('should default the hours and minutes as 0 when duration is not defined', inject(function ($compile) { scope.item = { }; element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('0'); expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('0'); })); it('should update the duration of the model', inject(function ($compile) { scope.item = { duration: 20 }; element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); element.find('[data-hook="duration-picker-hours"]').val('1').change(); element.find('[data-hook="duration-picker-minutes"]').val('35').change(); scope.$digest(); expect(scope.item.duration).toBe(95); }));
  • 21. it('should validate that at least one of the inputs should be 1 and above and the other is 0 and above', inject(function ($compile) { scope.item = {}; element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); let hoursInput = element.find('[data-hook="duration-picker-hours"]'); let minutesInput = element.find('[data-hook="duration-picker-minutes"]'); expect(hoursInput.attr('ng-min')).toBe('1'); expect(minutesInput.attr('ng-min')).toBe('1'); hoursInput.val('2').change(); scope.$digest(); expect(minutesInput.attr('ng-min')).toBe('0'); minutesInput.val('2').change(); scope.$digest(); expect(hoursInput.attr('ng-min')).toBe('0'); }));
  • 22. It’s nice, but… • A mix of selectors and expectations • Complex setup for each test • Not reusable in the testing of component that wraps the duration picker
  • 23. Introducing TurnerComponentDriver • Component oriented testing kit • Removes the hassle of having to deal with compilation and rendering of the templates • Supports hierarchies • Easy to use selectors and appending/detaching from body Made by Carmel
  • 24. 4 / Using Turner (Live Demo)
  • 25. API • renderFromTemplate – renders a template with attributes which are loaded to the scope and initializes the driver and its child drivers • findByDataHook/ All – selectors by data-hook attribute • connectToBody, disconnectFromBody – connects the template to the html body – useful when testing height and position • defineChild/defineChildren – define a child driver (single or array) in order to reuse drivers Documentation: https://github.com/wix-private/turnerjs/blob/master/README.md#base-driver-methods-members
  • 26. class DurationPickDriver extends TurnerComponentDriver { render(item: {duration?: number}) { this.renderFromTemplate('<boost-duration-picker item="item"></boost-duration-picker>', {item}); } get hours(): string { return this.getHoursElement().val(); } set hours(newVal) { this.getHoursElement().val(newVal).change(); this.scope.$digest(); } get minutes(): string { return this.getMinutesElement().val(); } set minutes(newVal) { this.getMinutesElement().val(newVal).change(); this.scope.$digest(); } getMinimumHours(): string { return this.getHoursElement().attr('ng-min'); } getMinimumMinutes(): string { return this.getMinutesElement().attr('ng-min'); } getHoursElement(): ng.IAugmentedJQuery { return this.findByDataHook('duration-picker-hours'); } getMinutesElement(): ng.IAugmentedJQuery { return this.findByDataHook('duration-picker-minutes'); } }
  • 27. 'use strict'; describe('Directive: durationPicker', () => { let scope, element; beforeEach(function () { module('schedulerOwnerAppInternal'); }); beforeEach(inject(function ($rootScope) { scope = $rootScope.$new(); })); it('should split duration into hours and minutes', inject(function ($compile) { scope.item = { duration: 65 }; element = angular.element( '<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('1'); expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('5'); })); let driver: DurationPickDriver; beforeEach(function () { module('schedulerOwnerAppInternal'); driver = new DurationPickDriver(); }); it('should split duration into hours and minutes', (() => { let item = { duration: 65 }; driver.render(item); expect(driver.hours).toBe('1'); expect(driver.minutes).toBe('5'); }));
  • 28. it('should default the hours and minutes as 0 when duration is not defined', inject(function ($compile) { scope.item = { }; element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); expect(element.find('[data-hook="duration-picker-hours"]').val()).toBe('0'); expect(element.find('[data-hook="duration-picker-minutes"]').val()).toBe('0'); })); it('should update the duration of the model', inject(function ($compile) { scope.item = { duration: 20 }; element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); element.find('[data-hook="duration-picker-hours"]').val('1').change(); element.find('[data-hook="duration-picker-minutes"]').val('35').change(); scope.$digest(); expect(scope.item.duration).toBe(95); })); it('should default the hours and minutes as 0 when duration is not defined', () => { let item = { }; driver.render(item); expect(driver.hours).toBe('0'); expect(driver.minutes).toBe('0'); }); it('should update the duration of the model', () => { let item = { duration: 20 }; driver.render(item); driver.minutes = '35'; driver.hours = '1'; expect(item.duration).toBe(95); });
  • 29. it('should validate that at least one of the inputs should be 1 and above and the other is 0 and above', inject(function ($compile) { scope.item = {}; element = angular.element('<boost-duration-picker item="item"></boost-duration-picker>'); element = $compile(element)(scope); scope.$digest(); let hoursInput = element.find('[data-hook="duration-picker-hours"]'); let minutesInput = element.find('[data-hook="duration-picker-minutes"]'); expect(hoursInput.attr('ng-min')).toBe('1'); expect(minutesInput.attr('ng-min')).toBe('1'); hoursInput.val('2').change(); scope.$digest(); expect(minutesInput.attr('ng-min')).toBe('0'); minutesInput.val('2').change(); scope.$digest(); expect(hoursInput.attr('ng-min')).toBe('0'); })); it('should validate that at least one of the inputs should be 1 and above and the other is 0 and above', () => { let item = {}; driver.render(item); expect(driver.getMinimumHours()).toBe('1'); expect(driver.getMinimumMinutes()).toBe('1'); driver.hours = '2'; expect(driver.getMinimumMinutes()).toBe('0'); driver.minutes = '2'; expect(driver.getMinimumHours()).toBe('0'); });
  • 30. class ClassFormDriver extends TurnerComponentDriver { private durationPickerDriver: DurationPickDriver; constructor() { super(); this.durationPickerDriver = this.defineChild(new DurationPickDriver()); } render() { this.renderFromTemplate('<class-form-page></class-form-page>') } fillForm() { this.durationPickerDriver.hours = '1'; ... } } And it can be reused!
  • 31. Known Limitations • CSS classes – ng-hide is not really hiding the element ○ ng-if works just fine • Overlapping elements are clickable • Page navigation - one can check the route but not really run a flow ○ Selenium is still needed… Know your limits
  • 33. Summary • An AngularJS page should be considered as a set of components ○ Each component should be tested separately • Component testing level is used in order to test the components via the DOM rather than controller functions • By utilizing component testing, one can minimize the amount of tests needed in the higher levels which are heavy, slow and hard to maintain ○ The ‘cone’ is maintained TurnerJS is making it easy, maintainable and quick

Editor's Notes

  1. You would want to start from where you get the highest level of confidence You can’t start with E2E – testing the entire system