Komme i gang med slutt-til-ende-testing i kantet ved hjelp av protractor

Hva du skal skape

Protractor er en populær end-to-end test ramme som lar deg teste ditt Angular-program på en ekte nettleser som simulerer nettleserens interaksjoner, akkurat som en ekte bruker vil samhandle med. End-to-end tester er utformet for å sikre at applikasjonen oppfører seg som forventet fra brukerens perspektiv. Videre er testene ikke bekymret for den faktiske kodeimplementeringen.

Protractor kjører på toppen av den populære Selenium WebDriver, som er en API for nettleserautomatisering og testing. I tillegg til funksjonene som tilbys av Selenium WebDriver, tilbyr Protractor locators og metoder for å fange UI-komponentene i Angular-applikasjonen. 

I denne opplæringen lærer du om:

  • konfigurere, konfigurere og kjøre Protractor 
  • skriver grunnleggende tester for Protractor
  • sideobjekter og hvorfor du bør bruke dem
  • retningslinjer som skal vurderes når du skriver tester
  • skriver E2E tester for en applikasjon fra start til slutt

Lyder det ikke spennende? Men først ting først.

Trenger jeg å bruke Protractor?

Hvis du har brukt Angular-CLI, vet du kanskje at det leveres som standard med to rammer for testing. De er:

  • enhetstester med jasmin og karma
  • End-to-end tester ved hjelp av Protractor

Den tilsynelatende forskjellen mellom de to er at den førstnevnte brukes til å teste logikken til komponentene og tjenestene, mens sistnevnte brukes til å sikre at høynivåfunksjonaliteten (som involverer brukergrensesnittelementene) i applikasjonen virker som forventet. 

Hvis du er ny til testing i Angular, anbefaler jeg at du leser testkomponentene i kantet ved hjelp av Jasmine-serien for å få en bedre ide om hvor du skal tegne linjen. 

I det førstnevnte tilfellet kan du utnytte kraften til Angular testing utilities og Jasmine til å skrive ikke bare enhetstester for komponenter og tjenester, men også grunnleggende UI-tester. Men hvis du trenger å teste frontend-funksjonaliteten til søknaden din fra start til slutt, er Protractor veien å gå. Protractors API kombinert med designmønstre som sideobjekter gjør det lettere å skrive tester som er mer lesbare. Her er et eksempel for å få ting å rulle.

 / * 1. Det burde ha en opprett Paste-knapp 2. Når du klikker på knappen, skal du opprette et modalvindu * / it ('skal ha en Create Paste-knapp og modalvindu', () => forvente (addPastePage.isCreateButtonPresent ) .toBeTruthy ("knappen skal eksistere"); forvente (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("Det modale vinduet bør ikke eksistere, ennå ikke!"); addPastePage.clickCreateButton (); expect (addPastePage.isCreatePasteModalPresent )). toBeTruthy ("Det modale vinduet skal vises nå"););

Konfigurering av protractor

Å sette opp Protractor er enkelt hvis du bruker Angular-CLI for å generere prosjektet. Katalogstrukturen opprettet av ng ny er som følgende.

. ├── e2e │ ├── app.e2e-spec.ts │ ├── app.po.ts │ └─ - tsconfig.e2e.json ├── karma.conf.js ├── package.json ├── pakke-lock.json ├── protractor.conf.js ├── README.md ├── src │ ├── app │ ├── eiendeler │ ├── miljøer │ ├── favicon.ico │ ├── indeks .html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └ ── typings.d.ts ├── tsconfig.json └── tslint.json 5 kataloger, 19 filer 

Standard prosjektmal som er opprettet av Protractor, avhenger av to filer for å kjøre testene: specfilene som ligger inne i e2e katalog og konfigurasjonsfilen (protractor.conf.js). La oss se hvordan konfigurerbare protractor.conf.js er:

