test-driven development with angular 2 and jasmine

37
Test-Driven Development with Angular 2 and Jasmine SoCal Code Camp 12+13 Nov 2016

Upload: troy-miles

Post on 08-Apr-2017

264 views

Category:

Software


7 download

TRANSCRIPT

Page 1: Test-Driven Development with Angular 2 and Jasmine

Test-Driven Development with Angular 2 and JasmineSoCal Code Camp 12+13 Nov 2016

Page 2: Test-Driven Development with Angular 2 and Jasmine

Troy Miles• Troy Miles aka the RocknCoder

• Over 37 years of programming experience

• Speaker and author

• Author of jQuery Essentials

• bit.ly/rc-jquerybook

[email protected]

• @therockncoder

Page 3: Test-Driven Development with Angular 2 and Jasmine

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

Page 4: Test-Driven Development with Angular 2 and Jasmine

Affordable JavaScript Weekend Workshops

• Ionic 2 – Beautiful Android & iOS Apps in JavaScript

• MEAN Stack - Create Full Stack Web Apps in JavaScript

• Intro to React - Deep dive into the Super Popular Library for Build UIs

• Angular 2 - A Deep Dive into the Latest Version of the Popular Front End Framework by Google

Page 5: Test-Driven Development with Angular 2 and Jasmine

https://therockncoder.com

Page 6: Test-Driven Development with Angular 2 and Jasmine

Code + Slides Online

• https://github.com/Rockncoder/quizzer-start

• http://www.slideshare.net/rockncoder/testdriven-development-with-angular-2-and-jasmine

Page 7: Test-Driven Development with Angular 2 and Jasmine

Our Agenda• What is Test-Driven Development?

• Prepare Your Machine

• Know Your Tools

• Create Your Own Matchers

• Dependency Injection is Not Magic

• Red, Green, Refactor

• Summary

Page 8: Test-Driven Development with Angular 2 and Jasmine

What is Test-Driven Development?

• Write a test

• Run test, fail

• Write enough code to pass the test

• Repeat

Page 9: Test-Driven Development with Angular 2 and Jasmine

Prepare Your Machine

• Install Git (git —version)

• Install Node.js (node -v)

• Upgrade npm - npm i -g npm (npm -v)

• Install Angular CLI - npm i -g angular-cli (ng -v)

Page 10: Test-Driven Development with Angular 2 and Jasmine

Know Your ToolsTool Command

Web Server ng serve

Unit Test ng test

End to End Test ng e2e

Dev Build ng build —dev

Production Build ng build —prod

Page 11: Test-Driven Development with Angular 2 and Jasmine

Create New ComponentsComponent Command

Class ng g class my-new-class

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

Page 12: Test-Driven Development with Angular 2 and Jasmine

Setup• Multi-window setup

• IDE

• Web browser

• two terminal/command windows

• (terminals at app root)

Page 13: Test-Driven Development with Angular 2 and Jasmine

Jasmine

• Latest version 2.5.2

• The default unit test for Angular

• Behavior-driven JavaScript

Page 14: Test-Driven Development with Angular 2 and Jasmine

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

Page 15: Test-Driven Development with Angular 2 and Jasmine

describe()describe('App: Quizzer', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ AppComponent ], imports: [ RouterTestingModule ] }); }); });

Page 16: Test-Driven Development with Angular 2 and Jasmine

it() - Test Spec

• it() is a global Jasmine function

• Takes two parameters

• name of the spec (string)

• implementation of the spec (function)

Page 17: Test-Driven Development with Angular 2 and Jasmine

it()

it(`should have as title 'Quizzer'`, async(() => { let fixture = TestBed.createComponent(AppComponent); let app = fixture.debugElement.componentInstance; expect(app.title).toEqual('Quizzer'); }));

Page 18: Test-Driven Development with Angular 2 and Jasmine

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

Page 19: Test-Driven Development with Angular 2 and Jasmine

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

Page 20: Test-Driven Development with Angular 2 and Jasmine

expect()

let app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); expect(app).not.toBeUndefined(); expect(app.title).toEqual('Quizzer');

Page 21: Test-Driven Development with Angular 2 and Jasmine

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'

Page 22: Test-Driven Development with Angular 2 and Jasmine

Matchers (part 2)Matcher Comparison

toBeNull() compares against null

toBeTruthy() truthy boolean casting

toBeFalsy() falsy boolean casting

toContain() finds an item in array

Page 23: Test-Driven Development with Angular 2 and Jasmine

Matchers (part 3)Matcher Comparison

toBeLessThan() mathematical comparison

toBeGreaterThan() mathematical comparison

toBeCloseTo() precision math comparison

toThrow() should throw an exception

Page 24: Test-Driven Development with Angular 2 and Jasmine

Angular’s MatchersMatcher Comparison

toBePromise() the value is a promise

toBeAnInstanceOf() an instance of an object

toHaveText() the element has the given text

toHaveCssClass() the element has the given CSS class

toHaveCssStyle() the element has the given CSS styles

toImplement() the class implements the given interface

Page 25: Test-Driven Development with Angular 2 and Jasmine

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; } }; } };

Page 26: Test-Driven Development with Angular 2 and Jasmine

beforeEach()

• Setup function

• Called before each spec is executed

• A good place to add customer matchers

Page 27: Test-Driven Development with Angular 2 and Jasmine

beforeEach()

beforeEach(function() { jasmine.addMatchers(customMatchers); });

Page 28: Test-Driven Development with Angular 2 and Jasmine

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

Page 29: Test-Driven Development with Angular 2 and Jasmine

afterEach()

• Teardown function

• Called after each spec is executed

Page 30: Test-Driven Development with Angular 2 and Jasmine

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

Page 31: Test-Driven Development with Angular 2 and Jasmine

Dependency Injection is not Magic

• Dependency Injection (DI) is a core component of Angular

• It only means objects are instantiated somewhere else

• And supplied to your code when it needs them

• Angular calls DI a provider

Page 32: Test-Driven Development with Angular 2 and Jasmine

providers@NgModule({ imports: TroyModules, declarations: [ AppComponent, AboutComponent, LoginComponent, QuizComponent, PlayerComponent, MixedPipe, BackcolorDirective, ModelComponent ], providers: [QuizService], bootstrap: [AppComponent] }) export class AppModule { }

Page 33: Test-Driven Development with Angular 2 and Jasmine

Module InitializationKey Value

imports Modules (array)

declarations Components (array)

providers Services and other DI objects (array)

bootstrap the launch component

Page 34: Test-Driven Development with Angular 2 and Jasmine

Unit Test & DI

• When unit testing your app you ask Angular for just enough parts to make it work

• Angular use DI to do this

Page 35: Test-Driven Development with Angular 2 and Jasmine

Unit Tests & Providersdescribe('Router', () => { beforeEach(() => { // acts like NgModule TestBed.configureTestingModule({ imports: [ RouterTestingModule, AppRoutingModule ], declarations: [ AppComponent, AboutComponent, LoginComponent ], providers: [ {provide: APP_BASE_HREF, useValue: '/'} ] }); });

Page 36: Test-Driven Development with Angular 2 and Jasmine

Red, Green, Refactor

Page 37: Test-Driven Development with Angular 2 and Jasmine

Summary

• Unit Test help to make your code more solid

• Writing the tests first, means that you don’t have to write them later

• Writing tests first can lead to less code