Iniziare con test end-to-end in goniometro angolare

Cosa starai creando

Il goniometro è un popolare framework di test end-to-end che consente di testare la tua applicazione Angular su un browser reale simulando le interazioni del browser nel modo in cui un utente reale interagirebbe con esso. I test end-to-end sono progettati per garantire che l'applicazione si comporti come previsto dal punto di vista dell'utente. Inoltre, i test non riguardano l'effettiva implementazione del codice.

Il goniometro gira sul popolare Selenium WebDriver, che è un'API per l'automazione e il test del browser. Oltre alle funzionalità fornite da Selenium WebDriver, Goniometro offre localizzatori e metodi per acquisire i componenti dell'interfaccia utente dell'applicazione Angular. 

In questo tutorial imparerai a:

  • impostazione, configurazione ed esecuzione di Goniometro 
  • scrivere test di base per Goniometro
  • oggetti della pagina e perché dovresti usarli
  • linee guida da prendere in considerazione durante la scrittura dei test
  • scrivere test E2E per un'applicazione dall'inizio alla fine

Non suona eccitante? Tuttavia, le prime cose prima.

Ho bisogno di usare il goniometro?

Se si utilizza Angular-CLI, è possibile sapere che per impostazione predefinita viene fornito con due framework per il test. Loro sono:

  • test unitari usando Jasmine e Karma
  • test end-to-end utilizzando Goniometro

L'apparente differenza tra i due è che il primo è usato per testare la logica dei componenti e dei servizi, mentre il secondo è usato per assicurare che la funzionalità di alto livello (che coinvolge gli elementi dell'interfaccia utente) dell'applicazione funzioni come previsto. 

Se sei nuovo ai test in Angular, ti consiglio di leggere i componenti di prova nella serie Angular Using Jasmine per avere un'idea migliore di dove disegnare la linea. 

