CoWork SouthBay 15 April 2017 Angular Application Testing
Code & Slides • https://github.com/Rockncoder/gh-stars • https://www.slideshare.net/rockncoder/angular- application-testing 2
3
4
Troy Miles • Troy Miles aka the RocknCoder • Over 38 years of programming experience • Speaker and author • bit.ly/rc-jquerybook • rockncoder@gmail.com • @therockncoder • Now a lynda.com Author!
 5
Build Mobile Apps! • Develop mobile apps with Ionic and AngularJS • Learn the Ionic CLI • Fetch data via ajax • Deploy your app to Android & iOS • bit.ly/ionicvideo 6
Follow Me • Talks • Webcasts • Free stuff • Tips, tricks, tools • and general code nerd stuff • @therockncoder
My Versions app command my version git git —version 2.11.0 node.js node -v 7.7.2 npm npm —v 4.1.2 angular (package.json) 4.0.1 angular cli ng -v 1.0.0
“Code without tests is bad code.” — Michael C. Feathers 10
Agenda • Why Test? • Tools • Unit Testing Basics • Testing Components • Testing Directives • Testing Services • Testing Pipes • Testing Routes • E2E Tests • Summary 11
Why Test? 12
Why Test? • Make sure the app meets its requirements • Ensure that the app doesn’t regress • Allow us to enhance app without breaking it • Fearlessly improve the design 13
The Testing Pyramid Mike Cohn / Martin Fowler 14
Unit vs. End-to-End Unit End-to-End fast yes no reliable yes no isolates failures yes no simulates user no yes
Component • A class with component metadata • Responsible for a piece of the screen referred to as view. • Template is a form HTML that tells angular how to render the component. • Metadata tells Angular how to process a class
Component 1 import { Component, OnInit } from '@angular/core'; 2 3 @Component({ 4 selector: 'app-about', 5 templateUrl: './about.component.html', 6 styleUrls: ['./about.component.css'] 7 }) 8 export class AboutComponent implements OnInit { 9 10 constructor() { } 11 12 ngOnInit() { 13 } 14 } 15
Template/View • Is a way to describe a view using HTML • Templates can be included with the component • Or as a URL link to an HTML file • Best practice is to use an HTML file
Directive • A class with directive metadata • Three kinds of directives • Attribute directives alter the look or behavior of an existing element • Structural directives alter the layout by adding, removing, and replacing elements in the DOM • A component is a directive with a view
Directive import {Directive, ElementRef, Renderer, Input, OnInit} from 'angular2/core';
 
 @Directive({
 selector: '[sizer]'
 })
 export class Sizer implements OnInit {
 @Input() sizer:string;
 element:ELementRef;
 renderer:Renderer;
 
 constructor(element:ElementRef, renderer:Renderer) {
 this.element = element;
 this.renderer = renderer;
 }
 
 ngOnInit() {
 this.renderer.setElementStyle(this.element.nativeElement,
 'fontSize', this.sizer + '%');
 }
 }
