77
Testing AngularJS

Testing AngularJS

Embed Size (px)

DESCRIPTION

A walkthrough inside testing core concepts and how to apply them with AngularJS, plus an overview on the tools.

Citation preview

Page 1: Testing AngularJS

Testing!AngularJS

Page 2: Testing AngularJS

Jacopo NardielloPadawan Programmer

Presentation code on Github: github.com/jnardiello/angularjsday-testing-angular

Page 3: Testing AngularJS

Why?

Page 4: Testing AngularJS

Fail in Production

Page 5: Testing AngularJS

Fail in dev

Page 6: Testing AngularJS

Thanks to testing we…

Page 7: Testing AngularJS

fail fast

Page 8: Testing AngularJS

No Debugging

Page 9: Testing AngularJS

Machines handles bug hunting

Page 10: Testing AngularJS

Tests are a tool to handle complexity

Page 11: Testing AngularJS

Angular is no exception

Page 12: Testing AngularJS

Rock solid code

Benefits

Page 13: Testing AngularJS

Fast Dev Cycle

Benefits

Rock solid code

Page 14: Testing AngularJS

Relaxed Team

Benefits

Fast Dev Cycle

Rock solid code

Page 15: Testing AngularJS

Relaxed Team

Benefits

Fast Dev Cycle

Rock solid code

Relaxed PM

Page 16: Testing AngularJS

Testing Javascript

Page 17: Testing AngularJS

Testing Javascript

describe(“…”, function() { it(“should do something", function() { expect(true).toBe(true); }); });

Page 18: Testing AngularJS

Testing Javascript

describe(“…”, function() { it(“should do something", function() { expect(true).toBe(true); }); });

Page 19: Testing AngularJS

Types of tests

Page 20: Testing AngularJS

Unit tests

• Small portions of code

• Code is isolated

• Quick and easy

Page 21: Testing AngularJS

Integration tests

Interaction between elements

Page 22: Testing AngularJS

• From the product owner point of view

• They are (computationally) expensive and slow

Acceptance tests

Page 23: Testing AngularJS

Angular is special

Page 24: Testing AngularJS

Misko Hevery

“Agile Coach at Google where he is responsible for coaching Googlers to maintain the high level of automated testing culture”

- misko.hevery.com/about/

Page 25: Testing AngularJS

Misko Hevery

+

Page 26: Testing AngularJS

“Angular is written with testability in mind”

- Angular Doc

Page 27: Testing AngularJS

Why is Angular easily testable?

Page 28: Testing AngularJS

Dependency Injection

Page 29: Testing AngularJS

DI

As a Pattern Framework

Page 30: Testing AngularJS

DI as Patternfunction Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }

Page 31: Testing AngularJS

DI as Patternfunction Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }

Page 32: Testing AngularJS

DI as Pattern

function Car(wheel, engine, door) { this.move = function() { engine.on(); wheel.rotate(); door.open(); } }

Page 33: Testing AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 34: Testing AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 35: Testing AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 36: Testing AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 37: Testing AngularJS

DI as frameworkfunction main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }

Page 38: Testing AngularJS

DI as frameworkfunction main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }

Car.$inject = [‘wheel’, ‘engine’, ‘door’]; function Car(wheel, engine, door) { this.move = function() { … } }

Page 39: Testing AngularJS

DI as frameworkfunction main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }

Car.$inject = [‘wheel’, ‘engine’, ‘door’]; function Car(wheel, engine, door) { this.move = function() { … } }

Page 40: Testing AngularJS

Angular testability is super-heroic!

but…

Page 41: Testing AngularJS

“you still have to do the right thing.”- Angular Doc

Page 42: Testing AngularJS

Testability

1. Don’t use new2. Don’t use globals

Page 43: Testing AngularJS

The Angular Way

Page 44: Testing AngularJS

Solid structured code

Page 45: Testing AngularJS

Testing components

Page 46: Testing AngularJS

Controllerfunction RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }

Page 47: Testing AngularJS

Controllerfunction RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }

Page 48: Testing AngularJS

var $scope = {}; var rc = $controller( 'RocketCtrl', { $scope: $scope } ); !$scope.currentFuel = 80; $scope.finalCheck(); expect($scope.check).toEqual('ko');

Controller Test

Page 49: Testing AngularJS

Directiveapp.directive('rocketLaunchPad', function () { return { restrict: 'AE', replace: true, template: ‘<rocket-launch-pad> Rocket here <rocket-launch-pad>’ }; });

Page 50: Testing AngularJS

Directive Test

it(‘Check launchpad was installed', function() { var element = $compile(“<rocket-launch-pad></rocket-launch-pad>”)($rootScope); ! expect(element.html()).toContain("Rocket here"); });

Page 51: Testing AngularJS

Filter Test.filter('i18n', function() { return function (str) { return translations.hasOwnProperty(str) && translations[str] || str; } })

var length = $filter('i18n'); expect(i18n(‘ciao’)).toEqual(‘hi’); expect(length(‘abc’)).toEqual(‘abc');

Page 52: Testing AngularJS

Tools

Page 53: Testing AngularJS
Page 54: Testing AngularJS

Karma

Protractor

Page 55: Testing AngularJS

Test Runner

Page 56: Testing AngularJS

Karma

Run tests against real browsers

Page 57: Testing AngularJS

Karma

Run tests against real browsers

Unit tests

Page 58: Testing AngularJS

Config file> karma init

Page 59: Testing AngularJS

Config file> karma init

- frameworks: [‘jasmine’]

Page 60: Testing AngularJS

Config file> karma init

- frameworks: [‘jasmine’]- autoWatch: true

Page 61: Testing AngularJS

Config file> karma init

- frameworks: [‘jasmine’]

- files: [ ‘../tests/controllerSpec.js’ ],

- autoWatch: true

Page 62: Testing AngularJS

Config file> karma init

- frameworks: [‘jasmine’]

- files: [ ‘../tests/controllerSpec.js’ ],

- autoWatch: true

- browsers: ['Chrome']

Page 63: Testing AngularJS

Using Karma> karma start config.js

Page 64: Testing AngularJS

Using Karma> karma start config.js

Page 65: Testing AngularJS

• From the product owner point of view

• They are (computationally) expensive and slow

Acceptance tests

Page 66: Testing AngularJS

• They can be very slow

• Hard to write

• Hard to keep updated

Acceptance tests

Page 67: Testing AngularJS

ProtractorE2E Angular Testing

Angular wrapper for WebDriver

Page 68: Testing AngularJS

Anatomy of a E2E testdescribe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });

Page 69: Testing AngularJS

Global Variablesdescribe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });

Page 70: Testing AngularJS

Global Variablesdescribe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });

Super-Happy Panda!

Page 71: Testing AngularJS

Page Objects

Protractor provides

Page 72: Testing AngularJS

Page Objects

Protractor provides

Debugging with superpowers

Page 73: Testing AngularJS

Page Objects

Protractor provides

Debugging with superpowersAngular-specific functions

Page 74: Testing AngularJS
Page 75: Testing AngularJS

Get your hands dirty!https://github.com/jnardiello/angularjsday-testing-angular

Tools in action - http://vimeo.com/86816782

Page 76: Testing AngularJS

Jacopo NardielloTwitter: @jnardiello

Say hi!

Page 77: Testing AngularJS

Jacopo NardielloTwitter: @jnardiello

Questions?