Goniometro - Guida rapida

Questo capitolo fornisce un'introduzione a Goniometro, dove imparerai l'origine di questo framework di test e perché devi sceglierlo, il funzionamento e i limiti di questo strumento.

Cos'è il goniometro?

Goniometro è un framework di test end-to-end open source per applicazioni Angular e AngularJS. È stato costruito da Google sulla parte superiore di WebDriver. Serve anche come sostituto del framework di test AngularJS E2E esistente chiamato "Angular Scenario Runner".

Funziona anche come integratore di soluzioni che combina potenti tecnologie come NodeJS, Selenium, Jasmine, WebDriver, Cucumber, Mocha ecc. Insieme ai test dell'applicazione AngularJS, scrive anche test di regressione automatizzati per normali applicazioni web. Ci consente di testare la nostra applicazione proprio come un utente reale perché esegue il test utilizzando un browser reale.

Il diagramma seguente fornirà una breve panoramica del goniometro:

Osserva che nel diagramma sopra abbiamo:

  • Protractor - Come discusso in precedenza, è un wrapper su WebDriver JS appositamente progettato per app angolari.

  • Jasmine- È fondamentalmente un framework di sviluppo basato sul comportamento per testare il codice JavaScript. Possiamo scrivere facilmente i test con Jasmine.

  • WebDriver JS - È un'implementazione dei collegamenti Node JS per selenium 2.0 / WebDriver.

  • Selenium - Automatizza semplicemente il browser.

Origine

Come detto in precedenza, Protractor è un sostituto per il framework di test AngularJS E2E esistente chiamato "Angular Scenario Runner". Fondamentalmente, l'origine di Goniometro inizia con la fine di Scenario Runner. Una domanda che sorge qui è perché abbiamo bisogno di costruire Goniometro? Per capirlo, dobbiamo prima controllare il suo predecessore: Scenario Runner.

Inception del goniometro

Julie Ralph, il principale contributore allo sviluppo di Goniometro, ha avuto la seguente esperienza con Angular Scenario Runner su un altro progetto all'interno di Google. Questa è diventata ulteriormente la motivazione per costruire Goniometro, specialmente per colmare le lacune -

"Abbiamo provato a utilizzare Scenario Runner e abbiamo scoperto che non poteva fare le cose che dovevamo testare. Avevamo bisogno di testare cose come l'accesso. La tua pagina di accesso non è una pagina angolare e lo Scenario Runner non poteva occuparsene. E non poteva gestire cose come popup e finestre multiple, navigazione nella cronologia del browser, cose del genere. "

Il più grande vantaggio per il goniometro è stata la maturità del progetto Selenium e racchiude i suoi metodi in modo che possa essere facilmente utilizzato per progetti angolari. Il design di Goniometro è costruito in modo tale da testare tutti i livelli come l'interfaccia utente web, i servizi di backend, il livello di persistenza e così via di un'applicazione.

Perché goniometro?

Come sappiamo, quasi tutte le applicazioni utilizzano JavaScript per lo sviluppo. Il compito dei tester diventa difficile quando JavaScript aumenta di dimensioni e diventa complesso per le applicazioni a causa del numero crescente di applicazioni stesse. La maggior parte delle volte diventa molto difficile catturare gli elementi web nelle applicazioni AngularJS, utilizza la sintassi HTML estesa per esprimere i componenti delle applicazioni web, usando JUnit o Selenium WebDriver.

La domanda qui è: perché Selenium Web Driver non è in grado di trovare elementi web AngularJS? Il motivo è perché le applicazioni AngularJS hanno alcuni attributi HTML estesi come ng-repeater, ng-controller e ng-model ecc. Che non sono inclusi nei localizzatori Selenium.

Qui, l'importanza di Protractor viene alla luce perché Protractor sulla parte superiore di Selenium può gestire e controllare quegli elementi HTML estesi nelle applicazioni web AngularJS. Questo è il motivo per cui possiamo dire che la maggior parte dei framework si concentra sulla conduzione di test unitari per applicazioni AngularJS, Protractor utilizzato per testare l'effettiva funzionalità di un'applicazione.

Funzionamento del goniometro

Protractor, il framework di test, funziona insieme a Selenium per fornire un'infrastruttura di test automatizzata per simulare l'interazione di un utente con un'applicazione AngularJS in esecuzione nel browser o dispositivo mobile.

Il funzionamento del goniometro può essere compreso con l'aiuto dei seguenti passaggi:

  • Step 1- Nella prima fase, dobbiamo scrivere i test. Può essere fatto con l'aiuto di Jasmine o Mocha o Cetriolo.

  • Step 2- Ora, dobbiamo eseguire il test che può essere eseguito con l'aiuto di Goniometro. È anche chiamato test runner.

  • Step 3 - In questo passaggio, il server Selenium aiuterà a gestire i browser.

  • Step 4 - Infine, le API del browser vengono richiamate con l'aiuto di Selenium WebDriver.

Vantaggi

Questo framework di test end-to-end open source offre i seguenti vantaggi:

  • Uno strumento open source, Goniometro è molto facile da installare e configurare.

  • Funziona bene con il framework Jasmine per creare il test.

  • Supporta lo sviluppo basato su test (TDD).

  • Contiene attese automatiche, il che significa che non è necessario aggiungere esplicitamente attese e sleep al nostro test.

  • Offre tutti i vantaggi di Selenium WebDriver.

  • Supporta test paralleli tramite più browser.

  • Offre il vantaggio della sincronizzazione automatica.

  • Ha un'eccellente velocità di test.

Limitazioni

Questo framework di test end-to-end open source presenta le seguenti limitazioni:

  • Non scopre alcun verticale nell'automazione del browser perché è un wrapper per WebDriver JS.

  • La conoscenza di JavaScript è essenziale per l'utente, perché è disponibile solo per JavaScript.

  • Fornisce solo test front-end perché è uno strumento di test basato sull'interfaccia utente.

Poiché la conoscenza di JavaScript è essenziale per lavorare con Goniometro, in questo capitolo comprendiamo in dettaglio i concetti del test JavaScript.

Test e automazione JavaScript

JavaScript è il linguaggio di scripting interpretato e digitato dinamicamente più popolare, ma il compito più impegnativo è testare il codice. È perché, a differenza di altri linguaggi compilati come JAVA e C ++, non ci sono passaggi di compilazione in JavaScript che possono aiutare il tester a capire gli errori. Inoltre, i test basati su browser richiedono molto tempo; quindi c'è la necessità di strumenti che supportino i test automatici per JavaScript.

Concetti di test automatizzati

È sempre una buona pratica scrivere il test perché migliora il codice; il problema con il test manuale è che richiede un po 'di tempo ed è soggetto a errori. Il processo di test manuale è abbastanza noioso anche per i programmatori poiché devono ripetere il processo, scrivere le specifiche di test, modificare il codice e aggiornare il browser più volte. Inoltre, il test manuale rallenta anche il processo di sviluppo.

Per i motivi di cui sopra, è sempre utile disporre di alcuni strumenti in grado di automatizzare questi test e aiutare i programmatori a sbarazzarsi di questi passaggi ripetitivi e noiosi. Cosa dovrebbe fare uno sviluppatore per rendere automatizzato il processo di test?

Fondamentalmente, uno sviluppatore può implementare il set di strumenti nella CLI (Command Line Interpreter) o nell'IDE di sviluppo (ambiente di sviluppo integrato). Quindi, questi test verranno eseguiti continuamente in un processo separato anche senza l'input dello sviluppatore. Anche il test automatico di JavaScript non è nuovo e sono stati sviluppati molti strumenti come Karma, Goniometro, CasperJS ecc.

Tipi di test per JavaScript

Possono esserci test diversi per scopi diversi. Ad esempio, alcuni test vengono scritti per verificare il comportamento delle funzioni in un programma, mentre altri vengono scritti per testare il flusso di un modulo o di una funzionalità. Pertanto, abbiamo i seguenti due tipi di test:

Test unitario

Il test viene eseguito sulla parte testabile più piccola del programma chiamata unit. L'unità è fondamentalmente testata in isolamento senza alcun tipo di dipendenza di quell'unità dalle altre parti. In caso di JavaScript, il singolo metodo o funzione che ha un comportamento specifico può essere un'unità di codice e queste unità di codice devono essere testate in modo isolato.

Uno dei vantaggi del test unitario è che il test delle unità può essere eseguito in qualsiasi ordine perché le unità sono indipendenti l'una dall'altra. Un altro vantaggio del test unitario che conta davvero è che può eseguire il test in qualsiasi momento come segue:

  • Fin dall'inizio del processo di sviluppo.
  • Dopo aver completato lo sviluppo di qualsiasi modulo / funzionalità.
  • Dopo aver modificato qualsiasi modulo / funzionalità.
  • Dopo aver aggiunto una nuova funzionalità nell'applicazione esistente.

Per i test di unità automatizzati delle applicazioni JavaScript, possiamo scegliere tra molti strumenti e framework di test come Mocha, Jasmine e QUnit.

Test end-to-end

Può essere definita come la metodologia di test utilizzata per verificare se il flusso dell'applicazione dall'inizio alla fine (da un'estremità all'altra) funziona correttamente come da progetto.

Il test end-to-end è anche chiamato test di funzione / flusso. A differenza del test unitario, il test end-to-end verifica il modo in cui i singoli componenti lavorano insieme come un'applicazione. Questa è la principale differenza tra test unitario e test end-to-end.

Ad esempio, supponiamo di avere un modulo di registrazione in cui l'utente deve fornire alcune informazioni valide per completare la registrazione, il test E2E per quel particolare modulo seguirà i seguenti passaggi per completare il test:

  • Innanzitutto, caricherà / compilerà il form o il modulo.
  • Ora otterrà il DOM (Document object model) degli elementi del form.
  • Successivamente, attiva l'evento clic del pulsante di invio per verificare se funziona o meno.
  • Ora, a scopo di convalida, raccogliere il valore dai campi di input.
  • Successivamente, i campi di input dovrebbero essere convalidati.
  • A scopo di test, chiama un'API falsa per archiviare i dati.

