Techniques and Practices for Testing Angular

Slides:



Advertisements
Similar presentations
Microsoft Virtual Academy Stacey Mulcahy | Technical Evangelist Christopher Harrison | Content Developer.
Advertisements

Andrew Hennessy Automating Server Application migrations to the Cloud – Goodbye Server INF21 3.
Kevin Francis Developing on Windows Devices ARC33 2.
Chris Hewitt Adding magic to your business with Perceptual Intelligence ARC323 B.
Matt McSpirit Software-defined Networking in Windows Server 2016 INF32 4.
Michael Niehaus Using the Windows Store for Business: New Capabilities for Managing Apps in the Enterprise WIN335.
Jessica Payne Microsoft Global Incident Response and Recovery
James Bannan Freddy vs JSON: Azure Resource Manager CLD44 3.
Nick Application Development for the Universal Windows Platform MOB225.
Alec Tucker An Introduction to Cross Platform Native App Development using Xamarin to Develop, Test and Monitor MOB227.
Orin Thomas 30 Bad Habits of Server Administrators INF32 3.
Orin EDP, EFS, BitLocker, RMS, DAC, and IPsec: Protect your files at rest and in transit. WIN341 A.
Building a Microservices solution using Docker,
Kevin Francis Big Building Blocks – a tour of Dynamics ARC323 A.
Marc Soester Project Visualization, Resource Management and Collaboration using Office 365 Project Online PRD32 6.
James Bannan The Cloud That Chuck Norris Built: Resilient Architecture in Azure ARC44 3.
UNIT TESTING IN ANGULARJS Dhananjay
A deep dive into Azure AD B2C
3 Ways to Integrate Business Systems to Partners
Office 365 Development July 2014.
Azure ARM Templates CLD321 Aaron Saikovski
Serverless in Office 365 Build services with Azure Functions
Microsoft Ignite /5/ :32 AM
Making of the Ignite Bot
What's New in System Center Configuration Manager, Current Branch and Intune INF324a Steven Hosking.
30 Tips and Tricks for Managing and Running Ubuntu/Bash/Windows Subsystem for Linux WIN321B Orin Thomas.
Introduction to ASP.NET Core
The Zen of Package Management
Conversation As a Platform - Part 1
Now, let’s implement/trial Windows Defender Advanced Threat Protection
Microsoft Virtual Academy
What's new in the world of SharePoint development and deployment
Building Business Application with Office 365 and Other Line Business Systems
Microsoft Ignite /19/2018 2:35 AM
Need for Speed: Why Applications With No Database and No Services are Fast ARC334 Nick Randolph – Built to Roam.
Mastering Connectivity to O365
Building a Continuous Delivery Pipeline for ASP.NET Core Apps
Jenkins and Azure OPEN322 Michael Friedrich.
Microsoft Build /22/2018 3:05 AM © 2016 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY,
Darren Neimke and Jonathan Ruckert
Displaying Form Validation Info
Microsoft Build /12/2018 2:41 PM © 2016 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY,
Build vNext in VSO and TFS 2015
What’s new in Visual Studio in 2015?
Microsoft Edge for Developers
Microsoft Ignite /19/ :53 AM Applying DevOps principals in applications integrated with Office 365 Evergreen Ben Parker ARC231B © 2015 Microsoft.
Rob Farley, LobsterPot Solutions
Application Insights:
Building responsive apps and sites with HTML5 web workers
Modern cloud PaaS for mobile apps, web sites, API's and business logic apps
Bare Metal Development for the Universal Windows Platform
Improving JavaScript Frameworks, Edge, & UWP Web Apps
Microsoft Ignite /2/2019 1:15 AM Power Up Your Cross Platform Mobile Code with Platform Specific Features using Xamarin Alec Tucker MOB331 © 2015.
Microsoft Build /2/2019 4:12 PM © 2016 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY,
Microsoft Connect /17/2019 9:55 PM
The Power of a Great API Damian Brady
Office 365 Development.
Microsoft Connect /24/ :10 PM
What is Visual Studio Code?
Deep Dive into Azure API Apps and Logic Apps
Microsoft Virtual Academy
Jonathan Ruckert & Darren Neimke
UI test automation of MVC apps with Microsoft Edge WebDriver
Microsoft Ignite NZ October 2016 SKYCITY, Auckland.
Reveal Highlight Introduction to using light in your app
Empower your users with Azure Active Directory Premium
Securing ASP.NET in an Azure Environment
Microsoft Virtual Academy
Presentation transcript:

Techniques and Practices for Testing Angular OPEN331 Duncan Hunter & Adam Stephensen

Adam Stephensen Duncan Hunter Architect / GM at SSW @AdamStephensen Duncan Hunter Architect at SSW @DuncHunter

Who has tested angular 1+?

1979 Testing != debugging 1996 XP 1998 SUnit 2001 JSUnit 2003 TDD 2006 BDD 2006 Selenium 2010 Jasmine 2010 Angular 1.0 2011 Karma 2013 Protractor 2016 Angular 2.0

Agenda Tools Jasmine Faking Dependencies TestBed API   TestBed API async and fakeAsync e2e tests