Service • “Substitutable objects that are wired together using dependency injection (DI)” • Used to share code across an app • Lazily instantiated • Angular has no “Service” defined type
Tools 22
The Angular CLI • Makes creating an Angular app that follows best practices easy • Built with TypeScript & Webpack • Based on the ember-cli project • Version 1.0.0 (yay!) • https://cli.angular.io/ 23
Angular CLI Tool Command New App ng new <app-name> Web Server ng serve Unit Test ng test End to End Test ng e2e Dev Build ng build dev Production Build ng build prod
Create New Components Component Command Class ng g class my-new-class Component ng g component my-new-component Directive ng g directive my-new-directive Enum ng g enum my-new-enum Interface ng g interface my-new-interface Module ng g module my-module Pipe ng g pipe my-new-pipe Service ng g service my-new-service
package.json Component Command core-js modular standard library for JavaScript rxjs reactive extensions for JavaScript zone.js change detection angular2-moment angular wrapper for moment.js hammerjs support touch gestures codelyzer set of tslint rules for static code analysis
Jasmine • Created by Pivotal Labs in 2010 • Current version 2.5.2 • JavaScript testing framework • The default unit test for Angular • Can test client and server code
describe() - Test Suite • describe() is a global Jasmine function • Takes to parameters • name of the test suite (string) • implementation of the suite (function) • Can be nested
describe() describe('App: Quizzer', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ AppComponent ], imports: [ RouterTestingModule ] }); }); });
it() - Test Spec • it() is a global Jasmine function • Takes two parameters • name of the spec (string) • implementation of the spec (function)
it() it(`should have as title 'Quizzer'`, async(() => { let fixture = TestBed.createComponent(AppComponent); let app = fixture.debugElement.componentInstance; expect(app.title).toEqual('Quizzer'); }));
expect() - Expectation • expect() is a global Jasmine function • Jasmine’s version of assert() • Takes one parameter • The actual - value generated by code under test • Is chained to a Matcher
Matcher • Takes the output of the expect() function • Takes one parameter • The expected value • Compares the expect and actual value using the logic of the matcher
expect() let app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); expect(app).not.toBeUndefined(); expect(app.title).toEqual('Quizzer');
Matchers (part 1) Matcher Comparison toBe() compares using === toEqual() works for literal variables and objects toMatch() for regular expressions toBeDefined() compares against 'undefined' toBeUndefined() also compares against ‘undefined'
Matchers (part 2) Matcher Comparison toBeNull() compares against null toBeTruthy() truthy boolean casting toBeFalsy() falsy boolean casting toContain() finds an item in array
Matchers (part 3) Matcher Comparison toBeLessThan() mathematical comparison toBeGreaterThan() mathematical comparison toBeCloseTo() precision math comparison toThrow() should throw an exception
Custom Matchers var customMatchers = { toBeGoofy: function (util, customEqualityTesters) { return { compare: function (actual, expected) { if (expected === undefined) { expected = ''; } var result = {}; result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters); result.message = result.pass ? "Expected " + actual + " not to be quite so goofy" : "Expected " + actual + " to be goofy, but it was not very goofy"; return result; } }; } };
beforeEach() • Setup function • Called before each spec is executed • A good place to add customer matchers
beforeEach() beforeEach(function() { jasmine.addMatchers(customMatchers); });
afterEach() • Teardown function • Called after each spec is executed
beforeAll & afterAll • beforeAll() called once before any spec is ran • afterAll() called once after all tests complete • Be careful not to leak state into test suite • Recommend not using unless you really need 42
this • beforeEach sets the this construct to any empty object • It is passed to each it() and afterEach() • The modified this doesn’t flow thru from one it() to the next
Disabling suites & specs • prepend an ‘x’ • to disable a suite change describe() to xdescribe() • to disable a spec change it() to xit() • They are not execute but appear in reporting
First 45
Karma • A JavaScript test runner created by Google • Testing framework agnostic • Works with Continuous Integration frameworks • Version 1.6.0 • Originally call “Testacular” • https://karma-runner.github.io/1.0/index.html 46
Karma • Installed via npm install karma —save-dev • Karma’s CLI npm install karma-cli • Invoke via ng test 47
Protractor • End-to-end test framework for Angular & AngularJS • Built on top WebDriverJS & Selenium • Tests like a user • Version 5.1.1 • http://www.protractortest.org/#/ 48
E2E specs • E2E tests are in the directory, “e2e” • Tests end with “e2e-spec.ts” • Tests look similar to Jasmine 49
Unit Testing Basics 50
Testing Components 51
Testing Services 52
Testing Pipes 53
Useful URLs • https://medium.com/google-developer-experts/ angular-2-testing-guide-a485b6cb1ef0 • https://medium.com/@ladyleet/setting-up-and-testing- angular-material-2-components-in-your-angular-2- angular-cli-application-6d1824ed9d81 • https://blog.thoughtram.io/angular/2016/11/28/testing- services-with-http-in-angular-2.html • https://blog.thoughtram.io/angular/2016/12/27/ angular-2-advance-testing-with-custom-matchers.html 54
Summary • Angular is built to test • The CLI creates the testing harness for both unit and e2e tests • Test your code 55