/ * Sti: protractor.conf.ts * / // Protractor konfigurasjonsfil, se lenke for mer informasjon // https://github.com/angular/protractor/blob/master/lib/config.ts const SpecReporter = kreve ( 'jasmine-spec-reporter'); exports.config = allScriptsTimeout: 11000, spesifikasjoner: ['./e2e/**/*.e2e-spec.ts'], evner: 'browserName': 'chrome', directConnect: true, baseUrl: 'http : // localhost: 4200 / ', framework:' jasmin ', jasmineNodeOpts: showColors: true, defaultTimeoutInterval: 30000, print: function () , onPrepare () krever (' ts-node '). prosjekt: 'e2e / tsconfig.e2e.json'); jasmine.getEnv (). addReporter (ny SpecReporter (spec: displayStacktrace: true)); ; 

Hvis du har det bra med å kjøre testen på Chrome-nettleseren, kan du la dette være og hoppe over resten av denne delen.

Sette opp protractor med selenes frittstående server

De directConnect: true Lar Protractor koble direkte til nettleserdriverne. Men i øyeblikket du skriver denne opplæringen, er Chrome den eneste støttede nettleseren. Hvis du trenger flere nettleserstøtte eller kjører en annen nettleser enn Chrome, må du sette opp Seleni-frittstående server. Trinnene er som følger.

Installer Protractor globalt ved hjelp av npm:

npm installer-g grader

Dette installerer kommandolinjeværktøyet for webdriver-manager sammen med det for graden. Oppdater nå webdriver-administratoren for å bruke de nyeste binærene, og start deretter Seleni-frittstående server.

webdriver-manager oppdaterer webdriver-manager start 

Endelig sett inn directConnect: false og legg til seleniumAddress eiendom som følger:

evner: 'browserName': 'firefox', directConnect: false, baseUrl: 'http: // localhost: 4200 /', selenAddress: 'http: // localhost: 4444 / wd / hub', rammeverk: 'jasmin' , jasmineNodeOpts: showColors: true, defaultTimeoutInterval: 30000, print: function () ,

Konfigureringsfilen på GitHub gir mer informasjon om konfigurasjonsalternativene som er tilgjengelige på Protractor. Jeg vil bruke standardvalgene for denne opplæringen.

Kjører testene 

ng e2e er den eneste kommandoen du trenger for å begynne å kjøre testene hvis du bruker Angular-CLI. Hvis testene ser ut til å være sakte, er det fordi Angular må samle koden hver gang du kjører ng e2e. Hvis du vil øke hastigheten litt, så er det du bør gjøre. Server applikasjonen med ng tjene.

Deretter brann opp en ny konsollfane og kjøre:

ng e2e -s false

Tester skal lastes raskere nå.

Vårt mål

Vi skal skrive E2E-tester for et grunnleggende Pastebin-program. Klon prosjektet fra GitHub repo.

Både versjoner, startversjon (den ene uten testene) og den endelige versjonen (den med testene), er tilgjengelige på separate grener. Klone startgrenen for nå. Valgfritt, betjen prosjektet og gå gjennom koden for å bli kjent med søknaden ved hånden.

La oss beskrive vår Pastebin-søknad kort. Programmet vil først laste inn en liste over pastaer (hentet fra en mock-server) til et bord. Hver rad i bordet vil ha en Se Lim inn knappen som, når den klikkes på, åpner et bootstrap-modalt vindu. Modalvinduet viser limdataene med alternativer for å redigere og slette limen. Mot slutten av bordet er det a Lag Lim inn knappen som kan brukes til å legge til nye pastaer.

Prøveapplikasjonen. 

Resten av opplæringen er dedikert til å skrive Protractor tester i Angular.

Protractor Basics

Spesfilen, som slutter med .E2E-spec.ts, vil være vert for de faktiske tester for vår søknad. Vi vil plassere alle testspesifikasjonene inne i e2e katalog siden det er stedet vi har konfigurert Protractor å se etter spesifikasjonene.

