Testing!
AngularJS
Jacopo Nardiello
Padawan Programmer
Presentation code on Github:
github.com/jnardiello/angularjsday-testing-angular
Why?
Fail in
Production
Fail in dev
Thanks to testing
we…
fail fast
No Debugging
Machines handles
bug hunting
Tests are a tool to handle
complexity
Angular is
no exception
Rock solid code
Benefits
Fast Dev Cycle
Benefits
Rock solid code
Relaxed Team
Benefits
Fast Dev Cycle
Rock solid code
Relaxed Team
Benefits
Fast Dev Cycle
Rock solid code
Relaxed PM
Testing Javascript
Testing Javascript
describe(“…”, function() {
it(“should do something", function() {
expect(true).toBe(true);
});
});
Testing Javascript
describe(“…”, function() {
it(“should do something", function() {
expect(true).toBe(true);
});
});
Types of tests
Unit tests
• Small portions of code
• Code is isolated
• Quick and easy
Integration tests
Interaction between elements
• From the product
owner point of view
• They are
(computationally)
expensive and slow
Acceptance tests
Angular is special
Misko Hevery
“Agile Coach at Google where he is
responsible for coaching Googlers to
maintain the high level of automated
...
Misko Hevery
+
“Angular is written with
testability in mind”
- Angular Doc
Why is Angular easily
testable?
Dependency
Injection
DI
As a Pattern Framework
DI as Pattern
function Car() {
var wheel = new Wheel();
var engine = Engine.getInstance();
var door = app.get(‘Door’);
!
t...
DI as Pattern
function Car() {
var wheel = new Wheel();
var engine = Engine.getInstance();
var door = app.get(‘Door’);
!
t...
DI as Pattern
function Car(wheel, engine, door) {
this.move = function() {
engine.on();
wheel.rotate();
door.open();
}
}
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
DI as framework
function main() {
var injector = new Injector(….);
var car = injector.get(Car);
car.move();
}
DI as framework
function main() {
var injector = new Injector(….);
var car = injector.get(Car);
car.move();
}
Car.$inject ...
DI as framework
function main() {
var injector = new Injector(….);
var car = injector.get(Car);
car.move();
}
Car.$inject ...
Angular testability
is super-heroic!
but…
“you still have to do the right thing.”
- Angular Doc
Testability
1. Don’t use new
2. Don’t use globals
The Angular
Way
Solid structured
code
Testing components
Controller
function RocketCtrl($scope) {
$scope.maxFuel = 100;
$scope.finalCheck = function() {
if ($scope.currentFuel < $s...
Controller
function RocketCtrl($scope) {
$scope.maxFuel = 100;
$scope.finalCheck = function() {
if ($scope.currentFuel < $s...
var $scope = {};
var rc = $controller(
'RocketCtrl',
{ $scope: $scope }
);
!
$scope.currentFuel = 80;
$scope.finalCheck();
...
Directive
app.directive('rocketLaunchPad', function () {
return {
restrict: 'AE',
replace: true,
template:
‘<rocket-launch...
Directive Test
it(‘Check launchpad was installed', function() {
var element = $compile(“<rocket-launch-pad></
rocket-launc...
Filter Test
.filter('i18n', function() {
return function (str) {
return translations.hasOwnProperty(str)
&& translations[st...
Tools
Karma
Protractor
Test Runner
Karma
Run tests against real browsers
Karma
Run tests against real browsers
Unit tests
Config file
> karma init
Config file
> karma init
- frameworks: [‘jasmine’]
Config file
> karma init
- frameworks: [‘jasmine’]
- autoWatch: true
Config file
> karma init
- frameworks: [‘jasmine’]
- files: [
‘../tests/controllerSpec.js’
],
- autoWatch: true
Config file
> karma init
- frameworks: [‘jasmine’]
- files: [
‘../tests/controllerSpec.js’
],
- autoWatch: true
- browsers: [...
Using Karma
> karma start config.js
Using Karma
> karma start config.js
• From the product
owner point of view
• They are
(computationally)
expensive and slow
Acceptance tests
• They can be very
slow
• Hard to write
• Hard to keep
updated
Acceptance tests
Protractor
E2E Angular Testing
Angular wrapper for WebDriver
Anatomy of a E2E test
describe(‘…’, function() {
it(‘…’, function() {
browser.get(‘…’);
element(by.model(‘…’)).sendKeys(.....
Global Variables
describe(‘…’, function() {
it(‘…’, function() {
browser.get(‘…’);
element(by.model(‘…’)).sendKeys(..);
!
...
Global Variables
describe(‘…’, function() {
it(‘…’, function() {
browser.get(‘…’);
element(by.model(‘…’)).sendKeys(..);
!
...
Page Objects
Protractor provides
Page Objects
Protractor provides
Debugging with superpowers
Page Objects
Protractor provides
Debugging with superpowers
Angular-specific functions
Get your hands dirty!
https://github.com/jnardiello/angularjsday-testing-angular
Tools in action - http://vimeo.com/868167...
Jacopo Nardiello
Twitter: @jnardiello
Say hi!
Jacopo Nardiello
Twitter: @jnardiello
Questions?
Testing AngularJS
Testing AngularJS
Upcoming SlideShare
Loading in …5
×

Testing AngularJS

1,089 views

Published on

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

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,089
On SlideShare
0
From Embeds
0
Number of Embeds
39
Actions
Shares
0
Downloads
43
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Testing AngularJS

  1. 1. Testing! AngularJS
  2. 2. Jacopo Nardiello Padawan Programmer Presentation code on Github: github.com/jnardiello/angularjsday-testing-angular
  3. 3. Why?
  4. 4. Fail in Production
  5. 5. Fail in dev
  6. 6. Thanks to testing we…
  7. 7. fail fast
  8. 8. No Debugging
  9. 9. Machines handles bug hunting
  10. 10. Tests are a tool to handle complexity
  11. 11. Angular is no exception
  12. 12. Rock solid code Benefits
  13. 13. Fast Dev Cycle Benefits Rock solid code
  14. 14. Relaxed Team Benefits Fast Dev Cycle Rock solid code
  15. 15. Relaxed Team Benefits Fast Dev Cycle Rock solid code Relaxed PM
  16. 16. Testing Javascript
  17. 17. Testing Javascript describe(“…”, function() { it(“should do something", function() { expect(true).toBe(true); }); });
  18. 18. Testing Javascript describe(“…”, function() { it(“should do something", function() { expect(true).toBe(true); }); });
  19. 19. Types of tests
  20. 20. Unit tests • Small portions of code • Code is isolated • Quick and easy
  21. 21. Integration tests Interaction between elements
  22. 22. • From the product owner point of view • They are (computationally) expensive and slow Acceptance tests
  23. 23. Angular is special
  24. 24. 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/
  25. 25. Misko Hevery +
  26. 26. “Angular is written with testability in mind” - Angular Doc
  27. 27. Why is Angular easily testable?
  28. 28. Dependency Injection
  29. 29. DI As a Pattern Framework
  30. 30. DI as Pattern function Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }
  31. 31. DI as Pattern function Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }
  32. 32. DI as Pattern function Car(wheel, engine, door) { this.move = function() { engine.on(); wheel.rotate(); door.open(); } }
  33. 33. The problem function 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(); }
  34. 34. The problem function 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(); }
  35. 35. The problem function 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(); }
  36. 36. The problem function 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(); }
  37. 37. DI as framework function main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }
  38. 38. DI as framework function 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() { … } }
  39. 39. DI as framework function 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() { … } }
  40. 40. Angular testability is super-heroic! but…
  41. 41. “you still have to do the right thing.” - Angular Doc
  42. 42. Testability 1. Don’t use new 2. Don’t use globals
  43. 43. The Angular Way
  44. 44. Solid structured code
  45. 45. Testing components
  46. 46. Controller function RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }
  47. 47. Controller function RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }
  48. 48. var $scope = {}; var rc = $controller( 'RocketCtrl', { $scope: $scope } ); ! $scope.currentFuel = 80; $scope.finalCheck(); expect($scope.check).toEqual('ko'); Controller Test
  49. 49. Directive app.directive('rocketLaunchPad', function () { return { restrict: 'AE', replace: true, template: ‘<rocket-launch-pad> Rocket here <rocket-launch-pad>’ }; });
  50. 50. Directive Test it(‘Check launchpad was installed', function() { var element = $compile(“<rocket-launch-pad></ rocket-launch-pad>”)($rootScope); ! expect(element.html()).toContain("Rocket here"); });
  51. 51. 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');
  52. 52. Tools
  53. 53. Karma Protractor
  54. 54. Test Runner
  55. 55. Karma Run tests against real browsers
  56. 56. Karma Run tests against real browsers Unit tests
  57. 57. Config file > karma init
  58. 58. Config file > karma init - frameworks: [‘jasmine’]
  59. 59. Config file > karma init - frameworks: [‘jasmine’] - autoWatch: true
  60. 60. Config file > karma init - frameworks: [‘jasmine’] - files: [ ‘../tests/controllerSpec.js’ ], - autoWatch: true
  61. 61. Config file > karma init - frameworks: [‘jasmine’] - files: [ ‘../tests/controllerSpec.js’ ], - autoWatch: true - browsers: ['Chrome']
  62. 62. Using Karma > karma start config.js
  63. 63. Using Karma > karma start config.js
  64. 64. • From the product owner point of view • They are (computationally) expensive and slow Acceptance tests
  65. 65. • They can be very slow • Hard to write • Hard to keep updated Acceptance tests
  66. 66. Protractor E2E Angular Testing Angular wrapper for WebDriver
  67. 67. Anatomy of a E2E test describe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });
  68. 68. Global Variables describe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });
  69. 69. Global Variables describe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); }); Super-Happy Panda!
  70. 70. Page Objects Protractor provides
  71. 71. Page Objects Protractor provides Debugging with superpowers
  72. 72. Page Objects Protractor provides Debugging with superpowers Angular-specific functions
  73. 73. Get your hands dirty! https://github.com/jnardiello/angularjsday-testing-angular Tools in action - http://vimeo.com/86816782
  74. 74. Jacopo Nardiello Twitter: @jnardiello Say hi!
  75. 75. Jacopo Nardiello Twitter: @jnardiello Questions?

×