Angular Application Testing

  • 1.
    CoWork SouthBay 15April 2017 Angular Application Testing
  • 2.
    Code & Slides •https://github.com/Rockncoder/gh-stars • https://www.slideshare.net/rockncoder/angular- application-testing 2
  • 3.
  • 4.
  • 5.
    Troy Miles • TroyMiles aka the RocknCoder • Over 38 years of programming experience • Speaker and author • bit.ly/rc-jquerybook • rockncoder@gmail.com • @therockncoder • Now a lynda.com Author!
 5
  • 6.
    Build Mobile Apps! •Develop mobile apps with Ionic and AngularJS • Learn the Ionic CLI • Fetch data via ajax • Deploy your app to Android & iOS • bit.ly/ionicvideo 6
  • 8.
    Follow Me • Talks •Webcasts • Free stuff • Tips, tricks, tools • and general code nerd stuff • @therockncoder
  • 9.
    My Versions app commandmy version git git —version 2.11.0 node.js node -v 7.7.2 npm npm —v 4.1.2 angular (package.json) 4.0.1 angular cli ng -v 1.0.0
  • 10.
    “Code without testsis bad code.” — Michael C. Feathers 10
  • 11.
    Agenda • Why Test? •Tools • Unit Testing Basics • Testing Components • Testing Directives • Testing Services • Testing Pipes • Testing Routes • E2E Tests • Summary 11
  • 12.
  • 13.
    Why Test? • Makesure the app meets its requirements • Ensure that the app doesn’t regress • Allow us to enhance app without breaking it • Fearlessly improve the design 13
  • 14.
    The Testing Pyramid MikeCohn / Martin Fowler 14
  • 15.
    Unit vs. End-to-End UnitEnd-to-End fast yes no reliable yes no isolates failures yes no simulates user no yes
  • 16.
    Component • A classwith component metadata • Responsible for a piece of the screen referred to as view. • Template is a form HTML that tells angular how to render the component. • Metadata tells Angular how to process a class
  • 17.
    Component 1 import {Component, OnInit } from '@angular/core'; 2 3 @Component({ 4 selector: 'app-about', 5 templateUrl: './about.component.html', 6 styleUrls: ['./about.component.css'] 7 }) 8 export class AboutComponent implements OnInit { 9 10 constructor() { } 11 12 ngOnInit() { 13 } 14 } 15
  • 18.
    Template/View • Is away to describe a view using HTML • Templates can be included with the component • Or as a URL link to an HTML file • Best practice is to use an HTML file
  • 19.
    Directive • A classwith directive metadata • Three kinds of directives • Attribute directives alter the look or behavior of an existing element • Structural directives alter the layout by adding, removing, and replacing elements in the DOM • A component is a directive with a view
  • 20.
    Directive import {Directive, ElementRef,Renderer, Input, OnInit} from 'angular2/core';
 
 @Directive({
 selector: '[sizer]'
 })
 export class Sizer implements OnInit {
 @Input() sizer:string;
 element:ELementRef;
 renderer:Renderer;
 
 constructor(element:ElementRef, renderer:Renderer) {
 this.element = element;
 this.renderer = renderer;
 }
 
 ngOnInit() {
 this.renderer.setElementStyle(this.element.nativeElement,
 'fontSize', this.sizer + '%');
 }
 }
  • 21.
    Service • “Substitutable objectsthat are wired together using dependency injection (DI)” • Used to share code across an app • Lazily instantiated • Angular has no “Service” defined type
  • 22.
  • 23.
    The Angular CLI •Makes creating an Angular app that follows best practices easy • Built with TypeScript & Webpack • Based on the ember-cli project • Version 1.0.0 (yay!) • https://cli.angular.io/ 23
  • 24.
    Angular CLI Tool Command NewApp ng new <app-name> Web Server ng serve Unit Test ng test End to End Test ng e2e Dev Build ng build dev Production Build ng build prod
  • 25.
    Create New Components ComponentCommand Class ng g class my-new-class Component ng g component my-new-component Directive ng g directive my-new-directive Enum ng g enum my-new-enum Interface ng g interface my-new-interface Module ng g module my-module Pipe ng g pipe my-new-pipe Service ng g service my-new-service
  • 26.
    package.json Component Command core-js modularstandard library for JavaScript rxjs reactive extensions for JavaScript zone.js change detection angular2-moment angular wrapper for moment.js hammerjs support touch gestures codelyzer set of tslint rules for static code analysis
  • 27.
    Jasmine • Created byPivotal Labs in 2010 • Current version 2.5.2 • JavaScript testing framework • The default unit test for Angular • Can test client and server code
  • 28.
    describe() - TestSuite • describe() is a global Jasmine function • Takes to parameters • name of the test suite (string) • implementation of the suite (function) • Can be nested
  • 29.
    describe() describe('App: Quizzer', ()=> { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ AppComponent ], imports: [ RouterTestingModule ] }); }); });
  • 30.
    it() - TestSpec • it() is a global Jasmine function • Takes two parameters • name of the spec (string) • implementation of the spec (function)
  • 31.
    it() it(`should have astitle 'Quizzer'`, async(() => { let fixture = TestBed.createComponent(AppComponent); let app = fixture.debugElement.componentInstance; expect(app.title).toEqual('Quizzer'); }));
  • 32.
    expect() - Expectation •expect() is a global Jasmine function • Jasmine’s version of assert() • Takes one parameter • The actual - value generated by code under test • Is chained to a Matcher
  • 33.
    Matcher • Takes theoutput of the expect() function • Takes one parameter • The expected value • Compares the expect and actual value using the logic of the matcher
  • 34.
    expect() let app =fixture.debugElement.componentInstance; expect(app).toBeTruthy(); expect(app).not.toBeUndefined(); expect(app.title).toEqual('Quizzer');
  • 35.
    Matchers (part 1) MatcherComparison toBe() compares using === toEqual() works for literal variables and objects toMatch() for regular expressions toBeDefined() compares against 'undefined' toBeUndefined() also compares against ‘undefined'
  • 36.
    Matchers (part 2) MatcherComparison toBeNull() compares against null toBeTruthy() truthy boolean casting toBeFalsy() falsy boolean casting toContain() finds an item in array
  • 37.
    Matchers (part 3) MatcherComparison toBeLessThan() mathematical comparison toBeGreaterThan() mathematical comparison toBeCloseTo() precision math comparison toThrow() should throw an exception
  • 38.
    Custom Matchers var customMatchers= { toBeGoofy: function (util, customEqualityTesters) { return { compare: function (actual, expected) { if (expected === undefined) { expected = ''; } var result = {}; result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters); result.message = result.pass ? "Expected " + actual + " not to be quite so goofy" : "Expected " + actual + " to be goofy, but it was not very goofy"; return result; } }; } };
  • 39.
    beforeEach() • Setup function •Called before each spec is executed • A good place to add customer matchers
  • 40.
  • 41.
    afterEach() • Teardown function •Called after each spec is executed
  • 42.
    beforeAll & afterAll •beforeAll() called once before any spec is ran • afterAll() called once after all tests complete • Be careful not to leak state into test suite • Recommend not using unless you really need 42
  • 43.
    this • beforeEach setsthe this construct to any empty object • It is passed to each it() and afterEach() • The modified this doesn’t flow thru from one it() to the next
  • 44.
    Disabling suites &specs • prepend an ‘x’ • to disable a suite change describe() to xdescribe() • to disable a spec change it() to xit() • They are not execute but appear in reporting
  • 45.
  • 46.
    Karma • A JavaScripttest runner created by Google • Testing framework agnostic • Works with Continuous Integration frameworks • Version 1.6.0 • Originally call “Testacular” • https://karma-runner.github.io/1.0/index.html 46
  • 47.
    Karma • Installed vianpm install karma —save-dev • Karma’s CLI npm install karma-cli • Invoke via ng test 47
  • 48.
    Protractor • End-to-end testframework for Angular & AngularJS • Built on top WebDriverJS & Selenium • Tests like a user • Version 5.1.1 • http://www.protractortest.org/#/ 48
  • 49.
    E2E specs • E2Etests are in the directory, “e2e” • Tests end with “e2e-spec.ts” • Tests look similar to Jasmine 49
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
    Useful URLs • https://medium.com/google-developer-experts/ angular-2-testing-guide-a485b6cb1ef0 •https://medium.com/@ladyleet/setting-up-and-testing- angular-material-2-components-in-your-angular-2- angular-cli-application-6d1824ed9d81 • https://blog.thoughtram.io/angular/2016/11/28/testing- services-with-http-in-angular-2.html • https://blog.thoughtram.io/angular/2016/12/27/ angular-2-advance-testing-with-custom-matchers.html 54
  • 55.
    Summary • Angular isbuilt to test • The CLI creates the testing harness for both unit and e2e tests • Test your code 55