9/12/2018 10:17 PM Tools © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Angular is designed from the ground up to be tested.

Unit tests e2e test Test specific methods or units of code. Tests an app running in a real browser, interacting with it as a user would.

describe(`Component: JokeComponent`, () => { }); it(`should add 1 + 1 `, () => { expect(1 + 1).toEqual(2); }); it(`should add 1 + 1 `, () => { expect(1 + 1).toEqual(2); });

Angular CLI

Summary - Tools Use Angular CLI Use Karma, Protractor and Jasmine Check out WallabyJS

9/12/2018 10:17 PM Jasmine © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

PH: what we will test as an app image

PH: what we will test as an app image

PH: what we will test as an app image

Jasmine Tests 1 + 1 Component Title Code Demo

describe(`Component: JokeComponent`, () => { }); describe(`Component: JokeComponent`, () => { }); it(`should add 1 + 1 `, () => { expect(1 + 1).toEqual(2); }); it(`should add 1 + 1 `, () => { expect(1 + 1).toEqual(2); }); it(`should have a title of "Chuck Norris Quotes"`, () => { const component = new JokeComponent(null); expect(component.title).toEqual('Chuck Norris Jokes'); }); beforeEach(() => { let component = new JokeComponent(null); };

Summary - Jasmine Default for Angular Community More than syntax it’s a testing framework

Faking Dependencies 9/12/2018 10:17 PM © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Faking and setup of dependencies is still one of the hardest part of testing

let component = new JokeComponent(fakeJokeService); let fakeJokeService = { getJoke: () => Observable.of(‘FAKE_JOKE’); }; let component = new JokeComponent(fakeJokeService);

let component = new JokeComponent(fakeJokeService); let fakeJokeService = jasmine.createSpyObj('jokeService', ['getJoke']) fakeJokeService.getJoke.and.returnValue(Observable.of(‘FAKE JOKE’); let component = new JokeComponent(fakeJokeService);

Intercept any function call Override the behaviour of the function spyOn(jokeService, ‘getJoke’) .and.returnValue(Observable.of((`FAKE JOKE’)); Spies Let You Intercept any function call Override the behaviour of the function

expect(jokeService.getJoke).toHaveBeenCalled(); expect(jokeService.getJoke).toHaveBeenCalledTimes(2); expect(jokeService.getJokeByType).toHaveBeenCalledWith(‘DadJokes’);

Faking Dependencies Fake Service Jasmine Spy Code Demo

describe(`Component: JokeComponent`, () => { }); let component: JokeComponent; let fakeJokeService: any; beforeEach(() => { fakeJokeService = { getJoke: () => Observable.of(‘FAKE JOKE’) }; component = new JokeComponent(fakeJokeService); it(`should set joke when component is initialised `, () => { component.ngOnInit(); expect(component.joke).toEqual(‘FAKE_JOKE’); });

describe(`Component: JokeComponent`, () => { }); let component: JokeComponent; let fakeJokeService: any; beforeEach(() => { fakeJokeService = jasmine.createSpyObj('jokeService',['getJoke']); fakeJokeService.getJoke.and.returnValue(Observable.of(‘FAKE JOKE’); component = new JokeComponent(fakeJokeService); }; it(`should set joke when component is initialised `, () => { component.ngOnInit(); expect(component.joke).toEqual(‘FAKE_JOKE’); });

Spying Faking Spy functionality and assertions Cleaner code Isolated Duplicated code Forgot to update

Summary - Faking Dependencies Tools you need both fakes and spies Faking and setup of dependencies is still the hardest part of testing The Testbed will you help you ….

9/12/2018 10:17 PM TestBed API © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Types of Unit Tests Isolated Shallow Integrated HTML template No HTML template HTML template No child components Test the entire app

An NgModule for testing Just the dependencies you need to test Testbed.configureTestingModule({ imports: [HttpModule], declarations: [JokeComponent], providers: [JokeService] }); TestBed API An NgModule for testing Just the dependencies you need to test

Component Fixture fixture = Testbed.createComponent(JokeComponent); component = fixture.componentInstance; debugElement = fixture.debugElement; fixture.detectChanges(); Component Fixture

CSS selector for querying the HTML Template .nativeElement; jokeText = debugElement.query(By.css(`p`)) Query the DOM CSS selector for querying the HTML Template

TestBed API helps you Create a testing module Query HTML templates Detect Changes More…..

TestBed API Configure TestBed Test DOM content Code Demo

describe(`Component: JokeComponent`, () => { }); describe(`Component: JokeComponent`, () => { }); let component: JokeComponent; let jokeService: JokeService; let fixture: ComponentFixture<JokeComponent>; let de: DebugElement; let component: JokeComponent; let jokeService: JokeService; let fixture: ComponentFixture<JokeComponent>; let de: DebugElement; beforeEach(() => { Testbed.configureTestingModule({ imports: [HttpModule], declarations: [JokeComponent], providers: [JokeService], }); fixture = Testbed.createComponent(JokeComponent); component = fixture.componentInstance; jokeService = Testbed.get(JokeService); de = Fixture.debugElement; fixture = Testbed.createComponent(JokeComponent); component = fixture.componentInstance; jokeService = Testbed.get(JokeService); de = Fixture.debugElement;

it(`should get display the joke content`, () => { }); spyOn(jokeService, ‘getJoke’) .and.returnValues( .Observable.of(‘FAKE_JOKE’); fixture.detectChanges(); let joke = de.query(By.css(’p’)).nativeElement; expect(joke.textContent).toEqual('FAKE JOKE');

Summary - TestBed API Big API takes time to learn Makes a NgModule and runs everything in a zone

async and fakeAsync 9/12/2018 10:17 PM © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Async adds complexity to writing JavaScript unit tests.

Jasmine ‘done’ Callbacks it(`should show quote after getJoke'`, done => { spyOn(jokeService, ’getJoke’) .returnValue('FAKE JOKE 2').then(() => { fixture.detectChanges(); expect(el.textContent).toEqual('FAKE JOKE 2'); done(); }); Jasmine ‘done’ Callbacks Requires chaining promises, handling errors, and calling done Not recommended, but still required for some edge cases

Zones define an execution context for asynchronous operations

async(() => { button.click(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(el.textContent).toEqual('FAKE JOKE 2'); }); async Tests Fixture.whenStable( ) resolves when all pending asynchronous activities within the test complete

fakeAsync(() => { button.click(); tick(3000); fixture.detectChanges(); expect(el.textContent).toEqual('FAKE JOKE'); }); } fakeAsync Tests tick( ) simulates the passage of time until all pending async requests complete, or you can specify a specific amount of time

async and fakeAsync Joke button fakeAsync Joke button async Code Demo

it(`should get next quote on click - with async`, async(() => { })); spyOn(jokeService, ‘getJoke’) .and.returnValues( .Observable.of(‘FAKE_JOKE’), .Observable.of(‘FAKE_JOKE’)); fixture.detectChanges(); let el = de.query(By.css(’p’)).nativeElement; expect(el.textContent).toEqual('FAKE JOKE'); let button = fixuture.debugElement .query(By.css(’button’)).nativeElement; button.click(); fixture.whenStable().then(() => { fixture.detectChanges();; expect(el.textContent).toEqual('FAKE JOKE 2'); });

it(`should get next quote on click`, fakeAsync(() => { })); spyOn(jokeService, ‘getJoke’) .and.returnValues( .Observable.of(‘FAKE_JOKE’), .Observable.of(‘FAKE_JOKE’).timeout(2000)); fixture.detectChanges(); let el = de.query(By.css(’p’)).nativeElement; expect(el.textContent).toEqual('FAKE JOKE'); let button = fixture.debugElement .query(By.css(’button’)).nativeElement; button.click(); tick(3000); fixture.detectChanges(); expect(el.textContent).toEqual('FAKE JOKE 2');

async fakeAsync Simplifies coding of asynchronous tests Tests appear to be synchronous You cannot XHR calls

Async adds complexity to writing JavaScript unit tests.

Summary - async and fakeAsync Async code is edgy to get right New helpers simplify async testing

9/12/2018 10:17 PM e2e tests © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

e2e tests ensure that integrated components function as expected.

e2e Tests Joke title Joke button Code Demo

import { browser, by, element } from ‘protractor’ describe(`Page: Joke Page`, () => { }); describe(`Page: Joke Page`, () => { }); it(`should have a title of "Chuck Norris Jokes"`, () => { browser.get(‘/’); let title = element(by.css(‘h1’).getText(); expect(title).toEqual('Chuck Norris Jokes'); }); it(`should have a title of "Chuck Norris Jokes"`, () => { browser.get(‘/’); let title = element(by.css(‘h1’).getText(); expect(title).toEqual('Chuck Norris Jokes'); }); it(`should have a new joke on button click`, async() => { browser.get(‘/’); let firstJoke = element(by.css(‘p’).getText(); element(by.css(‘button’).click(); let secondJoke = await element(by.css(‘p’).getText(); expect(title).not.toEqual(secondJoke); }); it(`should have a new joke on button click`, async() => { browser.get(‘/’); let firstJoke = element(by.css(‘p’).getText(); element(by.css(‘button’).click(); let secondJoke = await element(by.css(‘p’).getText(); expect(title).not.toEqual(secondJoke); });

Summary - e2e tests Not a unit test it runs in a browser Test user stories versus functions Helps save the manual testers!

Testing is something that the whole team need to practice …. and practice regularly.

www.courses.firebootcamp.com ignite-testing

Summary Tools Jasmine Faking Dependencies TestBed API   TestBed API async and fakeAsync e2e tests

Continue your Ignite learning path 9/12/2018 10:17 PM Continue your Ignite learning path Visit Channel 9 to access a wide range of Microsoft training and event recordings https://channel9.msdn.com/ Head to the TechNet Eval Centre to download trials of the latest Microsoft products http://Microsoft.com/en-us/evalcenter/ Visit Microsoft Virtual Academy for free online training visit https://www.microsoftvirtualacademy.com © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

9/12/2018 10:17 PM Thank you Chat with us in the Speaker Lounge Find us @dunchunter & @adamstephensen © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.