Presentation is loading. Please wait.

Presentation is loading. Please wait.

Techniques and Practices for Testing Angular

Similar presentations


Presentation on theme: "Techniques and Practices for Testing Angular"— Presentation transcript:

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

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

3 Who has tested angular 1+?

4 Testing != debugging XP SUnit JSUnit TDD BDD Selenium Jasmine Angular 1.0 Karma Protractor Angular 2.0

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

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

7 Angular is designed from the ground up to be tested.

8 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.

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

10

11

12

13

14 Angular CLI

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

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

17 PH: what we will test as an app image

18 PH: what we will test as an app image

19 PH: what we will test as an app image

20 Jasmine Tests 1 + 1 Component Title Code Demo

21 describe(`Component: JokeComponent`, () => {
}); describe(`Component: JokeComponent`, () => { }); it(`should add `, () => { expect(1 + 1).toEqual(2); }); it(`should add `, () => { 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); };

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

23 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.

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

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

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

27 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

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

29 Faking Dependencies Fake Service Jasmine Spy Code Demo

30 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’); });

31 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’); });

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

33 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 ….

34 9/12/ :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.

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

36 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

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

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

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

40 TestBed API Configure TestBed Test DOM content Code Demo

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

42 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');

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

44 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.

45 Async adds complexity to writing JavaScript unit tests.

46 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

47 Zones define an execution context for asynchronous operations

48 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

49 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

50 async and fakeAsync Joke button fakeAsync Joke button async Code Demo

51 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'); });

52 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');

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

54 Async adds complexity to writing JavaScript unit tests.

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

56 9/12/ :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.

57 e2e tests ensure that integrated components function as expected.

58 e2e Tests Joke title Joke button Code Demo

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

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

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

62

63

64

65

66

67 www.courses.firebootcamp.com ignite-testing

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

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

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


Download ppt "Techniques and Practices for Testing Angular"

Similar presentations


Ads by Google