angular application testing
TRANSCRIPT
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
• @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 Versionsapp 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 PyramidMike Cohn / Martin Fowler
14
Unit vs. End-to-EndUnit 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
Component1 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
Directiveimport {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 CLITool 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 ComponentsComponent CommandClass ng g class my-new-classComponent ng g component my-new-componentDirective ng g directive my-new-directiveEnum ng g enum my-new-enumInterface ng g interface my-new-interfaceModule ng g module my-modulePipe ng g pipe my-new-pipeService ng g service my-new-service
package.jsonComponent 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 Matchersvar 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