Nel primo caso, è possibile sfruttare la potenza delle utility di test Angular e Jasmine per scrivere non solo test unitari per componenti e servizi, ma anche test di interfaccia utente di base. Tuttavia, se è necessario testare la funzionalità front-end dell'applicazione dall'inizio alla fine, il metodo Gripractor è la scelta giusta. L'API del goniometro combinata con modelli di progettazione come gli oggetti di pagina facilita la scrittura di test più leggibili. Ecco un esempio per far girare le cose.

 / * 1. Dovrebbe avere un pulsante Crea Paste 2. Facendo clic sul pulsante dovrebbe apparire una finestra modale * / it ('dovrebbe avere un pulsante Crea Incolla e una finestra modale', () => expect (addPastePage.isCreateButtonPresent () ) .toBeTruthy ("Il pulsante dovrebbe esistere"); expect (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("La finestra modale non dovrebbe esistere, non ancora!"); addPastePage.clickCreateButton (); expect (addPastePage.isCreatePasteModalPresent ( )). toBeTruthy ("La finestra modale dovrebbe apparire ora"););

Configurazione del goniometro

L'impostazione di Goniometro è semplice se si utilizza Angular-CLI per generare il progetto. La struttura della directory creata da nuovo è come segue.

. ├── e2e │ ├── app.e2e-spec.ts │ ├── app.po.ts │ └── tsconfig.e2e.json ├── karma.conf.js ├── package.json ├── package-lock.json ├── protractor.conf.js ├── README.md ├── src │ ├── app │ ├── assets │ ├── ambienti │ ├── favicon.ico │ ├── indice .html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └ ── typings.d.ts ├── tsconfig.json └── tslint.json 5 directory, 19 file 

Il modello di progetto predefinito creato da Protractor dipende da due file per eseguire i test: i file delle specifiche che si trovano all'interno del file e2e directory e il file di configurazione (protractor.conf.js). Vediamo come configurabile protractor.conf.js è:

/ * Percorso: protractor.conf.ts * / // File di configurazione del goniometro, vedere il collegamento per ulteriori informazioni // https://github.com/angular/protractor/blob/master/lib/config.ts const SpecReporter = require ( 'jasmine-spec-giornalista'); exports.config = allScriptsTimeout: 11000, specifiche: ['./e2e/**/*.e2e-spec.ts'], capacità: 'browserName': 'chrome', directConnect: true, baseUrl: 'http : // localhost: 4200 / ', framework:' jasmine ', jasmineNodeOpts: showColors: true, defaultTimeoutInterval: 30000, print: function () , onPrepare () require (' ts-node '). register ( progetto: 'e2e / tsconfig.e2e.json'); jasmine.getEnv (). addReporter (nuovo SpecReporter (specifica: displayStacktrace: true)); ; 

Se sei d'accordo con l'esecuzione del test sul browser Chrome, puoi lasciarlo così com'è e saltare il resto di questa sezione.

Impostazione del goniometro con il server autonomo Selenium

Il directConnect: true consente a Protractor di connettersi direttamente ai driver del browser. Tuttavia, al momento della stesura di questo tutorial, Chrome è l'unico browser supportato. Se hai bisogno di supporto multi-browser o esegui un browser diverso da Chrome, dovrai configurare il server autonomo Selenium. i passi sono come segue.

Installa Goniometro globalmente usando npm:

gpm install-g goniometro

Questo installa lo strumento da riga di comando per webdriver-manager insieme a quello del goniometro. Ora aggiorna il webdriver-manager per usare i binari più recenti, quindi avvia il server autonomo Selenium.

webdriver-manager update webdriver-manager start 

Infine, imposta il directConnect: false e aggiungi il seleniumAddress proprietà come segue:

capacità: 'browserName': 'firefox', directConnect: false, baseUrl: 'http: // localhost: 4200 /', seleniumAddress: 'http: // localhost: 4444 / wd / hub', framework: 'jasmine' , jasmineNodeOpts: showColors: true, defaultTimeoutInterval: 30000, print: function () ,

Il file di configurazione su GitHub fornisce ulteriori informazioni sulle opzioni di configurazione disponibili su Protractor. Userò le opzioni predefinite per questo tutorial.

Esecuzione dei test 

ng e2e è l'unico comando di cui hai bisogno per iniziare a eseguire i test se stai usando Angular-CLI. Se i test sembrano essere lenti, è perché Angular deve compilare il codice ogni volta che si esegue ng e2e. Se vuoi accelerarlo un po ', ecco cosa dovresti fare. Servire l'applicazione usando ng servire.

Quindi attiva una nuova scheda della console ed esegui:

ng e2e -s false

I test dovrebbero caricarsi più velocemente ora.

Il nostro obbiettivo

Scriveremo test E2E per un'applicazione Pastebin di base. Clona il progetto dal repository GitHub.

Entrambe le versioni, la versione iniziale (quella senza i test) e la versione finale (quella con i test), sono disponibili su rami separati. Clona il ramo di avviamento per ora. Opzionalmente, servire il progetto e passare attraverso il codice per familiarizzare con l'applicazione a portata di mano.

Descriviamo brevemente la nostra applicazione Pastebin. L'applicazione caricherà inizialmente un elenco di paste (recuperate da un server simulato) in una tabella. Ogni riga nella tabella avrà a Visualizza incolla pulsante che, quando viene cliccato, apre una finestra modale di bootstrap. La finestra modale visualizza i dati di incolla con le opzioni per modificare ed eliminare l'incolla. Verso la fine del tavolo, c'è un Crea Incolla pulsante che può essere utilizzato per aggiungere nuove paste.

L'applicazione di esempio. 

Il resto del tutorial è dedicato alla scrittura dei test dei goniometri in Angular.

Nozioni di base sui goniometri

Il file delle specifiche, che termina con .E2E-spec.ts, ospiterà i test effettivi per la nostra applicazione. Inseriremo tutte le specifiche di prova all'interno del e2e directory poiché quello è il posto in cui abbiamo configurato Goniometro per cercare le specifiche.

Ci sono due cose da considerare durante la scrittura dei test del goniometro:

  • Sintassi del gelsomino
  • Goniometro

Sintassi del gelsomino

Crea un nuovo file chiamato test.e2e-spec.ts con il seguente codice per iniziare. 

/ * Percorso: e2e / test.e2e-spec.ts * / import browser, da, elemento da 'goniometro'; description ('Protractor Demo', () => beforeEach (() => // Il codice qui verrà eseguito prima che ogni blocco venga chiamato //browser.get('/ ');); it (' dovrebbe mostrare il nome dell'applicazione ', () => / * Le aspettative accettano parametri che saranno abbinati al valore reale usando le funzioni di matcher di Jasmine.come ad esempio Equal (), toContain (), toBe (), toBeTruthy () ecc. . * / expect ("Pastebin Application"). toEqual ("Pastebin Application");); it ('dovrebbe fare clic sul pulsante crea Paste', () => // spec goes here););

Questo descrive come i nostri test saranno organizzati all'interno del file spec usando la sintassi di Jasmine. descrivere(), beforeeach () e esso () sono funzioni globali del gelsomino. 

Jasmine ha una grande sintassi per i test di scrittura, e funziona altrettanto bene con Protractor. Se sei nuovo a Jasmine, ti consiglio di passare prima attraverso la pagina GitHub di Jasmine.

Il descrivere il blocco viene utilizzato per dividere i test in suite di test logiche. Ogni descrivere block (o test suite) può avere multipli esso blocchi (o specifiche di prova). I test effettivi sono definiti all'interno delle specifiche del test. 

"Perché dovrei strutturare i miei test in questo modo?" potresti chiedere Una suite di test può essere utilizzata per descrivere logicamente una particolare funzionalità dell'applicazione. Ad esempio, tutte le specifiche relative al componente Pastebin dovrebbero idealmente essere coperte all'interno di un blocco descrittivo intitolato Pastebin Page. Sebbene ciò possa comportare test ridondanti, i test saranno più leggibili e manutenibili. 

Un blocco descrittivo può avere un beforeeach () metodo che verrà eseguito una volta, prima di ogni specifica in quel blocco. Quindi, se hai bisogno del browser per navigare verso un URL prima di ogni test, inserisci il codice per la navigazione all'interno beforeeach () è la cosa giusta da fare.

Le dichiarazioni attese, che accettano un valore, sono concatenate con alcune funzioni di corrispondenza. Sia i valori reali che quelli previsti vengono confrontati e viene restituito un valore booleano che determina se il test ha esito negativo o meno.

Goniometro

Ora, mettiamoci un po 'di carne. 

/ * Percorso: e2e / test.e2e-spec.ts * / import browser, da, elemento da 'goniometro'; description ('Protractor Demo', () => beforeEach (() => browser.get ('/');); it ('dovrebbe visualizzare il nome dell'applicazione', () => expect ( element (by.css ('. pastebin')). ​​getText ()). toContain ('Pastebin Application');); it ('create il pulsante Paste dovrebbe funzionare', () => expect (element (by. id ('source-modal')). isPresent ()). toBeFalsy ("La finestra modale non dovrebbe apparire in questo momento"); element (by.buttonText ('create Paste')). click (); expect (elemento (by.id ('source-modal')). isPresent ()). toBeTruthy ('La finestra modale dovrebbe apparire ora');););

browser.get ( '/') e Elemento (by.css ('. pastebin')). ​​getText () fanno parte dell'API del goniometro. Prendiamoci le mani sporche e salta a destra in ciò che Goniometro ha da offrire.

I componenti principali esportati da Protractor API sono elencati di seguito.

  1. del browser (): Dovresti chiamare del browser () per tutte le operazioni a livello di browser come la navigazione, il debug, ecc. 
  2. elemento(): Questo è usato per cercare un elemento nel DOM basato su una condizione di ricerca o una catena di condizioni. Restituisce un oggetto ElementFinder ed è possibile eseguire azioni come getText () o clic() su di essi.
  3. element.all (): Questo è usato per cercare una serie di elementi che corrispondono ad alcune catene di condizioni. Restituisce un oggetto ElementArrayFinder. Tutte le azioni che possono essere eseguite su ElementFinder possono essere eseguite anche su ElementArrayFinder.
  4. locatori: i localizzatori forniscono metodi per trovare un elemento in un'applicazione angolare. 

Dal momento che utilizzeremo i localizzatori molto spesso, ecco alcuni dei localizzatori comunemente usati.

  • by.css ( 'selettore-name'): Questo è di gran lunga il localizzatore comunemente usato per trovare un elemento basato sul nome del selettore CSS.
  • by.name ( 'nome-valore'): Individua un elemento con un valore corrispondente per l'attributo name.
  • by.buttonText (pulsante 'valore'): Individua un elemento del pulsante o un array di elementi del pulsante in base al testo interno.  

Nota: i locator by.model, by.binding e by.repeater non funzionano con le applicazioni Angular 2+ al momento della stesura di questo tutorial. Utilizzare il CSS-localizzatori basati invece.

Scriviamo altri test per la nostra applicazione Pastebin.

 ('dovrebbe accettare e salvare i valori di input', () => elemento (by.buttonText ('create Paste')). click (); // invia i valori di input al modulo usando l'elemento sendKeys (by.name (' title ')). sendKeys (' Hello world in Ruby '); elemento (by.name (' language ')). element (by.cssContainingText (' option ',' Ruby ')). click (); element (di .name ('paste')). sendKeys ("puts 'Hello world';"); element (by.buttonText ('Salva')). click (); // si aspetta che la tabella contenga la nuova pasta const lastRow = element.all (by.tagName ('tr')). last (); expect (lastRow.getText ()). toContain ("Hello world in Ruby"););

Il codice sopra funziona e puoi verificarlo da solo. Tuttavia, non ti sentiresti più a tuo agio a scrivere test senza il vocabolario specifico di Protractor nel tuo file spec? Ecco di cosa sto parlando:

 ('dovrebbe avere un pulsante Crea Paste e una finestra modale', () => expect (addPastePage.isCreateButtonPresent ()). toBeTruthy ("Il pulsante dovrebbe esistere"); expect (addPastePage.isCreatePasteModalPresent ()). toBeFalsy (" La finestra modale non dovrebbe apparire, non ancora! "); AddPastePage.clickCreateButton (); expect (addPastePage.isCreatePasteModalPresent ()). ToBeTruthy (" La finestra modale dovrebbe apparire ora ");); ('dovrebbe accettare e salvare valori di input', () => addPastePage.clickCreateButton (); // Il campo di input dovrebbe essere vuoto inizialmente const emptyInputValues ​​= ["", "", ""]; expect (addPastePage.getInputPasteValues ​​( )). toEqual (emptyInputValues); // Ora aggiorna i campi di input addPastePage.addNewPaste (); addPastePage.clickSaveButton (); expect (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("La finestra modale dovrebbe essere scomparsa"); mainPage.getLastRowData ()). toContain ("Hello World in Ruby"););

Le specifiche appaiono più semplici senza il bagaglio supplementare del goniometro. Come ho fatto? Lascia che ti presenti agli oggetti Page.

Oggetti di pagina

Oggetto pagina è un modello di progettazione che è popolare nei cerchi di automazione del test. Un oggetto di pagina modella una pagina o parte di un'applicazione utilizzando una classe orientata agli oggetti. Tutti gli oggetti (che sono rilevanti per i nostri test) come testo, intestazioni, tabelle, pulsanti e collegamenti possono essere catturati in un oggetto di pagina. Possiamo quindi importare questi oggetti di pagina nel file spec e invocare i loro metodi. Ciò riduce la duplicazione del codice e semplifica la manutenzione del codice.

Crea una directory chiamata page-oggetti e aggiungere un nuovo file al suo interno chiamato pastebin.po.ts. Qui verranno catturati tutti gli oggetti interessati dal componente Pastebin. Come accennato in precedenza, abbiamo diviso l'intera app in tre diversi componenti e ogni componente avrà un oggetto di pagina dedicato. Lo schema di denominazione .po.ts è puramente convenzionale e puoi chiamarlo come vuoi.

Ecco un progetto del pagina che stiamo testando.

Ecco il codice.

pastebin.po.ts

/ * Percorso e2e / oggetti-pagina / pastebin.po.ts * / import browser, da, elemento, promessa, ElementFinder, ElementArrayFinder da 'goniometro'; export class Pastebin estende Base navigateToHome (): promise.Promise return browser.get ('/');  getPastebin (): ElementFinder return element (by.css ('. pastebin'));  / * Pastebin Heading * / getPastebinHeading (): promise.Promise return this.getPastebin (). element (by.css ("h2")). getText ();  / * Dati tabella * / getTable (): ElementFinder return this.getTable (). Element (by.css ('table'));  getTableHeader (): promise.Promise return this.getPastebin (). all (by.tagName ('tr')). get (0) .getText ();  getTableRow (): ElementArrayFinder return this.getPastebin (). all (by.tagName ('tr'));  getFirstRowData (): promise.Promise return this.getTableRow (). get (1) .getText ();  getLastRowData (): promise.Promise return this.getTableRow (). last (). getText ();  / * tag app-add-paste * / getAddPasteTag (): ElementFinder return this.getPastebin (). element (by.tagName ('app-add-paste'));  isAddPasteTagPresent (): promise.Promise return this.getAddPasteTag (). isPresent (); 

Andiamo su ciò che abbiamo imparato finora. L'API del goniometro restituisce oggetti e finora abbiamo incontrato tre tipi di oggetti. Loro sono:

  • promise.Promise
  • ElementFinder
  • ElementArrayFinder

In breve, elemento() restituisce un ElementFinder, e Elemento (). tutto restituisce un ElementArrayFinder. Puoi usare i localizzatori (by.css, by.tagName, ecc.) per trovare la posizione dell'elemento nel DOM e passarlo a elemento() o element.all ()

ElementFinder e ElementArrayFinder possono quindi essere concatenati con azioni come è presente(), getText (), clic(), ecc. Questi metodi restituiscono una promessa che viene risolta quando quella particolare azione è stata completata. 

Il motivo per cui non abbiamo una catena di poi()s nel nostro test è perché Goniometro si prende cura di esso internamente. I test sembrano essere sincroni anche se non lo sono; quindi, il risultato finale è un'esperienza di codifica lineare. Tuttavia, consiglio di utilizzare la sintassi asincrona / attesa per garantire che il codice sia a prova di futuro.

Puoi concatenare più elementi ElementFinder oggetti, come mostrato di seguito. Ciò è particolarmente utile se il DOM ha più selettori con lo stesso nome e abbiamo bisogno di catturare quello giusto.

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

Ora che abbiamo il codice per l'oggetto pagina pronto, importiamolo nelle nostre specifiche. Ecco il codice per i nostri test iniziali.

/ * Percorso: e2e / mainPage.e2e-spec.ts * / import Pastebin da "./page-objects/pastebin.po"; importare browser, goniometro da 'goniometro'; / * Scenari da testare 1. La pagina Pastebin dovrebbe mostrare un'intestazione con il testo Pastebin Application 2. Dovrebbe avere un'intestazione di tabella 3. La tabella dovrebbe avere le righe 4. Il tag app-add-paste dovrebbe esistere * / describe ('Pastebin Page ', () => const mainPage: Pastebin = new Pastebin (); beforeEach (() => mainPage.navigateToHome ();); it (' dovrebbe visualizzare l'intestazione Pastebin Application ', () => expect (mainPage.getPastebinHeading ()). toEqual ("Pastebin Application");); it ('dovrebbe avere un'intestazione di tabella', () => expect (mainPage.getTableHeader ()). toContain ("id Title Language Code ");) it ('table dovrebbe avere almeno una riga', () => expect (mainPage.getFirstRowData ()). toContain (" Hello world ");) it ('dovrebbe avere l'app-add -paste tag ', () => expect (mainPage.isAddPasteTagPresent ()). toBeTruthy ();));

Organizzazione di test e refactoring

I test dovrebbero essere organizzati in modo tale che la struttura generale appaia significativa e diretta. Ecco alcune linee guida che dovresti tenere presente durante l'organizzazione dei test E2E.

  • Separare i test E2E dai test unitari.
  • Raggruppa sensibilmente i test E2E. Organizza i tuoi test in modo che corrisponda alla struttura del tuo progetto.
  • Se ci sono più pagine, gli oggetti di pagina dovrebbero avere una propria directory separata.
  • Se gli oggetti di pagina hanno alcuni metodi in comune (come ad esempio navigateToHome ()), crea un oggetto pagina di base. Altri modelli di pagina possono ereditare dal modello di pagina di base. 
  • Rendi i tuoi test indipendenti gli uni dagli altri. Non vuoi che tutti i tuoi test falliscano a causa di un piccolo cambiamento nell'interfaccia utente, vero??
  • Mantenere le definizioni degli oggetti di pagina prive di asserzioni / aspettative. Le asserzioni dovrebbero essere fatte all'interno del file spec.

Seguendo le linee guida sopra, ecco come dovrebbe essere la gerarchia degli oggetti della pagina e l'organizzazione del file. 

Abbiamo già coperto pastebin.po.ts e mainPage.e2e-spec.ts. Ecco il resto dei file.

Oggetto pagina base

/ * percorso: e2e / page-objects / base.po.ts * / import browser, da, elemento, promessa, ElementFinder, ElementArrayFinder da 'goniometro'; export class Base / * Metodi di navigazione * / navigateToHome (): promise.Promise return browser.get ('/');  navigateToAbout (): promise.Promise return browser.get ('/ about');  navigateToContact (): promise.Promise return browser.get ('/ contact');  / * Dati fittizi per la creazione di un nuovo Incolla e modifica di paste esistenti * / getMockPaste (): any incolla: any = title: "Qualcosa qui", lingua: "Ruby", incolla: "Test" return paste;  getEditedMockPaste (): any incolla: any = title: "Incolla 2", lingua: "JavaScript", incolla: "Test2" return paste;  / * Metodi condivisi da addPaste e viewPaste * / getInputTitle (): ElementFinder return element (by.name ("title"));  getInputLanguage (): ElementFinder return element (by.name ("language"));  getInputPaste (): ElementFinder return element (by.name ("incolla")); 

Aggiungi Incolla oggetto pagina

Progetto per il componente AddPaste
/ * Percorso: e2e / oggetti-pagina / add-paste.po.ts * / import browser, da, elemento, promessa, ElementFinder, ElementArrayFinder da 'goniometro'; importare Base da './base.po'; export class AddPaste estende Base getAddPaste (): ElementFinder return element (by.tagName ('app-add-paste'));  / * Crea pulsante Incolla * / getCreateButton (): ElementFinder return this.getAddPaste (). Element (by.buttonText ("create Paste"));  isCreateButtonPresent (): promise.Promise return this.getCreateButton (). isPresent ();  clickCreateButton (): promise.Promise return this.getCreateButton (). click ();  / * Crea Paste Modal * / getCreatePasteModal (): ElementFinder return this.getAddPaste (). Element (by.id ("source-modal"));  isCreatePasteModalPresent (): promise.Promise return this.getCreatePasteModal (). isPresent ();  / * Pulsante Salva * / getSaveButton (): ElementFinder return this.getAddPaste (). Element (by.buttonText ("Save"));  clickSaveButton (): promise.Promise return this.getSaveButton (). click ();  / * Pulsante Chiudi * / getCloseButton (): ElementFinder return this.getAddPaste (). Element (by.buttonText ("Close"));  clickCloseButton (): promise.Promise return this.getCloseButton (). click ();  / * Ottieni i valori di Input Paste dalla finestra Modal * / getInputPasteValues ​​(): Promise lasciare inputTitle, inputLanguage, inputPaste; // Restituisce i valori di input dopo che la promessa è stata risolta // Nota che this.getInputTitle (). GetText non funziona // Usa getAttribute ('value') invece restituisce Promise.all ([this.getInputTitle (). GetAttribute ( "valore"), this.getInputLanguage (). getAttribute ("valore"), this.getInputPaste (). getAttribute ("valore")]) .then ((valori) => valori di ritorno;);  / * Aggiungi un nuovo Incolla * / addNewPaste (): any let newPaste: any = this.getMockPaste (); // Invia valori di input this.getInputTitle (). SendKeys (newPaste.title); this.getInputLanguage () .element (by.cssContainingText ('option', newPaste.language)). click (); . This.getInputPaste () SendKeys (newPaste.paste); // Converti l'oggetto paste in un array restituisce Object.keys (newPaste) .map (key => newPaste [key]); 

Aggiungi Paste Spec File

/ * Percorso: e2e / addNewPaste.e2e-spec.ts * / import Pastebin da "./page-objects/pastebin.po"; importare AddPaste da "./page-objects/add-paste.po"; importare browser, goniometro da 'goniometro'; / * Scenari da testare 1. La pagina AddPaste dovrebbe avere un pulsante quando si fa clic su dovrebbe presentare una finestra modale 2. La finestra modale dovrebbe accettare i nuovi valori e salvarli 4. I dati salvati dovrebbero apparire in MainPage 3. Il pulsante Chiudi dovrebbe lavoro * / descrizione ('Aggiungi nuova pagina di incolla', () => const addPastePage: AddPaste = new AddPaste (); const mainPage: Pastebin = new Pastebin (); beforeEach (() => addPastePage.navigateToHome ( );); it ('dovrebbe avere un pulsante Crea incolla e una finestra modale', () => expect (addPastePage.isCreateButtonPresent ()). toBeTruthy ("Il pulsante dovrebbe esistere"); expect (addPastePage.isCreatePasteModalPresent () ) .toBeFalsy ("La finestra modale non dovrebbe apparire, non ancora!"); addPastePage.clickCreateButton (); expect (addPastePage.isCreatePasteModalPresent ()). toBeTruthy ("La finestra modale dovrebbe apparire ora");); ("dovrebbe accettare e salvare i valori di input", () => addPastePage.clickCreateButton (); const emptyInputValues ​​= ["", "", ""]; expect (addPastePage.getInputPasteValues ​​()). toEqual (emptyInputValues); const newInputValues ​​= addPastePage.addNewPaste (); aspetterebbe (addPastePage.getInputPasteValues ​​()) toEqual (newInputValues).; addPastePage.clickSaveButton (); expect (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("La finestra modale dovrebbe essere scomparsa"); expect (mainPage.getLastRowData ()). toContain ("Qualcosa qui"); ); ("chiudi pulsante dovrebbe funzionare", () => addPastePage.clickCreateButton (); addPastePage.clickCloseButton (); expect (addPastePage.isCreatePasteModalPresent ()). toBeFalsy ("La finestra modale dovrebbe essere scomparsa");); ); 

esercizi

Ci sono un paio di cose mancanti, però: i test per il Visualizza incolla pulsante e la finestra modale che viene visualizzata dopo aver fatto clic sul pulsante. Ho intenzione di lasciare questo come esercizio per te. Tuttavia, ti lascerò un suggerimento. 

La struttura degli oggetti della pagina e le specifiche per ViewPastePage sono simili a quelle di AddPastePage. 

Progetto per il componente ViewPaste

Ecco gli scenari che devi testare:

  1. Pagina ViewPaste dovrebbe avere un pulsante, e al clic, dovrebbe far apparire una finestra modale.
  2. La finestra modale dovrebbe visualizzare i dati di incollatura della pasta aggiunta di recente.
  3. La finestra modale dovrebbe consentire di aggiornare i valori.
  4. Il pulsante Elimina dovrebbe funzionare.

Cerca di attenersi alle linee guida, ove possibile. In caso di dubbio, passa al ramo finale per vedere la bozza finale del codice. 

Avvolgendolo

Così il gioco è fatto. In questo articolo, abbiamo coperto la scrittura di test end-to-end per la nostra applicazione Angular utilizzando Goniometro. Abbiamo iniziato con una discussione sui test unitari e test e2e, e poi abbiamo imparato a configurare, configurare ed eseguire Protractor. Il resto del tutorial si è concentrato sulla scrittura di test reali per l'applicazione demo di Pastebin. 

Per favore fatemi sapere i vostri pensieri ed esperienze riguardo alla scrittura di prove usando Goniometro o test di scrittura per Angular in generale. Mi piacerebbe sentirli. Grazie per aver letto!