JavascriptTuts

E2E-testning i Angular 2 fra nul til helt (sidste del)

Kære fremtidige mestre i Angular 2 E2E-testning.
Dette er det. Ved slutningen af denne lektion vil du endelig have alle værktøjer til at oprette funktionelle tests til dine Angular 2-applikationer. Ikke flere undskyldninger: Du har magten!

Vi vil først blive bekendt med Locators, derefter vil vi se, hvor fantastiske Page Objects kan være, efterfulgt af hvordan man håndterer asynkronitet og endelig den nemmeste del, som er at udløse Actions.

Hvis du ikke har styr på det grundlæggende, så gå derhen, ellers er du lidt fortabt.

Locators

En, hvis ikke den vigtigste ting i E2E-test er at finde de elementer, som du vil teste i din visning. Det meste af tiden vil du stille dig selv spørgsmålet “hvorfor kan jeg ikke finde dette **** element?” efterfulgt af et “oooohhhhhhh”.

Du har mange måder at gøre dette på. De fleste af dem afhænger af din applikation. For at finde dine elementer skal du bruge en række Locators. For det meste kan du finde dine elementer ved at:

  • Klassens navn.
  • Id.
  • Model.
  • Binding.

I de kommende tests vil vi bruge denne skabelon.html:

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

Lad os fokusere på nested-class og nested-id.

By Class:

Vi griber her vores element ved hjælp af element(by.css(selector)) og derefter tester vi, om det er til stede eller ej.

By Id:

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

Vi tager her vores element ved hjælp af element(by.id(elem-id)) og derefter tester vi, om det er til stede eller ej.

De følgende lokalisatorer er meget nyttige i AngularJS, men er endnu ikke implementeret i Angular 2, så hold dem bare ved siden af for nu.

By Model:

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

By Bindings:

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

For at debugge dine tests kan du bare tilføje “browser.pause()” i din test, så vil du kunne køre alle de tidligere instruktioner og stoppe hvor du vil.

Når den når din pause, vil du få en skærm, der ligner denne:

Som du kan se på dette billede, skal du for at komme ind i førersædet skrive repl.

Nu lad os sige, at du ikke har nogen test, og at du bare vil lege lidt med Protractor. Du kan bare skrive i din terminal:

protractor --elementExplorer

Hvis du har nogle problemer med din sti, kan du skrive:

./node_modules/protractor/bin/elementexplorer.js

Det er ikke nødvendigt at skrive repl denne gang, du skal bare bruge browserobjektet, og så er du klar til at sejle!

Sideobjekter

Hvad hvis du har tests, der deler det samme scenarie? Skal du kopiere og indsætte din kode overalt? Hvad hvis dette scenarie ændres? Nu skal du gå alle filer igennem og foretage ændringerne.

Det er her, at Pages Objects bliver meget nyttige. Skriv én gang, del overalt!

Et sideobjekt er et objekt, der indeholder de elementer og scenarier, der vedrører en side.

Først et meget simpelt Page Object:

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

Dernæst bruger vi det i vores test:

Vi importerer Page Object, opretter en instans og bruger derefter dens egenskab.

Asynkrone eventyr

Nu, mine venner, kan du få adgang til alle elementer på din side! Jeg mener næsten :).

Der vil være nogle specielle tilfælde.

Hvis du har været (u)heldig nok til at arbejde med jQuery, må du være bekendt med document.ready().

På grund af JavaScript’s asynkrone natur vil der være tilfælde, hvor du vil forsøge at få adgang til et element, før det endnu er dukket op på siden.

For at håndtere det skal du bruge en funktion i Protractor for at vente på, at dit element er klar, før du leder efter det.

Her er et eksempel, der viser en knap efter en timeout-udløb.

Først klassen, der indeholder timeout:

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

Dernæst template.html:

Vi har her en knap, der vil udløse vores timeout, når timeout udløber, vises teksten.

Her er testene.

Vi finder vores knap, klikker på den, prøver at finde vores tekst MEN vi forventer at den ikke er til stede.

Og her er måden vi håndterer dette tilfælde på ;).

Vi bruger “browser.wait” kombineret med “browser.isElementPresent” der tester vores Locator. Efter 5 sekunder udføres resten af koden. Glem ikke at sætte en timer her, ellers vil dine tests blive blokeret for evigt!

Så hvis et af dine elementer skal være her, men du ikke kan få det, bør din mavefornemmelse fortælle dig, at du skal huske, hvad du lige har læst her.

Actions

Nu har du dit dyrebare element, og du har gjort 90% af arbejdet!

Hvis du ikke kan finde det, er det enten, at din applikation ikke fungerer, som den skal (det er derfor, vi laver tests), eller også skal du blive bedre til at teste og bruge mindre tid på Pokemon GO på at jage dratinis nær en flod kl. 1 om natten (vi har alle været der …).

Lad os fortsætte med de handlinger, som du kan bruge på et element. Her er de:

Vi bruger Protractor, som er afhængig af WebDriver. Hvis du har brug for flere smarte handlinger, kan du kigge på, hvad der er tilgængeligt her.

Lad os teste nogle af dem.

For template.html:

<input type="text" />

Vi vil lege lidt med tekstindtastningen. Hurtig quiz, hvad gør denne test (du skal ikke læse beskrivelsen)?

Løsning: Vi får vores input, skriver “Some text” indeni, tester, at vi har fået indstillet værdien, rydder den og tester til sidst, at værdien er tom.

Legitimt kan vi spørge os selv, hvad er den bedste måde at udløse handlinger på? Dette link her viser en af fejlene ved at bruge JavaScript i stedet for WebDriver.
Sikkert at skrive i JavaScript er langt mere kompakt, men det kommer med nogle risici!

Du kan gøre alt, hvad du vil, med et element. Den bedste måde at teste det på er at bruge de matchers, der er tilgængelige. Hvorfor? Fordi de er elegante og tæt på det menneskelige sprog, eksempel:

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

Konklusion

Dette var det sidste indlæg i denne serie, lige nu har du 90 % af færdighederne til at teste dine Angular 2-applikationer. Du vil få de andre 10% ved hjælp af erfaring. Husk, først at få dine elementer ved hjælp af Locators, derefter sætte den, der kan blive replikeret i et Page Object, hvis du ikke kan finde dit element, og du er sikker på, at det er her, kan det være måske, fordi det ikke er dukket op endnu, og du er nødt til at håndtere asynkronitet. Til sidst tester du **** ud af dine elementer med Actions.

Skriv en kommentar