Ogni passaggio fornisce i propri risultati che verranno confrontati con il set di risultati atteso.

Ora, la domanda che sorge è, sebbene questo tipo di E2E o test funzionale possa essere eseguito anche manualmente, perché abbiamo bisogno dell'automazione per questo? Il motivo principale è che l'automazione renderà semplice questo processo di test. Alcuni degli strumenti disponibili che possono essere facilmente integrati con qualsiasi applicazione, a questo scopo sono Selenium, PhantomJS e Goniometro.

Strumenti e framework di test

Abbiamo vari strumenti e framework di test per i test angolari. Di seguito sono riportati alcuni degli strumenti e dei framework ben noti:

Karma

Karma, creato da Vojta Jina, è un test runner. In origine questo progetto si chiamava Testacular. Non è un framework di test, il che significa che ci dà la possibilità di eseguire facilmente e automaticamente unit test JavaScript su browser reali. Karma è stato creato per AngularJS perché prima di Karma non esisteva uno strumento di test automatizzato per gli sviluppatori JavaScript basati sul web. D'altra parte, con l'automazione fornita da Karma, gli sviluppatori possono eseguire un semplice comando singolo e determinare se un'intera suite di test è stata superata o meno.

Vantaggi dell'utilizzo di Karma

Di seguito sono riportati alcuni vantaggi dell'utilizzo di Karma rispetto al processo manuale:

  • Automatizza i test in più browser e dispositivi.
  • Monitora i file per errori e li risolve.
  • Fornisce supporto e documentazione in linea.
  • Facilita l'integrazione con un server di integrazione continua.

Contro dell'uso del karma

I seguenti sono alcuni svantaggi dell'uso di Karma:

Il principale svantaggio dell'utilizzo di Karma è che richiede uno strumento aggiuntivo per la configurazione e la manutenzione.

Se stai usando il test runner Karma con Jasmine, allora è disponibile meno documentazione per trovare informazioni sulla configurazione del tuo CSS nel caso di avere più ID per un elemento.

Gelsomino

Jasmine, un framework di sviluppo basato sul comportamento per testare il codice JavaScript, è stato sviluppato presso Pivotal Labs. Prima dello sviluppo attivo del framework Jasmine, un framework di unit test simile chiamato JsUnit è stato sviluppato anche da Pivotal Labs, che ha un test runner integrato. I test dei browser possono essere eseguiti tramite i test Jasmine includendo il file SpecRunner.html o utilizzandolo anche come test runner da riga di comando. Può essere utilizzato anche con o senza Karma.

Vantaggi dell'utilizzo di Jasmine

I seguenti sono alcuni vantaggi dell'utilizzo di Jasmine:

  • Un framework indipendente da browser, piattaforma e lingua.

  • Supporta lo sviluppo guidato dai test (TDD) insieme allo sviluppo guidato dal comportamento.

  • Ha l'integrazione predefinita con Karma.

  • Sintassi di facile comprensione.

  • Fornisce spie di test, falsi e funzionalità pass-through che aiutano con i test come funzioni aggiuntive.

Contro dell'utilizzo di Jasmine

Quello che segue è un trucco dell'uso di Jasmine:

  • I test devono essere restituiti dall'utente quando cambiano perché non è disponibile alcuna funzione di controllo dei file in Jasmine durante l'esecuzione del test.

Mocha

Mocha, scritto per le applicazioni Node.js, è un framework di test ma supporta anche il test del browser. È abbastanza simile a Jasmine, ma la differenza principale tra loro è che Mocha ha bisogno di alcuni plugin e librerie perché non può funzionare da solo come framework di test. D'altra parte, Jasmine è autonomo. Tuttavia, Mocha è più flessibile da usare rispetto a Jasmine.

Vantaggi dell'utilizzo di Mocha

Di seguito sono riportati alcuni vantaggi dell'utilizzo di Mocha:

  • Mocha è molto facile da installare e configurare.
  • Documentazione semplice e intuitiva.
  • Contiene plugin con diversi progetti di nodi.

Contro dell'utilizzo di Mocha

I seguenti sono alcuni svantaggi dell'utilizzo di Mocha:

  • Ha bisogno di moduli separati per affermazioni, spie ecc.
  • Richiede anche una configurazione aggiuntiva per l'utilizzo con Karma.

QUnit

QUint, originariamente sviluppato da John Resig nel 2008 come parte di jQuery, è una suite di unit test JavaScript potente ma facile da usare. Può essere utilizzato per testare qualsiasi codice JavaScript generico. Sebbene si concentri sul test di JavaScript nel browser, è tuttavia molto comodo da usare da parte dello sviluppatore.

Vantaggi dell'utilizzo di QUnit

Di seguito sono riportati alcuni vantaggi dell'utilizzo di QUnit:

  • Facile da installare e configurare.
  • Documentazione semplice e intuitiva.

Contro dell'utilizzo di QUnit

Quello che segue è uno svantaggio dell'utilizzo di QUnit:

  • È stato sviluppato principalmente per jQuery e quindi non così buono per l'uso con altri framework.

Selenio

Il selenio, originariamente sviluppato da Jason Huggins nel 2004 come strumento interno di ThoughtWorks, è uno strumento di automazione dei test open source. Il selenio si definisce come “Il selenio automatizza i browser. Questo è tutto!". L'automazione dei browser significa che gli sviluppatori possono interagire con i browser molto facilmente.

Vantaggi dell'utilizzo del selenio

Di seguito sono riportati alcuni vantaggi dell'utilizzo del selenio:

  • Contiene un ampio set di funzionalità.
  • Supporta test distribuiti.
  • Ha il supporto SaaS attraverso servizi come Sauce Labs.
  • Facile da usare con semplici documentazioni e ricche risorse disponibili.

Contro dell'uso del selenio

I seguenti sono alcuni svantaggi dell'utilizzo del selenio:

  • Uno dei principali svantaggi dell'utilizzo del selenio è che deve essere eseguito come processo separato.
  • La configurazione è un po 'complicata in quanto lo sviluppatore deve seguire diversi passaggi.

Nei capitoli precedenti abbiamo appreso le basi di Goniometro. In questo capitolo impareremo come installarlo e configurarlo.

Prerequisiti

Dobbiamo soddisfare i seguenti prerequisiti prima di installare Goniometro sul tuo computer:

Node.js

Goniometro è un modulo Node.js, quindi il prerequisito molto importante è che dobbiamo avere Node.js installato sul nostro computer. Installeremo il pacchetto Goniometro utilizzando npm (un gestore di pacchetti JavaScript), fornito con Node.js.

Per installare Node.js, segui il link ufficiale - https://nodejs.org/en/download/. Dopo aver installato Node.js, puoi controllare la versione di Node.js e npm scrivendo il comandonode --version e npm --version nel prompt dei comandi come mostrato di seguito -

Cromo

Google Chrome, un browser web creato da Google, verrà utilizzato per eseguire test end-to-end in Protractor senza la necessità di un server Selenium. Puoi scaricare Chrome facendo clic sul link -https://www.google.com/chrome/.

Selenium WebDriver per Chrome

Questo strumento è fornito con il modulo Goniometro npm e ci permette di interagire con le applicazioni web.

Installazione del goniometro

Dopo aver installato Node.js sul nostro computer, possiamo installare Goniometro con l'aiuto del seguente comando:

npm install -g protractor

Una volta installato correttamente il goniometro, possiamo verificarne la versione scrivendo protractor --version comando nel prompt dei comandi come mostrato di seguito -

Installazione di WebDriver per Chrome

Dopo aver installato Goniometro, dobbiamo installare Selenium WebDriver per Chrome. Può essere installato con l'aiuto del seguente comando:

webdriver-manager update

Il comando precedente creerà una directory Selenium che contiene il driver Chrome richiesto utilizzato nel progetto.

Conferma di installazione e configurazione

Possiamo confermare l'installazione e la configurazione di Protractor modificando leggermente il file conf.js fornito nell'esempio dopo l'installazione di Protractor. Puoi trovare questo file conf.js nella directory principalenode_modules/Protractor/example.

Per questo, crea prima un nuovo file chiamato testingconfig.js nella stessa directory, ad es node_modules/Protractor/example.

Ora, nel file conf.js, sotto il parametro di dichiarazione del file sorgente, scrivi testingconfig.js.

Quindi, salva e chiudi tutti i file e apri il prompt dei comandi. Esegui il file conf.js come mostrato nello screenshot riportato di seguito.

La configurazione e l'installazione di Goniometro è riuscita se hai ottenuto l'output come mostrato di seguito -

L'output sopra mostra che non ci sono specifiche perché abbiamo fornito il file vuoto nel parametro di dichiarazione del file di origine nel file conf.js. Ma dall'output di cui sopra, possiamo vedere che sia il goniometro che WebDriver funzionano correttamente.

Problemi di installazione e configurazione

Durante l'installazione e la configurazione di Goniometro e WebDriver, potremmo riscontrare i seguenti problemi comuni:

Selenio non installato correttamente

È il problema più comune durante l'installazione di WebDriver. Questo problema si verifica se non si aggiorna WebDriver. Nota che dobbiamo aggiornare WebDriver, altrimenti non saremmo in grado di fare riferimento all'installazione di Goniometro.

Non riesco a trovare i test

Un altro problema comune è che dopo aver eseguito Goniometro, mostra che non è possibile trovare i test. Per questo, dobbiamo assicurarci che i relativi percorsi, nomi di file o estensioni siano corretti. Abbiamo anche bisogno di scrivere il file conf.js con molta attenzione perché inizia con il file di configurazione stesso.

Come discusso in precedenza, Protractor è un framework di test end-to-end open source per applicazioni Angular e AngularJS. È il programma Node.js. D'altra parte, Selenium è un framework di automazione del browser che include Selenium Server, le API WebDriver e i driver del browser WebDriver.

Goniometro con selenio