Det er to ting du må vurdere når du skriver Protractor tester:

  • Jasmine syntaks
  • Protractor API

Jasmine syntaks

Opprett en ny fil som heter test.e2e-spec.ts med følgende kode for å komme i gang. 

/ * Sti: e2e / test.e2e-spec.ts * / import nettleser, ved, element fra 'tallerken'; Beskriv ('Protractor Demo', () => beforeEach (() => // Koden her vil bli utført før hver den blokkering heter //browser.get('/ ');); den skal vise navnet på programmet ', () => / * Forventninger aksepterer parametere som vil bli matchet med den reelle verdien ved hjelp av Jasmines matcherfunksjoner. f.eks. toEqual (), toContain (), toBe (), toBetTuthy () etc . * / forvente ("Pastebin Application") .Equal ("Pastebin Application");); den ('skal klikke på opprett Lim inn', () => // spec går her;;);

Dette viser hvordan våre tester vil bli organisert i spesifikasjonsfilen ved hjelp av Jasmines syntaks. beskrive(), beforeEach () og den() er globale jasmine funksjoner. 

Jasmine har en flott syntaks for å skrive tester, og det fungerer like godt med Protractor. Hvis du er ny til Jasmine, vil jeg anbefale å gå gjennom Jasmines GitHub side først.

De beskrive blokk brukes til å dele testene i logiske testpakker. Hver beskrive blokk (eller test suite) kan ha flere den blokker (eller testspesifikasjoner). De faktiske testene er definert inne i testspesifikasjonene. 

"Hvorfor skal jeg strukturere mine tester på denne måten?" du kan spørre. En testpakke kan brukes til å logisk beskrive en bestemt funksjon i søknaden din. For eksempel bør alle spesifikasjonene som er berørt av Pastebin-komponenten, ideelt sett dekkes i en beskrivende blokk med tittelen Pastebin Page. Selv om dette kan resultere i tester som er overflødige, vil testene dine være mer lesbare og vedlikeholdsbare. 

En beskrivningsblokk kan ha en beforeEach () metode som vil bli utført en gang, før hver spesifikasjon i den aktuelle blokk. Så, hvis du trenger nettleseren til å navigere til en URL før hver test, plasserer du koden for navigering inne beforeEach () er den riktige tingen å gjøre.

Forvent at setninger, som godtar en verdi, er koblet sammen med noen matcherfunksjoner. Både de virkelige og forventede verdiene blir sammenlignet, og en boolsk returneres som avgjør om testen mislykkes eller ikke.

Protractor API

La oss nå legge kjøtt på den. 

/ * Sti: e2e / test.e2e-spec.ts * / import nettleser, ved, element fra 'tallerken'; beskrive ('Protractor Demo', () => beforeEach (() => browser.get ('/' ;;); den ('skal vise navnet på søknaden', () => element (by.css ('pastebin')). ​​getText ()) .Contain ('Pastebin Application');); det ('Lag Lim inn knappen skal fungere', () =>  id ('source-modal')). isPresent ()). toBeFalsy ("Det modale vinduet skal ikke vises akkurat nå"); element (by.buttonText ('create Paste')) (by.id ('source-modal')) .Present ()). toBeTruthy ('Det modale vinduet skal vises nå'););;

browser.get ( '/') og element (by.css ('. pastebin')) GetText. () er en del av Protractor API. La oss få våre hender skitne og hoppe rett inn i hva Protractor har å tilby.

De fremtredende komponentene eksportert av Protractor API er oppført nedenfor.

  1. nettleser(): Du bør ringe nettleser() for alle operasjoner på nettlesernivå som navigering, feilsøking osv. 
  2. element(): Dette brukes til å slå opp et element i DOM basert på en søkebetingelse eller en kjede av forhold. Den returnerer et ElementFinder-objekt, og du kan utføre handlinger som GetText () eller Klikk () på dem.
  3. element.all (): Dette brukes til å se etter en rekke elementer som samsvarer med en viss kjede av forhold. Den returnerer et ElementArrayFinder-objekt. Alle handlinger som kan utføres på ElementFinder kan også utføres på ElementArrayFinder.
  4. Locators: Locators gir metoder for å finne et element i en kantet applikasjon. 

