Download presentation
Presentation is loading. Please wait.
Published bySilvester Morgan Cox Modified over 6 years ago
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); });
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.
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.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.