Se parliamo della congiunzione di Goniometro e Selenio, Goniometro può lavorare con il server Selenium per fornire un'infrastruttura di test automatizzata. L'infrastruttura può simulare l'interazione dell'utente con un'applicazione angolare in esecuzione su un browser o su un dispositivo mobile. La congiunzione di Goniometro e Selenio può essere suddivisa in tre partizioni, ovvero test, server e Browser, come mostrato nel diagramma seguente:

Selenium WebDriver Processes

Come abbiamo visto nel diagramma sopra, un test con Selenium WebDriver coinvolge i seguenti tre processi:

  • Gli script di test
  • Il server
  • Il browser

In questa sezione, discutiamo la comunicazione tra questi tre processi.

Comunicazione tra script di test e server

La comunicazione tra i primi due processi - gli script di test e il server dipende dal funzionamento di Selenium Server. In altre parole, possiamo dire che il modo in cui il server Selenium è in esecuzione darà la forma al processo di comunicazione tra gli script di test e il server.

Il server Selenium può essere eseguito localmente sulla nostra macchina come Selenium Server autonomo (selenium-server-standalone.jar) oppure può essere eseguito in remoto tramite un servizio (Sauce Labs). In caso di server Selenium autonomo, ci sarebbe una comunicazione http tra Node.js e il server selenium.

Comunicazione tra il server e il browser

Come sappiamo, il server è responsabile dell'inoltro dei comandi al browser dopo aver interpretato gli stessi dagli script di test. Ecco perché anche il server e il browser richiedono un mezzo di comunicazione e qui la comunicazione avviene con l'aiuto diJSON WebDriver Wire Protocol. Il browser esteso con Browser Driver che viene utilizzato per interpretare i comandi.

Il concetto di cui sopra sui processi Selenium WebDriver e la loro comunicazione può essere compreso con l'aiuto del seguente diagramma:

Mentre si lavora con Goniometro, il primo processo, ovvero lo script di test, viene eseguito utilizzando Node.js ma prima di eseguire qualsiasi azione sul browser invierà un comando aggiuntivo per assicurarsi che l'applicazione da testare sia stabilizzata.

Configurazione di Selenium Server

Selenium Server agisce come un server proxy tra il nostro script di test e il driver del browser. Fondamentalmente inoltra il comando dal nostro script di test al WebDriver e restituisce le risposte dal WebDriver al nostro script di test. Ci sono le seguenti opzioni per impostare il server Selenium che sono incluse inconf.js file di script di test -

Server selenio autonomo

Se vogliamo eseguire il server sulla nostra macchina locale, dobbiamo installare un server selenio autonomo. Il prerequisito per installare un server selenium autonomo è JDK (Java Development Kit). Dobbiamo avere JDK installato sulla nostra macchina locale. Possiamo verificarlo eseguendo il seguente comando dalla riga di comando:

java -version

Ora abbiamo la possibilità di installare e avviare Selenium Server manualmente o dallo script di test.

Installazione e avvio manuale del server Selenium

Per installare e avviare manualmente il server Selenium, è necessario utilizzare lo strumento da riga di comando WebDriver-Manager fornito con Goniometro. I passaggi per l'installazione e l'avvio del server Selenium sono i seguenti:

Step 1- Il primo passo è installare il server Selenium e ChromeDriver. Può essere fatto con l'aiuto dell'esecuzione del seguente comando:

webdriver-manager update

Step 2- Successivamente, dobbiamo avviare il server. Può essere fatto con l'aiuto dell'esecuzione del seguente comando:

webdriver-manager start

Step 3- Alla fine abbiamo bisogno di impostare seleniumAddress nel file di configurazione all'indirizzo del server in esecuzione. L'indirizzo predefinito sarebbehttp://localhost:4444/wd/hub.

Avvio del server Selenium da uno script di test

Per avviare il server Selenium da uno script di test, dobbiamo impostare le seguenti opzioni nel nostro file di configurazione:

  • Location of jar file - Abbiamo bisogno di impostare la posizione del file jar per il server Selenium autonomo nel file di configurazione impostando seleniumServerJar.

  • Specifying the port- Dobbiamo anche specificare la porta da utilizzare per avviare il Selenium Server autonomo. Può essere specificato nel file di configurazione impostando seleniumPort. La porta predefinita è 4444.

  • Array of command line options- Abbiamo anche bisogno di impostare l'array di opzioni della riga di comando da passare al server. Può essere specificato nel file di configurazione impostando seleniumArgs. Se hai bisogno di un elenco completo di array di comandi, avvia il server con l'estensione-help bandiera.

Lavorare con Remote Selenium Server

Un'altra opzione per eseguire il nostro test è utilizzare il server Selenium da remoto. Il prerequisito per utilizzare il server in remoto è che dobbiamo avere un account con un servizio che ospita il server. Mentre lavoriamo con Goniometro, abbiamo il supporto integrato per i seguenti servizi che ospitano il server:

TestObject

Per utilizzare TestObject come server Selenium remoto, dobbiamo impostare testobjectUser, il nome utente del nostro account TestObject e testobjectKey, la chiave API del nostro account TestObject.

BrowserStack

Per utilizzare BrowserStack come server Selenium remoto, dobbiamo impostare browserstackUser, il nome utente del nostro account BrowserStack e browserstackKey, la chiave API del nostro account BrowserStack.

Sauce Labs

Per utilizzare Sauce Labs come server Selenium remoto, dobbiamo impostare il sauceUser, il nome utente del nostro account Sauce Labs e SauceKey, la chiave API del nostro account Sauce Labs.

Kobiton

Per utilizzare Kobiton come server Selenium remoto dobbiamo impostare kobitonUser, il nome utente del nostro account Kobiton e kobitonKey, la chiave API del nostro account Kobiton.

Connessione diretta al driver del browser senza utilizzare Selenium Server

Un'altra opzione per eseguire il nostro test è connettersi direttamente al driver del browser senza utilizzare il server Selenium. Goniometro può testare direttamente, senza l'uso di Selenium Server, su Chrome e Firefox impostando directConnect: true nel file di configurazione.

Configurazione del browser

Prima di configurare e impostare il browser, dobbiamo sapere quali browser sono supportati da Protractor. Di seguito è riportato l'elenco dei browser supportati da Goniometro:

  • ChromeDriver
  • FirefoxDriver
  • SafariDriver
  • IEDriver
  • Appium-iOS/Safari
  • Appium-Android/Chrome
  • Selendroid
  • PhantomJS

Per l'impostazione e la configurazione del browser, dobbiamo passare al file di configurazione di Protractor poiché la configurazione del browser viene eseguita all'interno dell'oggetto delle funzionalità del file di configurazione.

Configurazione di Chrome

Per configurare il browser Chrome, dobbiamo impostare l'oggetto delle funzionalità come segue

capabilities: {
   'browserName': 'chrome'
}

Possiamo anche aggiungere opzioni specifiche per Chrome che sono nidificate in chromeOptions e il suo elenco completo può essere visualizzato all'indirizzo https://sites.google.com/a/chromium.org/chromedriver/capabilities.

Ad esempio, se si desidera aggiungere il contatore FPS in alto a destra, è possibile farlo come segue nel file di configurazione:

capabilities: {
   'browserName': 'chrome',
   'chromeOptions': {
      'args': ['show-fps-counter=true']
   }
},

Configurazione di Firefox

Per configurare il browser Firefox, è necessario impostare l'oggetto delle funzionalità come segue:

capabilities: {
   'browserName': 'firefox'
}

Possiamo anche aggiungere opzioni specifiche per Firefox che sono annidate nell'oggetto moz: firefoxOptions e il suo elenco completo può essere visto su https://github.com/mozilla/geckodriver#firefox-capabilities.

Ad esempio, se desideri eseguire il test su Firefox in modalità provvisoria, puoi farlo come segue nel file di configurazione:

capabilities: {
   'browserName': 'firefox',
   'moz:firefoxOptions': {
     'args': ['—safe-mode']
   }
},

Configurazione di un altro browser

Per configurare qualsiasi altro browser diverso da Chrome o Firefox, è necessario installare un file binario separato da https://docs.seleniumhq.org/download/.

Configurazione di PhantonJS

In realtà, PhantomJS non è più supportato a causa dei suoi problemi di arresto anomalo. Invece di quello si consiglia di utilizzare Chrome headless o Firefox headless. Possono essere impostati come segue:

Per configurare Chrome headless, dobbiamo avviare Chrome con il flag –headless come segue -

capabilities: {
   'browserName': 'chrome',
   'chromeOptions': {
      'args': [“--headless”, “--disable-gpu”, “--window-size=800,600”]
   }
},

Per configurare Firefox headless, è necessario avviare Firefox con l'estensione –headless contrassegna come segue -

capabilities: {
   'browserName': 'firefox',
   'moz:firefoxOptions': {
      'args': [“--headless”]
   }
},

Configurazione di più browser per il test

Possiamo anche testare su più browser. Per questo dobbiamo usare l'opzione di configurazione multiCapabilities come segue:

multiCapabilities: [{
   'browserName': 'chrome'
},{
   'browserName': 'firefox'
}]

Quale Framework?

Due framework di test BDD (Behavior driven development), Jasmine e Mocha sono supportati da Protractor. Entrambi i framework sono basati su JavaScript e Node.js. La sintassi, il report e lo scaffolding, necessari per scrivere e gestire i test, sono forniti da questi framework.

Successivamente, vediamo come possiamo installare vari framework:

Quadro Jasmine

È il framework di test predefinito per Protractor. Quando installi Goniometro, otterrai la versione 2.x di Jasmine con esso. Non è necessario installarlo separatamente.

Quadro moka

Mocha è un altro framework di test JavaScript in esecuzione fondamentalmente su Node.js. Per utilizzare Mocha come framework di test, è necessario utilizzare l'interfaccia BDD (Behavior driven development) e le asserzioni Chai con Chai As Promised. L'installazione può essere eseguita con l'aiuto dei seguenti comandi:

npm install -g mocha
npm install chai
npm install chai-as-promised

Come puoi vedere, l'opzione -g viene utilizzata durante l'installazione di mocha, è perché abbiamo installato Goniometro globalmente usando l'opzione -g. Dopo averlo installato, dobbiamo richiedere e configurare Chai all'interno dei nostri file di prova. Può essere fatto come segue:

var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;

Dopodiché, possiamo usare Chai As Promised come tale -

expect(myElement.getText()).to.eventually.equal('some text');

Ora, dobbiamo impostare la proprietà del framework su mocha del file di configurazione aggiungendo framework: 'mocha'. Le opzioni come 'reporter' e 'slow' per mocha possono essere aggiunte nel file di configurazione come segue:

mochaOpts: {
   reporter: "spec", slow: 3000
}

Quadro di cetriolo

Per usare Cucumber come nostro framework di test, dobbiamo integrarlo con Goniometro con opzione framework custom. L'installazione può essere eseguita con l'aiuto dei seguenti comandi

npm install -g cucumber
npm install --save-dev protractor-cucumber-framework

Come puoi vedere, l'opzione -g viene utilizzata durante l'installazione di Cucumber, è perché abbiamo installato Goniometro globalmente, cioè con l'opzione -g. Successivamente, dobbiamo impostare la proprietà framework sucustom del file di configurazione aggiungendo framework: 'custom' e frameworkPath: 'Protractor-cucumber-framework' al file di configurazione denominato cucumberConf.js.

Il codice di esempio mostrato di seguito è un file cucumberConf.js di base che può essere utilizzato per eseguire i file delle caratteristiche del cetriolo con Goniometro -

exports.config = {
   seleniumAddress: 'http://localhost:4444/wd/hub',

   baseUrl: 'https://angularjs.org/',

   capabilities: {
      browserName:'Firefox'
   },

   framework: 'custom',

   frameworkPath: require.resolve('protractor-cucumber-framework'),

   specs: [
      './cucumber/*.feature'
   ],

   // cucumber command line options
   cucumberOpts: {
      require: ['./cucumber/*.js'],
      tags: [],
      strict: true,
      format: ["pretty"],
      'dry-run': false,
      compiler: []
   },
   onPrepare: function () {
      browser.manage().window().maximize();
   }
};

In questo capitolo, vediamo come scrivere il primo test in Goniometro.

File richiesti da Goniometro

Goniometro necessita dei seguenti due file per essere eseguito:

Specifica o file di prova

È uno dei file importanti per eseguire Goniometro. In questo file, scriveremo il nostro codice di prova effettivo. Il codice di test viene scritto utilizzando la sintassi del nostro framework di test.

Ad esempio, se stiamo usando Jasmine framework, quindi il codice di test verrà scritto utilizzando la sintassi di Jasmine. Questo file conterrà tutti i flussi funzionali e le asserzioni del test.

In parole semplici, possiamo dire che questo file contiene la logica e i locatori per interagire con l'applicazione.

Esempio

Quello che segue è un semplice script, TestSpecification.js, con il test case per navigare a un URL e controllare il titolo della pagina -

//TestSpecification.js
describe('Protractor Demo', function() {
   it('to check the page title', function() {
      browser.ignoreSynchronization = true;
      browser.get('https://www.tutorialspoint.com/tutorialslibrary.htm');
      browser.driver.getTitle().then(function(pageTitle) {
         expect(pageTitle).toEqual('Free Online Tutorials and Courses');
      });
   });
});

Spiegazione del codice

Il codice del file delle specifiche sopra può essere spiegato come segue:

Browser

È la variabile globale creata da Protractor per gestire tutti i comandi a livello di browser. È fondamentalmente un wrapper attorno a un'istanza di WebDriver. browser.get () è un semplice metodo Selenium che dirà a Protractor di caricare una pagina particolare.

  • describe e it- Entrambe sono le sintassi del framework di test Jasmine. Il’Describe’ viene utilizzato per contenere il flusso end-to-end del nostro caso di test mentre ‘it’contiene alcuni degli scenari di test. Possiamo avere più‘it’ blocchi nel nostro programma di test case.

  • Expect - È un'affermazione in cui stiamo confrontando il titolo della pagina web con alcuni dati predefiniti.

  • ignoreSynchronization- È un tag del browser che viene utilizzato quando proveremo a testare siti Web non angolari. Goniometro prevede di funzionare solo con siti Web angolari, ma se vogliamo lavorare con siti Web non angolari, questo tag deve essere impostato su“true”.

File di configurazione

Come suggerisce il nome, questo file fornisce spiegazioni per tutte le opzioni di configurazione di Goniometro. Fondamentalmente dice a Goniometro quanto segue:

  • Dove trovare i file di test o delle specifiche
  • Quale browser scegliere
  • Quale framework di test utilizzare
  • Dove parlare con Selenium Server

Esempio

Quello che segue è il semplice script, config.js, con il test

// config.js
exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

   // Spec patterns are relative to the current working directory when
   // protractor is called.
   specs: ['TestSpecification.js'],

Spiegazione del codice

Il codice del file di configurazione sopra con tre parametri di base, può essere spiegato come segue:

Parametro delle capacità

Questo parametro viene utilizzato per specificare il nome del browser. Può essere visto nel seguente blocco di codice del file conf.js -

exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
},

Come visto sopra, il nome del browser fornito qui è "chrome", che è il browser predefinito per Goniometro. Possiamo anche cambiare il nome del browser.

Parametro quadro

Questo parametro viene utilizzato per specificare il nome del framework di test. Può essere visto nel seguente blocco di codice del file config.js -

exports.config = {
   directConnect: true,

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

Qui stiamo usando il framework di test "jasmine".

Parametro di dichiarazione del file di origine

Questo parametro viene utilizzato per specificare il nome della dichiarazione del file di origine. Può essere visto nel seguente blocco di codice del file conf.js -

exports.config = {
   directConnect: true,
   // Spec patterns are relative to the current working 
   directory when protractor is called.
   specs: ['TsetSpecification.js'],

Come visto sopra, il nome della dichiarazione del file sorgente qui fornito è ‘TestSpecification.js’. È perché, per questo esempio, abbiamo creato il file delle specifiche con nomeTestSpecification.js.

Esecuzione del codice

Poiché abbiamo una conoscenza di base dei file necessari e del loro codice per l'esecuzione di Goniometro, proviamo a eseguire l'esempio. Possiamo seguire i seguenti passaggi per eseguire questo esempio:

  • Step 1 - Innanzitutto, apri il prompt dei comandi.

  • Step 2 - Successivamente, dobbiamo andare nella directory in cui abbiamo salvato i nostri file, ovvero config.js e TestSpecification.js.

  • Step 3 - Ora, esegui il file config.js eseguendo il comando Protrcator config.js.

La schermata mostrata di seguito spiegherà i passaggi precedenti per eseguire l'esempio:

Si vede nella schermata che il test è stato superato.

Ora, supponiamo che se stiamo testando siti web non angolari e non mettiamo il tag ignoreSynchronization su true, dopo aver eseguito il codice otterremo l'errore "Angular non è stato trovato sulla pagina".

Può essere visto nella seguente schermata:

Generazione di report

Finora abbiamo discusso dei file necessari e della loro codifica per l'esecuzione dei casi di test. Goniometro è anche in grado di generare il report per i casi di test. A tal fine, supporta Jasmine. JunitXMLReporter può essere utilizzato per generare automaticamente rapporti di esecuzione dei test.

Ma prima, dobbiamo installare Jasmine reporter con l'aiuto del seguente comando:

npm install -g jasmine-reporters

Come puoi vedere, l'opzione -g viene utilizzata durante l'installazione di Jasmine Reporter, perché abbiamo installato Goniometro globalmente, con l'opzione -g.

Dopo aver installato con successo jasmine-reporter, dobbiamo aggiungere il seguente codice nel nostro file config.js utilizzato in precedenza -

onPrepare: function(){ //configure junit xml report

   var jasmineReporters = require('jasmine-reporters');
   jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
      consolidateAll: true,
      filePrefix: 'guitest-xmloutput',
      savePath: 'test/reports'
   }));

Ora, il nostro nuovo file config.js sarebbe il seguente:

// An example configuration file.
exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

   // Spec patterns are relative to the current working directory when
   // protractor is called.
   specs: ['TestSpecification.js'],
   //framework: "jasmine2", //must set it if you use JUnitXmlReporter
   onPrepare: function(){ //configure junit xml report
      var jasmineReporters = require('jasmine-reporters');
      jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
         consolidateAll: true,
         filePrefix: 'guitest-xmloutput',
         savePath: 'reports'
      }));
   },
};

Dopo aver eseguito il file di configurazione sopra nello stesso modo, abbiamo eseguito in precedenza, genererà un file XML contenente il report nella directory principale in reportscartella. Se il test ha avuto successo, il rapporto apparirà come di seguito:

Ma, se il test fallisce, il rapporto apparirà come mostrato di seguito:

Goniometro - Core APIS

Questo capitolo consente di comprendere le varie API principali che sono fondamentali per il funzionamento del goniometro.

Importanza delle API Goniometro

Goniometro ci fornisce una vasta gamma di API che sono molto importanti per eseguire le seguenti azioni per ottenere lo stato corrente del sito Web:

  • Ottenere gli elementi DOM della pagina web che andremo a testare.
  • Interagire con gli elementi DOM.
  • Assegnare azioni a loro.
  • Condivisione di informazioni con loro.

Per eseguire le attività di cui sopra, è molto importante comprendere le API di Protractor.

Varie API Goniometro

Come sappiamo, Protractor è un wrapper attorno a Selenium-WebDriver, che è il collegamento WebDriver per Node.js. Goniometro ha le seguenti API:

Browser

È un wrapper attorno a un'istanza di WebDriver che viene utilizzata per gestire comandi a livello di browser come navigazione, informazioni a livello di pagina, ecc. Ad esempio, il metodo browser.get carica una pagina.

Elemento

Viene utilizzato per cercare e interagire con l'elemento DOM nella pagina che stiamo testando. A tal fine, richiede un parametro per individuare l'elemento.

Localizzatori (di)

È una raccolta di strategie di individuazione degli elementi. Gli elementi, ad esempio, possono essere trovati dal selettore CSS, dall'ID o da qualsiasi altro attributo a cui sono associati con ng-model.

