JavascriptTuts

E2E Testing In Angular 2 From Zero To Hero (Final Part)

Dear future Masters of Angular 2 E2E Testing.
Dit is het. Aan het einde van deze les heeft u eindelijk alle tools in handen om functionele tests te maken voor uw Angular 2 applicaties. Geen excuses meer: Je hebt de kracht!

We zullen eerst vertrouwd raken met Locators dan zullen we zien hoe geweldig Page Objects kunnen zijn, gevolgd door hoe om te gaan met asynchroniteit en tenslotte het makkelijkste deel dat is het triggeren van Actions.

Als je de basis nog niet onder de knie hebt, ga er dan heen anders zul je een beetje verloren zijn.

Locators

Een zo niet het belangrijkste ding in E2E testen is het vinden van de elementen die je wilt testen in je view. Meestal zul je jezelf de vraag stellen “waarom kan ik dit **** element niet vinden?” gevolgd door een “oooohhhh”.

Je hebt vele manieren om dit te doen. De meeste hangen af van je toepassing. Om je elementen te vinden, zul je een reeks Locators gebruiken. Meestal kun je je elementen vinden door:

  • Class name.
  • Id.
  • Model.
  • Binding.

Voor de komende tests gebruiken we dit sjabloon.html:

<div class="parent2"> <div class="parent1"> <div class="nested-class" style="color:blue;"> I am a nested element </div> </div></div>

Laten we ons richten op nested-class en nested-id.

By Class:

We pakken hier ons element met element(by.css(selector)) dan testen we of het aanwezig is of niet.

By Id:

it("should find the nested id", () => { let elem = element(by.id("nested-id")); expect(elem.getText()).toBe("I am a nested element");});

We pakken hier ons element met element(by.id(elem-id)) dan testen we of het aanwezig is of niet.

De volgende locators zijn erg nuttig in AngularJS maar nog niet geïmplementeerd in Angular 2 dus hou ze voorlopig nog even aan de kant.

naar model:

it("should find the model", () => { let elem = element(by.model("modelToFind")); expect(elem.isPresent()).toBeTruthy();});

naar bindingen:

it("should find the binding", () => { let elem = element(by.model("bindingToFind")); expect(elem.isPresent()).toBeTruthy();});

Om je tests te debuggen, kun je gewoon “browser.pause()” in je test zetten, je kunt dan alle voorgaande instructies uitvoeren en stoppen waar je maar wilt.

Als de pauze eenmaal is bereikt, krijg je een scherm dat lijkt op dit:

Zoals je in deze afbeelding kunt zien, moet je om in de bestuurdersstoel te komen repl.

Nu, laten we zeggen dat je geen test hebt en je wilt gewoon wat spelen met Protractor. Je kunt gewoon in je terminal typen:

protractor --elementExplorer

Als je wat problemen hebt met je pad, kun je typen:

./node_modules/protractor/bin/elementexplorer.js

Niet nodig om repl te typen deze keer, gebruik gewoon het browser object en je bent klaar om te varen!

Page Objects

Wat als je tests hebt die hetzelfde scenario delen? Ga je dan overal je code kopiëren en plakken? Wat als dit scenario verandert? Nu moet je door alle bestanden gaan en de wijzigingen aanbrengen.

Dat is waar Pages Objects erg handig worden. Write Once, Share Everywhere!

Een Pagina-Object is een object dat de elementen en scenario’s van een pagina bevat.

Eerst een heel simpel Pagina-Object:

export class HomePage { nestedClass; constructor() { this.nestedClass = element(by.css(".nested-class")); }}

Dan gebruiken we het in onze test:

We importeren het Pagina-Object, maken een instantie en gebruiken dan zijn eigenschap.

Asynchrone Avonturen

Nu mijn vrienden, kun je toegang krijgen tot alle elementen op je pagina! Ik bedoel bijna :).

Er zullen een paar speciale gevallen.

Als je (on)gelukkig genoeg was om met jQuery te werken, moet je bekend zijn met document.ready().

Door de asynchrone aard van JavaScript, zullen er gevallen zijn waarin je probeert toegang te krijgen tot een element voordat het nog op de pagina is verschenen.

Om daarmee om te gaan, zul je een functie van Protractor moeten gebruiken om te wachten tot je element klaar is voordat je het opzoekt.

Hier volgt een voorbeeld van het weergeven van een knop na afloop van een time-out.

Eerst de class die de timeout bevat:

export class Home { isHidden = true; triggerTimeOut = ((){ setTimeout(() => this.isHidden = false, 2250) })}

Dan de template.html:

We hebben hier een knop die onze timeout activeert, zodra de timeout verstrijkt, wordt de tekst weergegeven.

Hier zijn de tests.

We vinden onze knop, klikken erop, proberen onze tekst te vinden MAAR we verwachten dat die niet aanwezig is.

En hier is de manier waarop we dit geval afhandelen ;).

We gebruiken “browser.wait” gecombineerd met “browser.isElementPresent” om onze Locator te testen. Na 5 seconden wordt de rest van de code uitgevoerd. Vergeet niet om hier een timer te zetten, anders worden je tests voor altijd geblokkeerd!

Dus als een van je elementen hier zou moeten zijn, maar je kunt het niet krijgen, dan zou je instinct je moeten vertellen dat je moet onthouden wat je hier zojuist hebt gelezen.

Acties

Nu je je kostbare element hebt, heb je 90% van het werk gedaan!

Als je het niet kunt vinden, dan werkt je applicatie niet zoals het hoort (daarom doen we tests) of je moet beter worden in testen en minder tijd besteden aan Pokemon GO jagen op dratini’s bij een rivier om 1 uur ’s nachts (we hebben het allemaal meegemaakt …).

Laten we verder gaan met de acties die je op een element kunt gebruiken. Hier zijn ze:

We gebruiken Protractor, dat vertrouwt op WebDriver. Als je meer fancy acties nodig hebt, kun je eens kijken wat hier beschikbaar is.

Laten we er eens een paar testen.

Voor de template.html:

<input type="text" />

We gaan een beetje spelen met de tekst invoer. Snelle quiz, wat doet deze test (lees de beschrijving niet)?

Oplossing: We krijgen onze input, typen “Some text” erin, testen dat we de waarde ingesteld hebben gekregen, wissen het en tenslotte testen dat de waarde leeg is.

Legitimistisch kunnen we ons afvragen wat de beste manier is om acties te triggeren? Deze link hier toont een van de zwakke punten van het gebruik van JavaScript in plaats van WebDriver.
Zeker, schrijven in JavaScript is veel compacter, maar het komt met een aantal risico’s!

Je kunt alles doen wat je wilt met een element. De beste manier om het te testen is om de matchers te gebruiken die beschikbaar zijn. Waarom? Omdat ze elegant zijn en dicht bij de menselijke taal staan, voorbeeld:

expect(apples.length !== 0).toBe(true);
expect(apples).not.toBeEmpty();

Conclusie

Dit was de laatste post van deze serie, op dit moment heb je 90% van de vaardigheden om je Angular 2 applicaties te testen. De overige 10% krijg je door ervaring. Onthoud, eerst je elementen ophalen met Locators, dan degene die misschien gerepliceerd worden in een Page Object zetten, als je je element niet kan vinden en je bent er zeker van dat het hier is, kan het zijn omdat het nog niet verschenen is en je de asynchroniteit moet behandelen. Tenslotte test je de **** van je elementen met Actions.

Plaats een reactie