Siden vi ofte bruker lokalbefolkningen, er det noen av de vanligste locators.

  • by.css ( 'selector-navnet'): Dette er langt den vanligste locatoren for å finne et element basert på navnet på CSS-velgeren.
  • by.name ( 'navn-verdi'): Finnes et element med en samsvarende verdi for navnetattributtet.
  • by.buttonText ( 'knapp-verdi'): Finnes et knappelement eller en rekke knappelementer basert på den indre teksten.  

Merk: Lokalbefolkningen by.model, by.binding og by.repeater virker ikke med Angular 2+ applikasjoner når du skriver denne opplæringen. Bruke CSS-baserte lokalbefolkningen i stedet.

La oss skrive flere tester for vårt Pastebin-program.

 det ('skal akseptere og lagre inntastingsverdier', () => element (by.buttonText ('create Paste')). klikk (); // send innverdier til skjemaet ved å bruke sendKeys element (by.name (' tittel ')). sendKeys (' Hello world in Ruby '); element (by.name (' language ')) element (by.cssContainingText (' option ',' Ruby ')). .Kjør ();) (Kryss)) .Klikk (); // Forvent at tabellen skal inneholde den nye limekomponenten lastRow = element.all (by.tagName ('tr')). siste (); forvente (lastRow.getText ()) .Contain ("Hei verden i Ruby"););

Koden ovenfor fungerer, og du kan bekrefte det selv. Men vil du ikke føle deg mer komfortable skrivetester uten det spesifikke vokabularet i din spesifikke fil? Her er hva jeg snakker om:

 toBeTruthy ("Knappen skulle eksistere"); forvent (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("ThePagePage.CreateButtonPresent"). Modalvinduet skal ikke vises, ennå! "); AddPastePage.clickCreateButton (); expect (addPastePage.isCreatePasteModalPresent ()). ToBeTruthy (" Det modale vinduet skal vises nå ");); det ('skal akseptere og lagre inntastingsverdier', () => addPastePage.clickCreateButton (); // Input-feltet skal være tom først const emptyInputValues ​​= ["", "", "") )). toEqual (emptyInputValues); // Oppdater nå inntastingsfelt addPastePage.addNewPaste (); addPastePage.clickSaveButton (); expect (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("Det modale vinduet skal være borte"); mainPage.getLastRowData ()) .Contain ("Hello World in Ruby"););

Spesifikasjonene vises enklere uten ekstra protractorbagasje. Hvordan gjorde jeg det? La meg introdusere deg til sideobjekter.

Sideobjekter

Sideobjekt er et mønster som er populært i testautomatiseringssirklene. Et sidobjekt modellerer en side eller en del av et program ved hjelp av en objektorientert klasse. Alle objekter (som er relevante for våre tester) som tekst, overskrifter, tabeller, knapper og koblinger kan bli tatt i et sidobjekt. Vi kan deretter importere disse sidobjektene i spesifikasjonsfilen og påberope seg deres metoder. Dette reduserer kod duplisering og gjør vedlikehold av kode enklere.

Opprett en katalog som heter page-gjenstander og legg til en ny fil inni den som heter pastebin.po.ts. Alle gjenstandene som er berørt av Pastebin-komponenten vil bli fanget her. Som tidligere nevnt delte vi hele appen i tre forskjellige komponenter, og hver komponent vil ha et sidobjekt dedikert til det. Navngivningssystemet .po.ts er rent konvensjonelt, og du kan nevne alt du vil ha.

Her er en tegning av siden vi tester.

Her er koden.

pastebin.po.ts

/ * Sti e2e / side-objekter / pastebin.po.ts * / import nettleser, ved, element, løfte, ElementFinder, ElementArrayFinder fra 'tallerken'; eksportklasse Pastebin strekker seg Base navigateToHome (): promise.Promise return browser.get ('/');  getPastebin (): ElementFinder returelement (by.css ('pastebin'));  / * Pastebin Overskrift * / getPastebinHeading (): løfte.Promise return this.getPastebin (). element (by.css ("h2")). getText ();  / * Tabelldata * / getTable (): ElementFinder return this.getTable (). Element (by.css ('table'));  getTableHeader (): løfte.Promise return this.getPastebin (). all (by.tagName ('tr')). få (0) .getText ();  getTableRow (): ElementArrayFinder return this.getPastebin (). alle (by.tagName ('tr'));  getFirstRowData (): løfte.Promise return this.getTableRow (). get (1) .getText ();  getLastRowData (): løfte.Promise return this.getTableRow (). last (). getText ();  / * app-add-paste tag * / getAddPasteTag (): ElementFinder return this.getPastebin (). element (by.tagName ('app-add-paste'));  isAddPasteTagPresent (): løfte.Promise return this.getAddPasteTag (). isPresent (); 

La oss gå over det vi har lært så langt. Protractor API gir tilbake objekter, og vi har hittil opplevd tre typer objekter. De er:

  • promise.Promise
  • ElementFinder
  • ElementArrayFinder

Kort oppsummert, element() returnerer en ElementFinder, og element (). alle returnerer en ElementArrayFinder. Du kan bruke lokalbefolkningen (by.css, by.tagName, etc.) for å finne plasseringen av elementet i DOM og sende det til element() eller element.all ()

ElementFinder og ElementArrayFinder kan deretter knyttes sammen med handlinger, for eksempel er tilstede(), GetText (), Klikk (), etc. Disse metodene returnerer et løfte som blir løst når den aktuelle handlingen er fullført. 

Grunnen til at vi ikke har en kjede av deretter()s i vår test er fordi Protractor tar vare på det internt. Tester ser ut til å være synkron, selv om de ikke er det; Derfor er sluttresultatet en lineær kodende opplevelse. Jeg anbefaler imidlertid å bruke async / avvente syntaks for å sikre at koden er fremtidig bevis.

Du kan kjede flere ElementFinder objekter, som vist nedenfor. Dette er spesielt nyttig hvis DOM har flere selektorer med samme navn, og vi må fange den riktige.

 getTable (): ElementFinder return this.getPastebin (). element (by.css ('table')); 

Nå som vi har koden for sideobjektet klar, la oss importere det til vår spesifikasjon. Her er koden for våre første tester.

/ * Sti: e2e / mainPage.e2e-spec.ts * / import Pastebin fra './page-objects/pastebin.po'; importer browser, protractor fra 'protractor'; / * Scenarier som skal testes 1. Pastebin-siden skal vise en overskrift med tekst Pastebin Application 2. Den skal ha en tabelloverskrift 3. Tabellen skal ha rader 4. App-add-paste tag skal eksistere * / describe ('Pastebin Page '() => const mainPage: Pastebin = new Pastebin (); beforeEach (() => mainPage.navigateToHome ();); den (' skal vise overskriften Pastebin Application ' (mainPage.getPastebinHeading ()) .Equal ("Pastebin Application");); den ('skal ha en tabelloverskrift', () => forventer (mainPage.getTableHeader ()). toContain ("id Tittel Språkkode ");) det ('tabellen skal ha minst én rad', () => forventer (mainPage.getFirstRowData ()). toContain (" Hello world ");) -paste tag ', () => forvente (mainPage.isAddPasteTagPresent ()). toBeTruthy ();));

Organiseringstester og refactoring

Tester bør organiseres på en slik måte at den overordnede strukturen virker meningsfylt og grei. Her er noen påståtte retningslinjer som du bør huske på mens du organiserer E2E-tester.

  • Separate E2E-tester fra enhetstester.
  • Grupper dine E2E-tester fornuftig. Organiser testene dine på en måte som samsvarer med prosjektets struktur.
  • Hvis det er flere sider, må sideobjekter ha egen egen katalog.
  • Hvis sideobjektene har noen metoder til felles (for eksempel navigateToHome ()), opprett et grunnsideobjekt. Andre sidemodeller kan arve fra basissiden. 
  • Gjør testene dine uavhengige av hverandre. Du vil ikke at alle tester skal mislykkes på grunn av en mindre endring i brukergrensesnittet, gjør du?
  • Hold sideobjektdefinisjonene fri for påstand / forventninger. Påstandene skal gjøres inne i spesifikasjonsfilen.

Følg retningslinjene ovenfor, her er hva sidenobjekthierarkiet og filorganisasjonen skal se ut. 

Vi har allerede dekket pastebin.po.ts og mainPage.e2e-spec.ts. Her er resten av filene.

Grunnsideobjekt

/ * bane: e2e / side-objekter / base.po.ts * / import nettleser, ved, element, løfte, ElementFinder, ElementArrayFinder fra 'gradecraft'; eksport klasse Base / * Navigasjonsmetoder * / navigateToHome (): løfte.Promise return browser.get ('/');  navigateToAbout (): løfte.Promise return browser.get ('/ about');  navigateToContact (): løfte.Promise return browser.get ('/ contact');  / * Mock data for å lage en ny Lim inn og redigere eksisterende lim * / getMockPaste (): noen la lim: any = title: "Noe her", språk: "Ruby", lim inn: "Test"  getEditedMockPaste (): noen la lim: any = title: "Lim inn 2", språk: "JavaScript", lim inn: "Test2" returpaste;  / * Metoder deles av addPaste og viewPaste * / getInputTitle (): ElementFinder returelement (by.name ("title"));  getInputLanguage (): ElementFinder returelement (by.name ("language"));  getInputPaste (): ElementFinder returelement (by.name ("paste")); 

Legg til Lim inn sidobjekt

Blueprint for AddPaste-komponenten
/ * Sti: e2e / side-objekter / add-paste.po.ts * / import nettleser, ved, element, løfte, ElementFinder, ElementArrayFinder fra 'gradecraft'; importer Base fra './base.po'; eksport klasse AddPaste utvider Base getAddPaste (): ElementFinder returelement (by.tagName ('app-add-paste'));  / * Opprett Lim inn * / getCreateButton (): ElementFinder return this.getAddPaste (). Element (by.buttonText ("create Paste"));  isCreateButtonPresent (): promise.Promise return this.getCreateButton (). isPresent ();  clickCreateButton (): løfte.Promise return this.getCreateButton (). klikk ();  / * Lag Lim inn Modal * / getCreatePasteModal (): ElementFinder return this.getAddPaste (). Element (by.id ("source-modal"));  isCreatePasteModalPresent (): løfte.Promise return this.getCreatePasteModal (). isPresent ();  / * Lagre knapp * / getSaveButton (): ElementFinder return this.getAddPaste (). Element (by.buttonText ("Save"));  clickSaveButton (): promise.Promise return this.getSaveButton (). klikk ();  / * Lukk knapp * / getCloseButton (): ElementFinder return this.getAddPaste (). Element (by.buttonText ("Close"));  clickCloseButton (): løfte.Promise return this.getCloseButton (). klikk ();  / * Få Input Lim inn verdier fra Modal-vinduet * / getInputPasteValues ​​(): Promise la inputTitle, inputLanguage, inputPaste; // Retur inputverdiene etter at løftet er løst // Merk at denne.getInputTitle () .TeText ikke virker // Bruk getAttribute ('value') istedenfor å returnere Promise.all ([this.getInputTitle (). GetAttribute () "value"), this.getInputLanguage (). getAttribute ("value"), this.getInputPaste (). getAttribute ("value")]) .then ((verdier) => returverdier;);  / * Legg til en ny Lim inn * / addNewPaste (): any let newPaste: any = this.getMockPaste (); // Send innstillingsverdier this.getInputTitle (). SendKeys (newPaste.title); this.getInputLanguage () .element (by.cssContainingText ('option', newPaste.language)). klikk (); . This.getInputPaste () SendKeys (newPaste.paste); // Konverter lim-objektet til en matrise Return Object.keys (newPaste) .map (key => newPaste [key]); 

Legg til Lim inn spesifikasjonsfil

/ * Sti: e2e / addNewPaste.e2e-spec.ts * / import Pastebin fra './page-objects/pastebin.po'; importer AddPaste fra './page-objects/add-paste.po'; importer browser, protractor fra 'protractor'; / * Scenarier som skal testes 1. AddPaste Side skal ha en knapp når den klikkes på, skal presentere et modalvindu 2. Modalvinduet skal akseptere de nye verdiene og lagre dem 4. De lagrede dataene skal vises i hovedsiden 3. Lukk-knappen skal Arbeid * / Beskriv ('Legg til ny Paste-side', () => const addPastePage: AddPaste = Ny AddPaste (); const mainPage: Pastebin = Ny Pastebin (); beforeEach (() => addPastePage.navigateToHome );); den ('burde ha en Create Paste-knapp og modal-vinduet', () => forventer (addPastePage.isCreateButtonPresent ()). toBeTruthy ("knappen skal eksistere"); ). toBeFalsy ("Det modale vinduet skal ikke vises, ennå ikke!"); addPastePage.clickCreateButton (); expect (addPastePage.isCreatePasteModalPresent ()). toBeTruthy ("Det modale vinduet skal vises nå");); ("skal akseptere og lagre inngangsverdier", () => addPastePage.clickCreateButton (); const emptyInputValues ​​= ["", "", ""; forvente (addPastePage.getInputPasteValues ​​()) .Equal (emptyInputValues); const newInputValues ​​= addPastePage.addNewPaste (); forventer (addPastePage.getInputPasteValues ​​()) toEqual (newInputValues.); addPastePage.clickSaveButton (); Forvent (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("Det modale vinduet skal være borte"); Forvent (mainPage.getLastRowData ()). toContain ("Noe her"); ); det ("lukkeknapp skal fungere", () => addPastePage.clickCreateButton (); addPastePage.clickCloseButton (); expect (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("Det modale vinduet skal være borte");); ); 

Øvelser

Det mangler et par ting, men testene for Se Lim inn knappen og det modale vinduet som dukker opp etter at du har klikket på knappen. Jeg skal forlate dette som en øvelse for deg. Imidlertid vil jeg gi deg et hint. 

Strukturen til sidobjektene og spesifikasjonene for ViewPastePage ligner på AddPastePage. 

Blueprint for ViewPaste-komponenten

Her er scenariene som du må teste:

  1. ViewPaste Page burde ha en knapp, og på klikk burde den få et modalt vindu.
  2. Modalvinduet skal vise limdataene for den nylig lagt limen.
  3. Modalvinduet lar deg oppdatere verdier.
  4. Slettknappen skal fungere.

Prøv å holde fast i retningslinjene når det er mulig. Hvis du er i tvil, bytt til siste gren for å se det endelige utkastet til koden. 

Pakke det opp

Så der har du det. I denne artikkelen har vi dekket å skrive slutt-til-ende-tester for vårt vinkelprogram ved hjelp av Protractor. Vi startet med en diskusjon om enhetstester vs. e2e-tester, og da lærte vi om å konfigurere, konfigurere og kjøre Protractor. Resten av opplæringen konsentrert seg om å skrive faktiske tester for demo-Pastebin-applikasjonen. 

Gi meg beskjed om dine tanker og erfaringer om å skrive tester ved hjelp av Protractor eller skrive tester for Angular generelt. Jeg vil gjerne høre dem. Takk for at du leste!