Successivamente, discuteremo in dettaglio di queste API e delle loro funzioni.

API del browser

Come discusso in precedenza, è un wrapper attorno a un'istanza di WebDriver per la gestione dei comandi a livello di browser. Svolge varie funzioni come segue:

Funzioni e loro descrizioni

Le funzioni dell'API ProtractorBrowser sono le seguenti:

browser.angularAppRoot

Questa funzione dell'API del browser imposta il selettore CSS per un elemento su cui troveremo Angular. Di solito, questa funzione è in 'body', ma nel caso in cui la nostra ng-app, è in una sottosezione della pagina; può anche essere un sottoelemento.

browser.waitForAngularEnabled

Questa funzione dell'API del browser può essere impostata su true o false. Come suggerisce il nome, se questa funzione è impostata su false, Goniometro non aspetterà Angular$http and $attività di timeout da completare prima di interagire con il browser. Possiamo anche leggere lo stato corrente senza modificarlo chiamando waitForAngularEnabled () senza passare un valore.

browser.getProcessedConfig

Con l'aiuto di questa funzione delle API del browser possiamo ottenere l'oggetto di configurazione elaborato, comprese le specifiche e le capacità, che è attualmente in esecuzione.

browser.forkNewDriverInstance

Come suggerisce il nome, questa funzione eseguirà il fork di un'altra istanza del browser da utilizzare nei test interattivi. Può essere eseguito con il flusso di controllo abilitato e disabilitato. Di seguito viene fornito un esempio per entrambi i casi:

Example 1

In esecuzione browser.forkNewDriverInstance() con flusso di controllo abilitato -

var fork = browser.forkNewDriverInstance();
fork.get(‘page1’);

Example 2

In esecuzione browser.forkNewDriverInstance() con flusso di controllo disabilitato -

var fork = await browser.forkNewDriverInstance().ready;
await forked.get(‘page1’);

browser.restart

Come suggerisce il nome, riavvierà il browser chiudendo l'istanza del browser e creandone una nuova. Può anche essere eseguito con il flusso di controllo abilitato e disabilitato. Di seguito viene fornito un esempio per entrambi i casi:

Example 1 - In esecuzione browser.restart() con flusso di controllo abilitato -

browser.get(‘page1’);
browser.restart();
browser.get(‘page2’);

Example 2 - In esecuzione browser.forkNewDriverInstance() con flusso di controllo disabilitato -

await browser.get(‘page1’);
await browser.restart();
await browser.get(‘page2’);

browser.restartSync

È simile alla funzione browser.restart (). L'unica differenza è che restituisce direttamente la nuova istanza del browser invece di restituire una promessa che si risolve alla nuova istanza del browser. Può essere eseguito solo quando il flusso di controllo è abilitato.

Example - In esecuzione browser.restartSync() con flusso di controllo abilitato -

browser.get(‘page1’);
browser.restartSync();
browser.get(‘page2’);

browser.useAllAngular2AppRoots

Come suggerisce il nome, è compatibile solo con Angular2. Cercherà tra tutte le app angolari disponibili nella pagina mentre trova elementi o attende stabilità.

browser.waitForAngular

Questa funzione dell'API del browser indica al WebDriver di attendere fino a quando Angular non ha terminato il rendering e non ha sospeso $http or $timeout chiama prima di continuare.

browser.findElement

Come suggerisce il nome, questa funzione API del browser attende che Angular termini il rendering prima di cercare l'elemento.

browser.isElementPresent

Come suggerisce il nome, questa funzione API del browser verificherà che l'elemento sia presente o meno sulla pagina.

browser.addMockModule

Aggiungerà un modulo da caricare prima di Angular ogni volta che viene chiamato il metodo Protractor.get.

Example

browser.addMockModule('modName', function() {
   angular.module('modName', []).value('foo', 'bar');
});

browser.clearMockModules

a differenza di browser.addMockModule, cancellerà l'elenco dei moduli fittizi registrati.

browser.removeMockModule

Come suggerisce il nome, rimuoverà un registro dei moduli fittizi. Esempio: browser.removeMockModule ('modName');

browser.getRegisteredMockModules

Di fronte a browser.clearMockModule, otterrà l'elenco dei moduli fittizi registrati.

browser.get

Possiamo usare browser.get () per navigare nel browser verso un particolare indirizzo web e caricare i moduli fittizi per quella pagina prima del caricamento angolare.

Example

browser.get(url);
browser.get('http://localhost:3000'); 
// This will navigate to the localhost:3000 and will load mock module if needed

browser.refresh

Come suggerisce il nome, questo ricaricherà la pagina corrente e caricherà i moduli fittizi prima di Angular.

browser.navigate

Come suggerisce il nome, viene utilizzato per combinare i metodi di navigazione nell'oggetto di navigazione in modo che vengano richiamati come prima. Esempio: driver.navigate (). Refresh ().

browser.setLocation

Viene utilizzato per passare a un'altra pagina utilizzando la navigazione in-page.

Example

browser.get('url/ABC');
browser.setLocation('DEF');
expect(browser.getCurrentUrl())
   .toBe('url/DEF');

Navigherà dalla pagina ABC alla pagina DEF.

browser.debugger

Come suggerisce il nome, deve essere utilizzato con il debug del goniometro. Questa funzione fondamentalmente aggiunge un'attività al flusso di controllo per mettere in pausa il test e inserire le funzioni di supporto nel browser in modo che il debug possa essere eseguito nella console del browser.

browser.pause

Viene utilizzato per il debug dei test WebDriver. Possiamo usarebrowser.pause() nel nostro test per entrare nel debugger del goniometro da quel punto nel flusso di controllo.

Example

element(by.id('foo')).click();
browser.pause();
// Execution will stop before the next click action.
element(by.id('bar')).click();

browser.controlFlowEnabled

Viene utilizzato per determinare se il flusso di controllo è abilitato o meno.

Goniometro - Core APIS (CONTD ...)

In questo capitolo, impariamo alcune altre API principali di Protractor.

API Elements

Element è una delle funzioni globali esposte dal goniometro. Questa funzione prende un localizzatore e restituisce quanto segue:

  • ElementFinder, che trova un singolo elemento in base al localizzatore.
  • ElementArrayFinder, che trova un array di elementi in base al localizzatore.

Entrambi i metodi di concatenamento di cui sopra supportano come discusso di seguito.

Funzioni di concatenamento di ElementArrayFinder e relative descrizioni

Le seguenti sono le funzioni di ElementArrayFinder -

element.all(locator).clone

Come suggerisce il nome, questa funzione creerà una copia superficiale dell'array degli elementi, ad esempio ElementArrayFinder.

element.all(locator).all(locator)

Questa funzione sostanzialmente restituisce un nuovo ElementArrayFinder che potrebbe essere vuoto o contenere gli elementi figli. Può essere utilizzato per selezionare più elementi come un array come segue

Example

element.all(locator).all(locator)
elementArr.all(by.css(‘.childselector’));
// it will return another ElementFindArray as child element based on child locator.

element.all(locator).filter(filterFn)

Come suggerisce il nome, dopo aver applicato la funzione di filtro a ciascun elemento all'interno di ElementArrayFinder, restituisce un nuovo ElementArrayFinder con tutti gli elementi che passano la funzione di filtro. Fondamentalmente ha due argomenti, il primo è ElementFinder e il secondo è indice. Può essere utilizzato anche negli oggetti della pagina.

Example

View

<ul class = "items">
   <li class = "one">First</li>
   <li class = "two">Second</li>
   <li class = "three">Third</li>
</ul>

Code

element.all(by.css('.items li')).filter(function(elem, index) {
   return elem.getText().then(function(text) {
      return text === 'Third';
   });
}).first().click();

element.all(locator).get(index)

Con l'aiuto di questo, possiamo ottenere un elemento all'interno di ElementArrayFinder per indice. Notare che l'indice inizia da 0 e gli indici negativi sono avvolti.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let list = element.all(by.css('.items li'));
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');

element.all(locator).first()

Come suggerisce il nome, questo otterrà il primo elemento per ElementArrayFinder. Non recupererà l'elemento sottostante.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let first = element.all(by.css('.items li')).first();
expect(first.getText()).toBe('First');

element.all(locator).last()

Come suggerisce il nome, questo otterrà l'ultimo elemento per ElementArrayFinder. Non recupererà l'elemento sottostante.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let first = element.all(by.css('.items li')).last();
expect(last.getText()).toBe('Third');

element.all(locator).all(selector)

Viene utilizzato per trovare un array di elementi all'interno di un genitore quando le chiamate a $$ possono essere concatenate.

Example

View

<div class = "parent">
   <ul>
      <li class = "one">First</li>
      <li class = "two">Second</li>
      <li class = "three">Third</li>
   </ul>
</div>

Code

let items = element(by.css('.parent')).$$('li');

element.all(locator).count()

Come suggerisce il nome, questo conterà il numero di elementi rappresentati da ElementArrayFinder. Non recupererà l'elemento sottostante.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let list = element.all(by.css('.items li'));
expect(list.count()).toBe(3);

element.all(locator).isPresent()

Abbinerà gli elementi con il cercatore. Può restituire vero o falso. Vero, se sono presenti elementi che corrispondono al cercatore e False in caso contrario.

Example

expect($('.item').isPresent()).toBeTruthy();

element.all(locator).locator

Come suggerisce il nome, restituirà il localizzatore più rilevante.

Example

$('#ID1').locator();
// returns by.css('#ID1')
$('#ID1').$('#ID2').locator();
// returns by.css('#ID2')
$$('#ID1').filter(filterFn).get(0).click().locator();
// returns by.css('#ID1')

element.all(locator).then(thenFunction)

Recupererà gli elementi rappresentati da ElementArrayFinder.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

element.all(by.css('.items li')).then(function(arr) {
   expect(arr.length).toEqual(3);
});

element.all(locator).each(eachFunction)

Come suggerisce il nome, chiamerà la funzione di input su ogni ElementFinder rappresentato da ElementArrayFinder.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

element.all(by.css('.items li')).each(function(element, index) {
   // It will print First 0, Second 1 and Third 2.
   element.getText().then(function (text) {
      console.log(index, text);
   });
});

element.all(locator).map(mapFunction)

Come suggerisce il nome, applicherà una funzione map su ogni elemento all'interno di ElementArrayFinder. Ha due argomenti. Il primo sarebbe l'ElementFinder e il secondo sarebbe l'indice.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let items = element.all(by.css('.items li')).map(function(elm, index) {
   return {
      index: index,
      text: elm.getText(),
      class: elm.getAttribute('class')
   };
});
expect(items).toEqual([
   {index: 0, text: 'First', class: 'one'},
   {index: 1, text: 'Second', class: 'two'},
   {index: 2, text: 'Third', class: 'three'}
]);

element.all(locator).reduce(reduceFn)

Come suggerisce il nome, applicherà una funzione di riduzione contro un accumulatore e ogni elemento trovato utilizzando il localizzatore. Questa funzione ridurrà ogni elemento in un unico valore.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let value = element.all(by.css('.items li')).reduce(function(acc, elem) {
   return elem.getText().then(function(text) {
      return acc + text + ' ';
   });
}, '');

expect(value).toEqual('First Second Third ');

element.all(locator).evaluate

Come suggerisce il nome, valuterà l'input indipendentemente dal fatto che rientri o meno nell'ambito degli elementi sottostanti correnti.

Example

View

<span class = "foo">{{letiableInScope}}</span>

Code

let value = 
element.all(by.css('.foo')).evaluate('letiableInScope');

element.all(locator).allowAnimations

Come suggerisce il nome, determinerà se l'animazione è consentita o meno sugli elementi sottostanti correnti.

Example

element(by.css('body')).allowAnimations(false);

Funzioni di concatenamento di ElementFinder e loro descrizioni

Funzioni di concatenamento di ElementFinder e loro descrizioni -

element(locator).clone

Come suggerisce il nome, questa funzione creerà una copia superficiale di ElementFinder.

element(locator).getWebElement()

Restituirà il WebElement rappresentato da questo ElementFinder e verrà generato un errore WebDriver se l'elemento non esiste.

Example

View

<div class="parent">
   some text
</div>

Code

// All the four following expressions are equivalent.
$('.parent').getWebElement();
element(by.css('.parent')).getWebElement();
browser.driver.findElement(by.css('.parent'));
browser.findElement(by.css('.parent'));

element(locator).all(locator)

Troverà una serie di elementi all'interno di un genitore.

Example

View

<div class = "parent">
   <ul>
      <li class = "one">First</li>
      <li class = "two">Second</li>
      <li class = "three">Third</li>
   </ul>
</div>

Code

let items = element(by.css('.parent')).all(by.tagName('li'));

element(locator).element(locator)

Troverà elementi all'interno di un genitore.

Example

View

<div class = "parent">
   <div class = "child">
      Child text
      <div>{{person.phone}}</div>
   </div>
</div>

Code

// Calls Chain 2 element.
let child = element(by.css('.parent')).
   element(by.css('.child'));
expect(child.getText()).toBe('Child text\n981-000-568');

// Calls Chain 3 element.
let triple = element(by.css('.parent')).
   element(by.css('.child')).
   element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');

element(locator).all(selector)

Troverà un array di elementi all'interno di un genitore quando le chiamate a $$ possono essere concatenate.

Example

View

<div class = "parent">
   <ul>
      <li class = "one">First</li>
      <li class = "two">Second</li>
      <li class = "three">Third</li>
   </ul>
</div>

Code

let items = element(by.css('.parent')).$$('li'));

element(locator).$(locator)

Troverà elementi all'interno di un genitore quando le chiamate a $ possono essere concatenate.

Example

View

<div class = "parent">
   <div class = "child">
      Child text
      <div>{{person.phone}}</div>
  </div>
</div>

Code

// Calls Chain 2 element.
let child = element(by.css('.parent')).
   $('.child')); expect(child.getText()).toBe('Child text\n981-000-568'); // Calls Chain 3 element. let triple = element(by.css('.parent')). $('.child')).
   element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');

element(locator).isPresent()

Determinerà se l'elemento è presentato sulla pagina o meno.

Example

View

<span>{{person.name}}</span>

Code

expect(element(by.binding('person.name')).isPresent()).toBe(true);
// will check for the existence of element

expect(element(by.binding('notPresent')).isPresent()).toBe(false); 
// will check for the non-existence of element

element(locator).isElementPresent()

È uguale a element (locator) .isPresent (). L'unica differenza è che controllerà se l'elemento identificato da sublocator è presente piuttosto che il cercatore di elementi corrente.

element.all(locator).evaluate

Come suggerisce il nome, valuterà l'input indipendentemente dal fatto che rientri o meno nell'ambito degli elementi sottostanti correnti.

Example

View

<span id = "foo">{{letiableInScope}}</span>

Code

let value = element(by.id('.foo')).evaluate('letiableInScope');

element(locator).allowAnimations

Come suggerisce il nome, determinerà se l'animazione è consentita o meno sugli elementi sottostanti correnti.

Example

element(by.css('body')).allowAnimations(false);

element(locator).equals

Come suggerisce il nome, confronterà un elemento per l'uguaglianza.

Localizzatori (di) API

È fondamentalmente una raccolta di strategie di localizzazione di elementi che fornisce modi per trovare elementi nelle applicazioni angolari mediante associazione, modello ecc.

Functions and their descriptions

Le funzioni dell'API di ProtractorLocators sono le seguenti:

by.addLocator(locatorName,fuctionOrScript)

Aggiungerà un localizzatore a questa istanza di ProtrcatorBy che può essere ulteriormente utilizzato con element (by.locatorName (args)).

Example

View

<button ng-click = "doAddition()">Go!</button>

Code

// Adding the custom locator.
by.addLocator('buttonTextSimple',
      function(buttonText, opt_parentElement, opt_rootSelector) {

      var using = opt_parentElement || document,
         buttons = using.querySelectorAll('button');

      return Array.prototype.filter.call(buttons, function(button) {
      return button.textContent === buttonText;
   });
});
element(by.buttonTextSimple('Go!')).click();// Using the custom locator.

by.binding

Come suggerisce il nome, troverà un elemento per associazione di testo. Verrà eseguita una corrispondenza parziale in modo che vengano restituiti tutti gli elementi associati alle variabili contenenti la stringa di input.

Example

View

<span>{{person.name}}</span>
<span ng-bind = "person.email"></span>

Code

var span1 = element(by.binding('person.name'));
expect(span1.getText()).toBe('Foo');

var span2 = element(by.binding('person.email'));
expect(span2.getText()).toBe('[email protected]');

by.exactbinding

Come suggerisce il nome, troverà un elemento per associazione esatta.

Example

View

<spangt;{{ person.name }}</spangt;
<span ng-bind = "person-email"gt;</spangt;
<spangt;{{person_phone|uppercase}}</span>

Code

expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);

by.model(modelName)

Come suggerisce il nome, troverà un elemento mediante l'espressione ng-model.

Example

View

<input type = "text" ng-model = "person.name">

Code

var input = element(by.model('person.name'));
input.sendKeys('123');
expect(input.getAttribute('value')).toBe('Foo123');

by.buttonText

Come suggerisce il nome, troverà un pulsante per testo.

Example

View

<button>Save</button>

Code

element(by.buttonText('Save'));

by.partialButtonText

Come suggerisce il nome, troverà un pulsante per testo parziale.

Example

View

<button>Save my file</button>

Code

element(by.partialButtonText('Save'));

by.repeater

Come suggerisce il nome, troverà un elemento all'interno di una ripetizione ng.

Example

View

<div ng-repeat = "cat in pets">
   <span>{{cat.name}}</span>
   <span>{{cat.age}}</span>
<</div>
<div class = "book-img" ng-repeat-start="book in library">
   <span>{{$index}}</span>
</div>
<div class = "book-info" ng-repeat-end>
   <h4>{{book.name}}</h4>
   <p>{{book.blurb}}</p>
</div>

Code

var secondCat = element(by.repeater('cat in 
pets').row(1)); // It will return the DIV for the second cat.
var firstCatName = element(by.repeater('cat in pets').
   row(0).column('cat.name')); // It will return the SPAN for the first cat's name.

by.exactRepeater

Come suggerisce il nome, troverà un elemento per ripetitore esatto.

Example

View

<li ng-repeat = "person in peopleWithRedHair"></li>
<li ng-repeat = "car in cars | orderBy:year"></li>

Code

expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
   .toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);

by.cssContainingText

Come suggerisce il nome, troverà gli elementi, contenenti la stringa esatta, tramite CSS

Example

View

<ul>
<li class = "pet">Dog</li>
<li class = "pet">Cat</li>
</ul>

Code

var dog = element(by.cssContainingText('.pet', 'Dog')); 
// It will return the li for the dog, but not for the cat.

by.options(optionsDescriptor)

Come suggerisce il nome, troverà un elemento tramite l'espressione ng-options.

Example

View

<select ng-model = "color" ng-options = "c for c in colors">
   <option value = "0" selected = "selected">red</option>
   <option value = "1">green</option>
</select>

Code

var allOptions = element.all(by.options('c for c in colors'));
expect(allOptions.count()).toEqual(2);
var firstOption = allOptions.first();
expect(firstOption.getText()).toEqual('red');

by.deepCSS(selector)

Come suggerisce il nome, troverà un elemento dal selettore CSS all'interno del DOM ombra.

Example

View

<div>
   <span id = "outerspan">
      <"shadow tree">
         <span id = "span1"></span>
      <"shadow tree">
      <span id = "span2"></span>
   </>
   </>
</div>

Code

var spans = element.all(by.deepCss('span'));
expect(spans.count()).toEqual(3);

Goniometro - Oggetti

Questo capitolo discute in dettaglio sugli oggetti in Goniometro.

Cosa sono gli oggetti pagina?

L'oggetto Page è un modello di progettazione diventato popolare per la scrittura di test e2e al fine di migliorare la manutenzione dei test e ridurre la duplicazione del codice. Può essere definita come una classe orientata agli oggetti che funge da interfaccia per una pagina del tuo AUT (applicazione sotto test). Ma, prima di immergerci in profondità negli oggetti della pagina, dobbiamo comprendere le sfide con i test automatizzati dell'interfaccia utente e i modi per gestirli.

Sfide con i test automatizzati dell'interfaccia utente

Di seguito sono riportate alcune sfide comuni con i test automatizzati dell'interfaccia utente:

Modifiche all'interfaccia utente

I problemi molto comuni durante il lavoro con i test dell'interfaccia utente sono i cambiamenti che avvengono nell'interfaccia utente. Ad esempio, la maggior parte delle volte accade che pulsanti o caselle di testo ecc. Di solito vengano modificati e creino problemi per i test dell'interfaccia utente.

Mancanza di supporto DSL (Domain Specific Language)

Un altro problema con i test dell'interfaccia utente è la mancanza di supporto DSL. Con questo problema, diventa molto difficile capire cosa viene testato.

Molte ripetizioni / duplicazione del codice

Il prossimo problema comune nei test dell'interfaccia utente è che ci sono molte ripetizioni o duplicazioni di codice. Può essere compreso con l'aiuto delle seguenti righe di codice:

element(by.model(‘event.name’)).sendKeys(‘An Event’);
element(by.model(‘event.name’)).sendKeys(‘Module 3’);
element(by.model(‘event.name’));

Manutenzione difficile

A causa delle sfide di cui sopra, diventa mal di testa per la manutenzione. È perché dobbiamo trovare tutte le istanze, sostituirle con il nuovo nome, selettore e altro codice. Abbiamo anche bisogno di dedicare molto tempo per mantenere i test in linea con il refactoring.

Test interrotti

Un'altra sfida nei test dell'interfaccia utente è il verificarsi di molti errori nei test.

Modi per gestire le sfide

Abbiamo visto alcune sfide comuni del test dell'interfaccia utente. Alcuni dei modi per gestire tali sfide sono i seguenti:

Aggiornamento manuale dei riferimenti

La prima opzione per gestire le sfide di cui sopra è aggiornare i riferimenti manualmente. Il problema con questa opzione è che dobbiamo fare la modifica manuale del codice così come i nostri test. Questo può essere fatto quando hai uno o due file di test, ma cosa succede se hai centinaia di file di test in un progetto?

Utilizzo di oggetti pagina

Un'altra opzione per gestire le sfide di cui sopra è utilizzare gli oggetti della pagina. Un oggetto pagina è fondamentalmente un semplice JavaScript che incapsula le proprietà di un modello angolare. Ad esempio, il seguente file di specifica viene scritto senza e con gli oggetti pagina per comprendere la differenza:

Without Page Objects

describe('angularjs homepage', function() {
   it('should greet the named user', function() {
      browser.get('http://www.angularjs.org');
      element(by.model('yourName')).sendKeys('Julie');
      var greeting = element(by.binding('yourName'));
      expect(greeting.getText()).toEqual('Hello Julie!');
   });
});

With Page Objects

Per scrivere il codice con gli oggetti pagina, la prima cosa che dobbiamo fare è creare un oggetto pagina. Quindi, un oggetto pagina per l'esempio precedente potrebbe essere simile a questo:

var AngularHomepage = function() {
   var nameInput = element(by.model('yourName'));
   var greeting = element(by.binding('yourName'));

   this.get = function() {
      browser.get('http://www.angularjs.org');
   };

   this.setName = function(name) {
      nameInput.sendKeys(name);
   };
   
   this.getGreetingText = function() {
      return greeting.getText();
   };
};
module.exports = new AngularHomepage();

Utilizzo di oggetti pagina per organizzare i test

Abbiamo visto l'uso di oggetti pagina nell'esempio precedente per gestire le sfide del test dell'interfaccia utente. Successivamente, discuteremo di come utilizzarli per organizzare i test. Per questo è necessario modificare lo script di test senza modificare la funzionalità dello script di test.

Esempio

Per comprendere questo concetto stiamo prendendo il file di configurazione sopra con oggetti di pagina. Dobbiamo modificare lo script di test come segue:

var angularHomepage = require('./AngularHomepage');
describe('angularjs homepage', function() {
   it('should greet the named user', function() {
      angularHomepage.get();

      angularHomepage.setName('Julie');
   
      expect(angularHomepage.getGreetingText()).toEqual
      ('Hello Julie!');
   });
});

Tieni presente che il percorso dell'oggetto pagina sarà relativo alla tua specifica.

Sulla stessa nota, possiamo anche separare la nostra suite di test in varie suite di test. Il file di configurazione può quindi essere modificato come segue

exports.config = {
   // The address of a running selenium server.
   seleniumAddress: 'http://localhost:4444/wd/hub',

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },
   // Spec patterns are relative to the location of the spec file. They may
   // include glob patterns.
   suites: {
      homepage: 'tests/e2e/homepage/**/*Spec.js',
      search: ['tests/e2e/contact_search/**/*Spec.js',
         'tests/e2e/venue_search/**/*Spec.js']
   },

   // Options to be passed to Jasmine-node.
   jasmineNodeOpts: {
      showColors: true, // Use colors in the command line report.
   }
};

Ora possiamo facilmente passare dall'esecuzione dell'una all'altra suite di test. Il seguente comando eseguirà solo la sezione della homepage del test:

protractor protractor.conf.js --suite homepage

Allo stesso modo, possiamo eseguire specifiche suite di test con il comando come segue:

protractor protractor.conf.js --suite homepage,search

Goniometro - Debug

Ora che abbiamo visto tutti i concetti di Goniometro nei capitoli precedenti, comprendiamo in dettaglio i concetti di debug in questo capitolo.

introduzione

I test end-to-end (e2e) sono molto difficili da eseguire il debug perché dipendono dall'intero ecosistema di tale applicazione. Abbiamo visto che dipendono da varie azioni o in particolare possiamo dire che da azioni precedenti come il login e talvolta dipendono dall'autorizzazione. Un'altra difficoltà nel debug dei test e2e è la sua dipendenza da WebDriver perché agisce in modo diverso con diversi sistemi operativi e browser. Infine, il debug dei test e2e genera anche lunghi messaggi di errore e rende difficile separare i problemi relativi al browser e gli errori del processo di test.

Tipi di fallimento

Ci possono essere vari motivi per il fallimento delle suite di test e di seguito sono riportati alcuni tipi di errore ben noti:

Errore WebDriver

Quando un comando non può essere completato, WebDriver genera un errore. Ad esempio, un browser non può ottenere l'indirizzo definito o un elemento non viene trovato come previsto.

Errore imprevisto di WebDriver

Un browser imprevisto e un errore relativo al sistema operativo si verifica quando non riesce ad aggiornare il gestore dei driver web.

Rottura del goniometro per angolare

Il fallimento di Goniometro per Angular si verifica quando Goniometro non ha trovato Angular nella libreria come previsto.

Guasto angolare2 del goniometro

In questo tipo di errore, Protractor fallirà quando il parametro useAllAngular2AppRoots non viene trovato nella configurazione. Succede perché, senza questo, il processo di test esaminerà un singolo elemento radice mentre si aspetta più di un elemento nel processo.

Guasto del goniometro per timeout

Questo tipo di errore si verifica quando la specifica del test raggiunge un ciclo o un pool lungo e non riesce a restituire i dati in tempo.

Fallimento delle aspettative

Uno degli errori di test più comuni che mostra l'aspetto di un normale errore di aspettativa.

Perché il debug è importante in Goniometro?

Supponiamo, se hai scritto casi di test e hanno fallito, è molto importante sapere come eseguire il debug di questi casi di test perché sarebbe molto difficile trovare il punto esatto in cui si è verificato l'errore. Mentre lavori con Goniometro, otterrai alcuni errori lunghi con caratteri di colore rosso nella riga di comando.

Pausa e debug del test

I modi per eseguire il debug in Protractor sono spiegati qui & miuns;

Metodo di pausa

L'uso del metodo pause per eseguire il debug dei casi di test in Goniometro è uno dei modi più semplici. Possiamo digitare il seguente comando nel punto in cui vogliamo mettere in pausa il nostro codice di prova & miuns;

browser.pause();

Quando i codici in esecuzione premono il comando precedente, interromperà il programma in esecuzione a quel punto. Dopodiché possiamo dare i seguenti comandi in base alle nostre preferenze:

Digita C per andare avanti

Ogni volta che un comando è esaurito, dobbiamo digitare C per andare avanti. Se non digiti C, il test non eseguirà il codice completo e fallirà a causa dell'errore di timeout di Jasmine.

Digitare repl per accedere alla modalità interattiva

Il vantaggio della modalità interattiva è che possiamo inviare i comandi WebDriver al nostro browser. Se vogliamo entrare nella modalità interattiva, digitarepl.

Digita Ctrl-C per uscire e continuare i test

Per uscire dal test dallo stato di pausa e continuare il test dal punto in cui è stato interrotto, è necessario digitare Ctrl-C.

Esempio

In questo esempio, abbiamo il file delle specifiche di seguito denominato example_debug.js, goniometro cerca di identificare un elemento con locator by.binding('mmmm') ma l'URL (https://angularjs.org/ la pagina non ha elementi con l'indicatore di posizione specificato.

describe('Suite for protractor debugger',function(){
   it('Failing spec',function(){
      browser.get("http://angularjs.org");
      element(by.model('yourName')).sendKeys('Vijay');
         //Element doesn't exist
         var welcomeText = 
         element(by.binding('mmmm')).getText();
         expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
   });
});

Ora, per eseguire il test sopra, dobbiamo aggiungere il codice browser.pause (), dove vuoi mettere in pausa il test, nel file delle specifiche sopra. Apparirà come segue:

describe('Suite for protractor debugger',function(){
   it('Failing spec',function(){
      browser.get("http://angularjs.org");
      browser.pause();
      element(by.model('yourName')).sendKeys('Vijay');
      //Element doesn't exist
      var welcomeText = 
      element(by.binding('mmmm')).getText();
      expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
   });
});

Ma prima di eseguire, è necessario apportare anche alcune modifiche al file di configurazione. Stiamo apportando le seguenti modifiche nel file di configurazione utilizzato in precedenza, denominatoexample_configuration.js nel capitolo precedente -

// An example configuration file.
exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

   // Spec patterns are relative to the current working directory when

   // protractor is called.
   specs: ['example_debug.js'],
      allScriptsTimeout: 999999,
      jasmineNodeOpts: {
      defaultTimeoutInterval: 999999
   },
   onPrepare: function () {
      browser.manage().window().maximize();
      browser.manage().timeouts().implicitlyWait(5000);
   }
};

Ora, esegui il seguente comando:

protractor example_configuration.js

Il debugger verrà avviato dopo il comando precedente.

Metodo debugger

L'uso del metodo pause per eseguire il debug dei casi di test in Goniometro è un modo un po 'avanzato. Possiamo digitare il seguente comando nel punto in cui vogliamo interrompere il nostro codice di test:

browser.debugger();

Utilizza il debugger del nodo per eseguire il debug del codice di test. Per eseguire il comando precedente, dobbiamo digitare il seguente comando in un prompt dei comandi separato che è stato aperto dalla posizione del progetto di prova -

protractor debug protractor.conf.js

In questo metodo, dobbiamo anche digitare C nel terminale per continuare il codice di test. Ma a differenza del metodo pause, in questo metodo deve essere digitato solo una volta.

Esempio

In questo esempio, stiamo usando lo stesso file di specifiche denominato bexample_debug.js, usato sopra. L'unica differenza è che invece dibrowser.pause(), dobbiamo usare browser.debugger()dove vogliamo rompere il codice di test. Apparirà come segue:

describe('Suite for protractor debugger',function(){
   it('Failing spec',function(){
      browser.get("http://angularjs.org");
      browser.debugger();
      element(by.model('yourName')).sendKeys('Vijay');
      //Element doesn't exist
      var welcomeText = element(by.binding('mmmm')).getText();
      expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
   });
});

Stiamo usando lo stesso file di configurazione, example_configuration.js, utilizzato nell'esempio precedente.

Ora, esegui il test del goniometro con la seguente opzione della riga di comando di debug

protractor debug example_configuration.js

Il debugger verrà avviato dopo il comando precedente.

Goniometro - Guida allo stile per goniometro

In questo capitolo, impariamo in dettaglio la guida di stile per il goniometro.

introduzione

La guida allo stile è stata creata da due ingegneri del software denominati, Carmen Popoviciu, ingegnere front-end presso ING e Andres Dominguez, software engineer presso Google. Quindi, questa guida di stile è anche chiamata Carmen Popoviciu e la guida di stile di Google per il goniometro.

Questa guida di stile può essere suddivisa nei seguenti cinque punti chiave:

  • Regole generiche
  • Struttura del progetto
  • Strategie di localizzazione
  • Oggetti pagina
  • Suite di test

Regole generiche

Di seguito sono riportate alcune regole generiche che devono essere prese in considerazione durante l'utilizzo del goniometro per i test:

Non testare end-to-end ciò che è già stato testato in unità

Questa è la primissima regola generica data da Carmen e Andres. Hanno suggerito che non dobbiamo eseguire il test e2e sul codice che è già stato unit test. La ragione principale è che i test unitari sono molto più veloci dei test e2e. Un altro motivo è che dobbiamo evitare i test duplicati (non eseguire test sia unitari che e2e) per risparmiare tempo.

Utilizza un solo file di configurazione

Un altro punto importante consigliato è che dobbiamo utilizzare un solo file di configurazione. Non creare file di configurazione per ogni ambiente che stai testando. Puoi usaregrunt-protractor-coverage per allestire ambienti diversi.

Evita di usare la logica per il tuo test

Dobbiamo evitare di usare istruzioni IF o cicli FOR nei nostri casi di test, perché se lo facciamo, il test potrebbe passare senza testare nulla o potrebbe essere eseguito molto lentamente.

Rendi il test indipendente a livello di file

Goniometro può eseguire il test parallelamente quando la condivisione è abilitata. Questi file vengono quindi eseguiti su browser diversi non appena diventano disponibili. Carmen e Andres consigliano di rendere il test indipendente almeno a livello di file perché l'ordine in cui verranno eseguiti dal goniometro è incerto ed inoltre è abbastanza facile eseguire un test in isolamento.

Struttura del progetto

Un altro punto chiave importante per quanto riguarda la guida allo stile di Goniometro è la struttura del tuo progetto. Quanto segue è la raccomandazione sulla struttura del progetto:

Tentare e2e test in una struttura sensibile

Carmen e Andres ci hanno consigliato di raggruppare i nostri test e2e in una struttura che abbia senso per la struttura del tuo progetto. Il motivo alla base di questa raccomandazione è che la ricerca dei file diventerebbe facile e la struttura delle cartelle sarebbe più leggibile. Questo passaggio separerà anche i test e2e dai test unitari. Hanno raccomandato di evitare il seguente tipo di struttura:

|-- project-folder
   |-- app
      |-- css
      |-- img
      |-- partials
         home.html
         profile.html
         contacts.html
      |-- js
         |-- controllers
         |-- directives
         |-- services
         app.js
         ...
      index.html
   |-- test
      |-- unit
      |-- e2e
         home-page.js
         home-spec.js
         profile-page.js
         profile-spec.js
         contacts-page.js
         contacts-spec.js

D'altra parte, hanno raccomandato il seguente tipo di struttura:

|-- project-folder
   |-- app
      |-- css
      |-- img
      |-- partials
         home.html
         profile.html
         contacts.html
      |-- js
         |-- controllers
         |-- directives
         |-- services
         app.js
         ...
      index.html
   |-- test
      |-- unit
      |-- e2e
         |-- page-objects
            home-page.js
            profile-page.js
            contacts-page.js
         home-spec.js
         profile-spec.js
         contacts-spec.js

Strategie di localizzazione

Di seguito sono riportate alcune strategie di localizzazione che devono essere prese con cura durante l'utilizzo del goniometro per i test:

Non utilizzare mai XPATH

Questa è la prima strategia di localizzazione consigliata nella guida allo stile del goniometro. Le ragioni alla base dello stesso è che XPath richiede molta manutenzione perché il markup è molto facilmente soggetto a modifiche. Inoltre, le espressioni XPath sono le più lente e molto difficili da eseguire il debug.

Preferisci sempre localizzatori specifici per goniometro come by.model e by.binding

I localizzatori specifici del goniometro come by.model e by.binding sono brevi, specifici e di facile lettura. Con l'aiuto di loro è molto facile scrivere anche il nostro localizzatore.

Esempio

View

<ul class = "red">
   <li>{{color.name}}</li>
   <li>{{color.shade}}</li>
   <li>{{color.code}}</li>
</ul>

<div class = "details">
   <div class = "personal">
      <input ng-model = "person.name">
   </div>
</div>

Per il codice sopra, si consiglia di evitare quanto segue:

var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));

D'altra parte, si consiglia di utilizzare:

var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
var nameElement = element(by.binding('color.name'));
var personName = element(by.model('person.name'));

Quando non sono disponibili localizzatori di goniometro, si consiglia di preferire by.id e by.css.

Evita sempre i localizzatori di testo per cambiare testo frequentemente

Dobbiamo evitare i localizzatori basati su testo come by.linkText, by.buttonText e by.cssContaningText perché il testo per pulsanti, link ed etichette cambia frequentemente nel tempo.

Oggetti pagina

Come discusso in precedenza, gli oggetti pagina incapsulano le informazioni sugli elementi nella nostra pagina dell'applicazione e grazie a questo ci aiutano a scrivere casi di test più puliti. Un vantaggio molto utile degli oggetti pagina è che possono essere riutilizzati in più test e nel caso in cui il modello della nostra applicazione sia stato modificato, dobbiamo solo aggiornare l'oggetto pagina. Di seguito sono riportati alcuni consigli per gli oggetti della pagina che devono essere curati durante l'utilizzo del goniometro per i test:

Per interagire con la pagina sotto test, utilizzare gli oggetti pagina

Si consiglia di utilizzare gli oggetti della pagina per interagire con la pagina sottoposta a test perché possono incapsulare informazioni sull'elemento nella pagina sottoposta a test e possono anche essere riutilizzati.

Dichiara sempre l'oggetto di una pagina per file

Dovremmo definire ogni oggetto della pagina nel proprio file perché mantiene il codice pulito e trovare le cose diventa facile.

Alla fine della pagina il file oggetto utilizza sempre un singolo module.exports

Si consiglia che ogni oggetto della pagina dichiari una singola classe in modo che sia necessario esportare solo una classe. Ad esempio, il seguente utilizzo del file oggetto dovrebbe essere evitato:

var UserProfilePage = function() {};
var UserSettingsPage = function() {};
module.exports = UserPropertiesPage;
module.exports = UserSettingsPage;

Ma d'altra parte, si consiglia di utilizzare:

/** @constructor */
var UserPropertiesPage = function() {};

module.exports = UserPropertiesPage;

Dichiara tutti i moduli richiesti in alto

Dovremmo dichiarare tutti i moduli richiesti nella parte superiore dell'oggetto della pagina perché rende le dipendenze dei moduli chiare e facili da trovare.

Crea un'istanza di tutti gli oggetti della pagina all'inizio della suite di test

Si consiglia di istanziare tutti gli oggetti della pagina all'inizio della suite di test perché questo separerà le dipendenze dal codice di test e renderà le dipendenze disponibili per tutte le specifiche della suite.

Non utilizzare wait () negli oggetti della pagina

Non dovremmo usare wait () negli oggetti della pagina, cioè non dovremmo fare alcuna asserzione nei nostri oggetti della pagina perché tutte le asserzioni devono essere fatte nei casi di test.

Un altro motivo è che il lettore del test dovrebbe essere in grado di comprendere il comportamento dell'applicazione leggendo solo i casi di test.