Corso - TEST AUTOMATION-Appunti.pdf
Document Details
Uploaded by LovedZombie
Tags
Full Transcript
Appunti del Corso TEST AUTOMATION JAVA È un linguaggio di programmazione ad alto livello, fortemente tipizzato, orientato agli oggetti e compilato in bytecode prima e interpretato poi da...
Appunti del Corso TEST AUTOMATION JAVA È un linguaggio di programmazione ad alto livello, fortemente tipizzato, orientato agli oggetti e compilato in bytecode prima e interpretato poi da parte di una JVM (Java Virtual Machine). Codice JAVAC Byte Code JVM → → JAVA compilato da Compiler in Linguaggio → Semi-Compilato Diversa per ogni interpretato da Sistema Operativo Le versioni principali di Java sono 2: SE (Standard Edition): permette di creare Applicazioni Desktop; EE (Enterprise Edition): permette di creare Applicazioni Web e Distribuite. VARIABILI Servono per conservare le informazioni in memoria. byte: numero intero, occupa 1 byte (da -128 a 127); short: numero intero, occupa 2 byte (da -32768 a 32767); int: numero intero, occupa 4 byte (da -2147483648 a 2147483647); long: numero intero, occupa 8 byte (da -9223372036854775808 a 9223372036854775807); float: numero decimale (virgola mobile), occupa 4 byte (±3.40282347e+38); double: numero decimale, occupa 8 byte (±1.79769313486231570e+308); boolean: valore logico (true o false / 0 o 1) , occupa 1 bit; char: carattere (Unicode), occupa in memoria 2 byte (0 – 65535); Le variabili alfanumeriche (stringhe) non sono dati primitivi ma oggetti wrapper e si dichiarano con il tipo String. CLASSI WRAPPER Permettono di istanziare oggetti che corrispondono ad un tipo di dato primitivo. Questo tipo di oggetti, oltre a permettere la memorizzazione del valore assegnato, offrono anche diversi metodi di utilità (come equals o contains per la comparazione di stringhe). Tutte le classi wrapper hanno un metodo statico per convertire una variabile nel tipo di dato wrapper. Integer.parseInt(s) OPERAZIONI Se si effettuano operazioni con diversi tipi di dichiarazioni di numeri, queste restituiranno come risultato il tipo più preciso: int + int = int int + float = float int + double = double float + double = double Quando si scrive una operazione, si può indicare anche il tipo di dato del risultato, tra parentesi tonde. Questa operazione si chiama CAST. DICHIARAZIONE E FIRMA DEL METODO La dichiarazione di un metodo è composta dal modificatore di accesso – tipo di ritorno – nome del metodo e tipi di parametri passati. La firma è composta invece solo dal nome del metodo e i tipi passati come parametro, quest’ultima è fondamentale nell’ Overloading. OOP (Object-Oriented Programming) La Programmazione Orientata agli Oggetti è un paradigma (modello) di programmazione di "astrazione della realtà", poiché utilizza classi (composte da attributi e metodi) per istanziare oggetti che rappresentano entità del mondo reale o concetti astratti. È tenuta a rispettare 3 principi fondamentali: 1. Incapsulamento: serve per limitare l'accesso agli elementi dell'oggetto. Esistono 4 modificatori di accesso utilizzati per definire l'accessibilità degli attributi o dei metodi delle classi: public: visibile da qualsiasi classe; private: visibile solo all'interno della classe; protected: visibile solo all'interno della classe e delle sue sottoclassi; default:visibile da qualsiasi classe all'interno del pacchetto. Da Java 9 è stata introdotta anche la parola chiave "module", che limita la visibilità a moduli specifici. 2. Ereditarietà Creazione di nuove classi che riutilizzano, estendono e/o modificano il comportamento definito in altre classi (madri). Avviene con il richiamo del metodo super() all'interno del costruttore e con la parola chiave extends. 3. Polimorfismo: rende la programmazione più semplice poiché implica la capacità di un oggetto di assumere più forme. Polimorfismo dei Metodi: ○ Overload: parametri diversi (per tipo) distinguono metodi diversi (solo se creati dall'utente) / la firma (nome + tipi dei parametri) distingue i metodi; ○ Override: sovrascrittura di un metodo (solo se ereditato). Polimorfismo degli Oggetti: ○ Per Ereditarietà: classe Dipendente figlia della classe Persona; ○ Per Implementazione della Stessa Interfaccia: classi ArrayList e LinkedList figlie di List, a sua volta figlia di Collection. Metodi Comuni Il Costruttore è un metodo speciale con lo stesso nome della classe e senza tipo di ritorno che serve per inizializzare gli attributi dell'oggetto; Il Distruttore è un metodo speciale che viene invocato automaticamente quando l'oggetto viene distrutto (non ha più riferimenti attivi). In JAVA è invocato automaticamente dal Garbage Collector. Per Garbage Collection (Raccolta dei Rifiuti) si intende una modalità automatica di gestione della memoria, mediante la quale si liberano le porzioni di memoria che non dovranno più essere successivamente utilizzate dalle applicazioni; I Setter e i Getter vengono usati per modificare o ottenere i dati in maniera "protetta". Errori Comuni Oggetto Dipendente con metodi e attributi SOLO di Persona. Persona p = new Dipendente(); Per renderlo Dipendente a tutti gli effetti basterebbe fare un CAST. CAST breve: ((Dipendente) p); CAST "normale": Dipendente d = (Dipendente) p; Dipendente d = new Persona(); Non si può fare, poiché Dipendente è figlio di Persona. TIPI DI METODI Statici: non legati all'istanza della classe (oggetto); Lab.verificaPari(); Dinamici: legati all'istanza della classe (oggetto) Lab lab = new Lab(); lab.verificapari(); FINAL Per una variabile: costante (valore immutabile); Per un metodo: overriding impossibile (metodo immutabile); Per una classe: ereditarietà impossibile (metodo immutabile). STATIC Per una variabile: unico riferimento in memoria (non verrà mai re-inizializzata automaticamente); Per un metodo: appartiene a una classe piuttosto che a un'istanza di una classe (che non può richiamare metodi statici); Per una classe: può accedere solo a variabili e metodi statici. È impossibile utilizzare static con una classe, a meno che non sia una classe interna. INTERFACCIA Comprende la dichiarazione di variabili costanti e metodi astratti (non implementati): public interface InterfacciaAutomobile { public void vernicia(); } È implementabile più volte (una classe può implementare più interfacce contemporaneamente, cosa che l'ereditarietà di classi non può fare). Non è possibile istanziare oggetti. CLASSE ASTRATTA È una classe che oltre agli attributi, i metodi ed i costruttori, contiene anche metodi astratti: public abstract class Automobile { } Le classi figlie devono obbligatoriamente implementare i metodi astratti. Può estendere anche l'interfaccia. Non è possibile istanziare oggetti. CLASSE SINGLETON È classe con un costruttore privato: questo garantisce l'esistenza di una sola istanza. public class TestSingleton { private static TestSingleton istanza = null; private TestSingleton() { } Crea un'istanza (se non esiste) o ritorna quella esistente. public static synchronized TestSingleton getIstanza() { if(istanza == null) { istanza = new TestSingleton(); } return istanza; } } ECCEZIONI È possibile creare delle eccezioni personalizzate. public class PrenotazioneException extends Exception { public PrenotazioneException() { super("Problema con la prenotazione"); } public String toString() { return getMessage() + ": posti esauriti!"; } } Ecco come si tratta poi nel try-catch della funzione stessa (Prenota): try { if(postiDisponibili == 0) { Lancio dell'eccezione. throw new PrenotazioneException(); } L'istruzione viene eseguita solo se non viene lanciata l'eccezione. postiDisponibili--; } catch (PrenotazioneException e) { System.out.println(e.toString()); } È possibile trattare le eccezioni anche con la parola chiave throws (accompagnata poi dal nome dell'eccezione) che avverte il compilatore che siamo consapevoli che il metodo possa lanciare l'eccezione e di non preoccuparsi, perché la gestiremo in un'altra parte del codice. NOVITÀ JAVA 8 Rispetto alle versioni precedenti introduce le espressioni lambda e delle nuove funzionalità di programmazione. Le espressioni lambda sono una sintassi concisa per definire funzioni ANONIME (definite nel corpo della dichiarazione di un oggetto). FUNZIONE SENZA LAMBDA public int somma(int a, int b) { return a + b; } FUNZIONE CON LAMBDA Si istanzia un oggetto di tipo operazione (addizione) e si implementa il metodo somma (vedi sopra). Operazione addizione = (a, b) -> a + b; Le Stream API semplificano la manipolazione e la trasformazione dei dati, consentendo operazioni come il filtraggio, la mappatura, la riduzione e l'ordinamento su sequenze di elementi. COLLECTION Java Collection Framework è la libreria che contiene le interfacce e le classi per gestire collezioni di oggetti. Gerarchia Java Collection Framework. ArrayList: array dinamico. Non accetta tipi primitivi. private ArrayList arrayList = new ArrayList(); LinkedList: array dinamico con metodi in più (addFirst() o addLast()). LinkedList linkedList = new LinkedList(); HashSet: array dinamico di oggetti univoci (non duplicati, non va in errore ma bypassa l'operazione), gli oggetti non hanno un ordine. HashSet hashSet = new HashSet(); HashMap: dizionari (si definisce TIPO INDICE, TIPO VALORE). Non si usa il foreach ma il formap (elementi univoci). HashMap hashMap = new HashMap(); DESIGN PATTERN Si occupano di come comporre le classi e gli oggetti per formare strutture complesse e sono una soluzione progettuale per un problema ricorrente. I pattern creazionali risolvono problematiche inerenti all'istanziazione degli oggetti. I pattern strutturali risolvono problematiche inerenti alla struttura delle classi e degli oggetti. I pattern comportamentali forniscono soluzione alle più comuni tipologie di interazione tra gli oggetti. I pattern architetturali esprimono schemi di base per impostare l'organizzazione strutturale di un sistema software. In questi schemi si descrivono sottosistemi predefiniti insieme con i ruoli che essi assumono e le relazioni reciproche (MVC). MVC (Model-View-Controller) Questo pattern è una soluzione progettuale utilizzata in molti linguaggi di programmazione per separare le responsabilità dell'applicazione in tre componenti principali, quali il modello, la vista e il controller: Model: rappresenta i dati che l'applicazione deve manipolare e gestire (classi); View: rappresenta l'interfaccia utente dell'applicazione, responsabile di mostrare i dati in modo appropriato (metodi di input output); Controller: funge da intermediario tra il modello e la vista. Gestisce gli input dell'utente, trasforma le sue richieste in azioni sul modello e aggiorna la vista (main). L'utilizzo di questo pattern aiuta a mantenere il codice pulito e organizzato, semplifica la manutenzione dell'applicazione e permette di separare la logica di business dalla presentazione dei dati. HTML (HyperText Markup Language) Non è un linguaggio di programmazione, ma è un linguaggio di marcatura (o di markup), ovvero un insieme di regole che descrivono i meccanismi di rappresentazione o impaginazione di un testo, che riceve istruzioni attraverso "tag", con cui si formattano documenti ipertestuali (pagine web). È case insensitive. TAG Sono marcatori o etichette contenute tra parentesi angolari che specificano il ruolo che quel determinato elemento dovrà possedere. Contengono il nome, eventuali attributi e omonimo tag di chiusura. STRUTTURA Si prevede che l'intero documento sia contenuto tra i tag , che si suddivide in 2 aree: Header: porzione della pagina che contiene, tra i tag , il titolo della pagina e tutte le informazioni relative agli script, i collegamenti a fogli di stile (CSS) e i meta-tag (informazioni aggiuntive alla pagina web); Corpo della Pagina: porzione della pagina in cui troviamo, tra i tag tutti il contenuto della pagina. CSS (Cascading Style Sheets) Un foglio di stile permette di separare l'aspetto delle pagine web dal loro contenuto. È una collezione di regole per posizionare, formattare e visualizzare i vari elementi che compongono una pagina web. Esistono tre modi per specificare uno stile: All'interno di elementi HTML con l'attributo style; All'interno del tag ; In un file esterno. JavaScript Ha aggiunto alle pagine HTML la possibilità di essere modificate in modo dinamico, in base all'interazione dell'utente con il browser. Esistono tre modi per inserire codice JavaScript: All'interno di elementi HTML con l'attributo che richiama un evento. onclick="(function(){alert(this);})()" All'interno del tag ; In un file esterno. È case sensitive. A differenza di altri linguaggi di programmazione, in JavaScript terminare un'istruzione con il punto e virgola non è obbligatorio. Ha solo tre tipi di variabili: var: variabile generica, all'occorrenza globale o locale; let: variabile locale; const:variabile locale costante. È dotato di diverse funzioni predefinite: alert("messaggio"): mostra un alert; confirm("messaggio"): mostra una finestra di conferma; prompt("messaggio"): mostra una finestra di dialogo. Prevede l'uso di funzioni function per eseguire un determinato algoritmo. function nomeFunzione(argomenti) { istruzioni; return var; } Per richiamarle all'interno dell'HTML basta associare il nome di un evento alla funzione. onclick="mostralert()" Risalire ad un elemento HTML: con la parola chiave this all'interno dell'HTML; onblur="validaNome(this)" attraverso il document. document.getElementById("id") GIT E GITHUB DIFFERENZA GIT: software per la gestione di progetti; GITHUB: servizio (hosting dei progetti). UTILIZZO In una nuova cartella, dal terminale GitBash: git init: inizializza la cartella per GIT; vi nomefile.estensione: apre l'editor e/o crea file, con i aggiunge testo, con esc:wq + invio esce dall'editor; git status: visualizza lo stato dei commit del file; git add: aggiunge tutti i file alla "coda" dei commit; git commit -m "titolo": effettua un commit; git log --outline: visualizza il log dei commit; git restore: annulla un commit; git branch nomebranch: crea un branch, senza nome visualizza i branch (quando si crea un branch, questo si inizializza con le modifiche fatte nel branch master); alias nome "comando": crea un alias; git log --all --decorate --outline --graph: visualizza il grafico dei branch; git checkout nomebranch: si sposta nel branch; cat nomefile.estensione: legge il contenuto del file; git diff primobranch..secondobranch: visualizza le differenze tra i branch e il loro contenuto; git branch --merge: visualizza il branch a cui è stato fatto l'ultimo commit; git merge: unisce i branch (se non sono presenti conflitti); git remote add origin urlprogetto: rende la cartella remota (GITHUB); git push -u origin master: procede all'autenticazione e all'inizializzazione in remoto; git pull: effettua un pull (import) delle modifiche altrui; git clone: clona una repo. AMBITO TESTING FRAMEWORK È l'intermediario tra il sistema operativo e il software che lo utilizza, è una linea guida che se viene seguita può aiutare ad avere una struttura facile da mantenere e migliorare. SQL (Structured Query Language) È un linguaggio di interrogazione (quindi non procedurale, cioè non permette la creazione di funzioni) che si utilizza per la definizione e la manipolazione dei dati e delle strutture utili a trattarli. Si divide in: Data Definition Language (DDL): permette di creare e cancellare database o di modificarne la struttura; Data Manipulation Language (DML): permette di inserire, cancellare, modificare i dati; Data Control Language (DCL): permette di gestire gli utenti e i permessi; Query Language (QL): permette di interrogare il database, cioè di leggere i dati; Device Media Control Language (DMCL): permette di controllare i supporti (memorie di massa) dove vengono memorizzati i dati. MySQL È un DBMS (DataBase Management System), quindi serve per la gestione dei database relazionali (non gerarchici o reticolari). SCENARIO Lo scenario è un'istanza del caso d'uso: LOGIN. CASO D'USO Sequenza di azioni per la quale viene specificato cosa ci si aspetta dal sistema: esito positivo → reindirizzamento alla home. SIT E UAT Le SIT (System Integration Testing) sono i test delle interfacce tra i componenti e delle interazioni con le varie parti dei sistemi effettuati direttamente dal tester. Le UAT (User Acceptance Testing) sono i test di convalida/accettazione eseguiti dall'utente finale. SDLC (Software Development LifeCycle) Ciclo di sviluppo del software composto da Analisi, Progettazione, Programmazione, Testing e Distribuzione. QA (Quality Assurance) Tester, colui che garantisce la qualità del software. ANALISTA Colui che scrive i casi di test e i report senza l'utilizzo di tool. TOOL Servono per velocizzare i processi di test, eliminare errori e fornire report. Comprendono i software per la simulazione delle azioni sul DOM (Document Object Model). Attenti ai POM:.xml (dipendenze) e Page Object Model (repository con elementi web). Attenti ai CRM (Customer Relationship Management per le relazioni con i clienti, come Salesforce) e CMS (Content Management System, come WordPress). TEST FUNZIONALI VS AUTOMATIZZATI I test funzionali prevedono la definizione, la scrittura, e l'esecuzione di tutti i test case manualmente, il che comporta errori e dispendio di tempo; I test automatizzati sono un insieme di metodologie, tecnologie e strumenti di automazione che fanno risparmiare tempo e sono più efficaci (evitano l'errore umano). SOFTWARE REGRESSION Aggiunta di una nuova funzionalità che "intacca" le precedenti. In caso di test funzionale, verranno ripetuti solo i test relativi alla versione precedente. TIPI DI TEST Unitari: controllo delle singole funzioni; Di integrazioni: controllo sull'insieme di funzioni che interagiscono tra loro; End-to-End: controllo sulla soddisfazione del cliente (qualità funzionalità richieste); Esplorativi: controllo su numerose aree, senza un approccio strutturato. Il Continuous Testing comprende: Test Unitario + Collaudo (Test Funzionale) + Test di Regressione + Test di Integrazione + Software Necessari. FUNZIONALE VS NON FUNZIONALE Test funzionale (metodo): stress del software per verificarne le specifiche; Test non funzionale (modo): tutto il resto (prestazioni, tempo ecc.). TDD (Test Driven Development) VS BDD (Behavior Driven Development) Il TDD si basa sulle funzioni del codice e su 3 fasi: 1. "Fase rossa": il programmatore scrive un test automatico per la nuova funzione da sviluppare, che deve fallire in quanto la funzione non è stata ancora realizzata; 2. "Fase verde": il programmatore sviluppa la quantità minima di codice necessaria per passare il test; 3. "Fase grigia" o refactoring: il programmatore esegue il refactoring del codice per adeguarlo a determinati standard di qualità Il BDD si basa sul comportamento del software e il suo scopo è quello di fare in modo che il team di sviluppo comprenda appieno le richieste del cliente e che quest'ultimo sia a conoscenza di ciò che il team di sviluppo ha compreso. METODOLOGIE DevOps (Development Operation) Si fonda su comunicazione, collaborazione e integrazione di tutti gli sviluppatori: ogni fase di sviluppo si basa sulle altre. L'implementazione del test automation ha portato a questa metodologia diversi vantaggi, tra cui velocità dello sviluppo e qualità del software, collaborazione (responsabilità condivisa), scalabilità (divisione del lavoro), sicurezza (errore umano azzerato), soddisfazione clienti. Agile È una metodologia, un approccio iterativo alla gestione dei progetti e allo sviluppo del software che aiuta i team a fornire valore ai propri clienti in modo più rapido e con meno problemi. Tutto si basa su piccoli incrementi di lavoro invece che su una sola data di rilascio: le 4 fasi da seguire a ripetizione sono DA FARE, IN CORSO, REVISIONE, COMPLETAMENTO. Shift Left I test vengono eseguiti in contemporanea allo sviluppo. CI/CD (Continuous Integration / Continuous Development + Delivery) Si basa su brevissime fasi di sviluppo, rilascio, feedback e gestione qualità da seguire a ripetizione. MOCK Oggetto simulato che viene utilizzato durante i test di unità per sostituire un componente reale del sistema. L'obiettivo principale dell'utilizzo dei mock è isolare l'unità di codice che viene testata dagli altri componenti del sistema (no dipendenze). MOCKUP Modello grafico con funzionalità non implementate. CALLBACK Funzione che prende come parametro una funzione. setNome(getNome()); JUnit È un framework open source per la scrittura di test unitari. Comprende: Annotazioni (@Test): identificano, eseguono e supportano i metodi; Asserzioni (risultato atteso, risultato ottenuto): verificano i risultati; Assunzioni (assume): come assert, ma non registra errori; Test Runner: eseguono i test. Per lavorare con JUnit bisogna: creare un progetto di tipo Maven (strumento di automazione build che ci permette di gestire in maniera più semplice i progetti) specificando: ○ Tipo: internal; ○ Filtro: quick (per quickstart); ○ Group ID: com.example.junit; ○ Artifact ID: junit; cliccare il tasto destro sul progetto → Build Path → Configura il tuo percorso di build → Add External JARs… → aggiungere junit-4.12.jar e hamcrest-core-1.3.jar (di tipo Java Archive, ovvero archivi compressi di classi JAVA). Suite Class (insieme di test) CalcolatriceTest.java package com.example.CalcolatriceProject; import static org.junit.Assert.*; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.Test; @RunWith(Suite.class) @Suite.SuiteClasses({ SommaTest.class, SottrazioneTest.class, MoltiplicazioneTest.class, DivisioneTest.class, RadiceQuadrataTest.class, PotenzaTest.class }) public class CalcolatriceTest { } SommaTest.java package com.example.CalcolatriceProject; import static org.junit.Assert.*; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class SommaTest { Calcolatrice cal = new Calcolatrice(); static int count = 0; Prima di tutti i test. @BeforeClass public static void messaggioIniziale() { System.out.println("Inizio dei test: Somma"); } Dopo tutti i test. @AfterClass public static void messaggioFinale() { System.out.println("Fine dei test: Somma \nTest Effettuati: " + count); } Prima di ogni test. @Before public void counter() { count++; } @Test public void sommaTestCorretto() throws ErroreCalcolatriceException { System.out.println("Test: Risultato Corretto!"); Asserzione. assertEquals(6, cal.somma(3, 3)); } @Test public void sommaTestSbagliato() throws ErroreCalcolatriceException { try { System.out.println("Test: Risultato Sbagliato!"); assertEquals(5, cal.somma(3, 3)); } catch(AssertionError e){ System.out.println("Errore -> " + e); fail(); } } Eccezione. @Test (expected = ErroreCalcolatriceException.class) public void sommaTestNull() throws ErroreCalcolatriceException { System.out.println("Test: Risultato Null!"); cal.somma(null, 1); } @Test (timeout = 5000) public void sommaTest5Secondi() throws ErroreCalcolatriceException { System.out.println("Test: Tempo 5 Secondi!"); assertEquals(2, cal.somma(1, 1)); } } NOTA: esiste l'annotazione @TestFactory per i test dinamici (generati automaticamente quando si esegue il codice) e @Parameters (da utilizzare insieme a @RunWith) per i test parametrici. SELENIUM È un framework open source per automatizzare l'iterazione col browser a scopo di test. Riesce a funzionare su tutti i browser grazie ai WebDriver, che sono insiemi di API e di protocolli che definiscono un'interfaccia indipendente di controllo del browser (ogni browser ha un driver specifico, che gestisce la comunicazione tra sé stesso e Selenium). UTILIZZO Per lavorare con Selenium bisogna: creare un progetto di tipo Maven (strumento di automazione build che ci permette di gestire in maniera più semplice i progetti) specificando: ○ Tipo: internal; ○ Filtro: quick (per quickstart); ○ Group ID: com.example.selenium; ○ Artifact ID: selenium; scaricare il WebDriver del browser che si intende utilizzare; specificare la dipendenza nel pom.xml del progetto. org.seleniumhq.selenium selenium-java 4.10.0 Successivamente, nella cartella src/main/java, andare a creare 2 file: Avvio.java: package com.example.selenium; import com.example.selenium.ConfiguraAmbiente.NomeBrowser; import java.net.URISyntaxException; public class Avvio { public static void main(String[] args) throws URISyntaxException { ConfiguraAmbiente ca = new ConfiguraAmbiente(NomeBrowser.CHROME); ca.cercaSuWikipedia(); ca.chiudiFinestra(); } } ConfiguraAmbiente.java: package com.example.selenium; import java.net.URISyntaxException; import java.time.Duration; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.By; import org.openqa.selenium.Keys; public class ConfiguraAmbiente { public WebDriver webDriver; enum NomeBrowser { CHROME, FIREFOX, IE } private void setProperties() throws URISyntaxException { System.setProperty("webdriver.chrome.driver", "C:\\Users\\salva\\OneDrive\\Desktop\\chromedriver_win32\ \chromedriver.exe"); } public ConfiguraAmbiente(NomeBrowser browser) throws URISyntaxException { setProperties(); switch(browser) { case CHROME: webDriver = new ChromeDriver(); break; case FIREFOX: webDriver = new FirefoxDriver(); break; case IE: webDriver = new InternetExplorerDriver(); break; } } public void cercaSuWikipedia() { webDriver.get("https://it.wikipedia.org/wiki/Pagina_princ ipale"); WebElement searchInput = webDriver.findElement(By.id("searchInput")); searchInput.sendKeys("Selenium"); searchInput.sendKeys(Keys.ENTER); } public void chiudiFinestra() { webDriver.quit(); } } CUCUMBER È uno strumento per eseguire test automatici basati sul comportamento del software (BDD). I test sono scritti in linguaggio Gherkin (GIVEN - WHEN - THEN), un semplice inglese leggibile anche dai non programmatori, che deve essere poi mappato in codice per funzionare. È scritto in Ruby, ma può essere implementato anche in C#, Python e Java. UTILIZZO Per lavorare con Cucumber bisogna: installare il plugin Cucumber Eclipse Plugin; specificare le dipendenze nel pom.xml del progetto io.cucumber cucumber-java 7.11.2 io.cucumber cucumber-junit 7.11.2 creare, in src/main/test, il package cucumber e il file TestRunner.java; package cucumber; import org.junit.runner.RunWith; import io.cucumber.junit.CucumberOptions; import io.cucumber.junit.Cucumber; @RunWith(Cucumber.class) @CucumberOptions( features = "src/test/java/resources", glue = {"step"}, tags = "@tag1 and @tag3 or @tag2", stepNotifications = true ) public class TestRunner { } creare, in src/main/test, il package resources e il file Palindromo.feature; Feature: Determine if String is Palindrome or not @tag1 @tag3 Scenario: Valid Palindrome Given I entered string "Refer" When I test it for Palindrome Then the result should be "true" @tag2 Scenario: Invalid Palindrome Given I entered string "Coin" When I test it for Palindrome Then the result should be "false" creare, in src/main/test, il package step e il file StepPalindromo.java. package step; import org.junit.Assert; import io.cucumber.java.en.Given; import io.cucumber.java.en.When; import io.cucumber.java.en.Then; public class StepPalindromo { private String testPalindrome; private boolean isPalindrome; @Given("^I entered string (.+)$") public void i_entered_string(String toTest) { testPalindrome = toTest; } @When("^I test it for Palindrome$") public void i_test_it_for_Palindrome() { isPalindrome = testPalindrome.equalsIgnoreCase(new StringBuilder(testPalindrome).reverse().toString()); } @Then("the result should be {string}") public void the_result_should_be(String string) { boolean expectedResult = Boolean.parseBoolean(string); if(expectedResult) { Assert.assertTrue(isPalindrome); } else { Assert.assertFalse(isPalindrome); } } } runnare il file TestRunner.java come JUnit. JMETER È un prodotto di Apache, progettato da un italiano (inizialmente utilizzato per misurare le prestazioni di Tomcat). Serve per misurare le performance di una varietà di servizi, attraverso: Test di Carico (Load Testing): comportamento del test sotto un carico di richieste previsto; Stress Test: spingersi oltre i limiti per determinare il carico massimo. UTILIZZO Per lavorare con JMeter bisogna: scaricare Java (versione 8 o superiore); scaricare il.zip (tipo binary) sul sito ufficiale e scompattarlo; avviare, nella cartella bin, il file jmeter.bat; cliccare il tasto destro su Test Plan → add →Threads (Users) → Thread Group: questa schermata permette l'inserimento degli accessi da simulare, dei secondi per la suddivisione degli utenti (ramp-up, che calcola i gruppi di utenti facendo utenti/secondi), del counter ecc. cliccare il tasto destro su nomeThreadGroup → add → Sampler → HTTP Request: questa schermata permette l'inserimento del tipo di protocollo (HTTP o HTTPS), dell'IP o del nome del server (it.wikipedia.org), della porta (443), del path (wiki/Pagina_principale); cliccare il tasto destro su Test Plan → add → Listener → Graph Results (per visualizzare i risultati su un grafico) o View Result Tree (per visualizzare i risultati in un albero delle richieste; cliccando su una richiesta → Response Data si può visualizzare il dato restituito dalla chiamata, che potrà essere un JSON o una pagina HTML). JSON (JavaScript Object Notation) È un formato di serializzazione basato su testo per lo scambio di dati, principalmente tra server e applicazione web. È basato su due tipi di strutture di dati: serie di coppie nome/valore; {"name1":"value1", "name2":"value2"} liste ordinate di valori (array). ["valore1", "valore2"]. DOMANDE E RISPOSTE UTILI 1. Cos'è l'automazione? È qualsiasi azione che può ridurre gli sforzi umani. 2. Cosa sono i test di automazione? Sono dei processi in cui, mediante l'uso di strumenti software e script, si testano delle funzionalità, come l'inserimento di dati. 3. È possibile ottenere il 100% di automazione (coverage)? È difficile, in quanto ci sono casi di test che sono marginali e che vengono eseguiti raramente. 4. Quali sono gli attributi di un buon framework? modulare: adattabile al cambiamento; riutilizzabile: i metodi comuni devono essere scritti in un file comune a tutti gli script; coerente: formato coerente; indipendente: script scritti in modo da essere indipendenti tra loro; registri: utile l'implementazione di registri nel caso in cui vengano eseguiti per molte ore; segnalazione: utile avere la funzione di reporting incorporata nel framework; integrazione: facile da integrare con altre applicazioni. 5. Esistono test che non andrebbero automatizzati? Sì: test che vengono eseguiti raramente, test di usabilità e test esplorativi. 6. Cos'è un framework di test automation? Un insieme di linee guida, presupposti, concetti e pratiche di codifica per creare un ambiente per eseguire i test che verranno automatizzati. 7. Vantaggi e Svantaggi dei due tipi di test: AUTOMATION MANUALE Vantaggi Svantaggi Vantaggi Svantaggi Persone/Qualifica meno nessuna più risorse risorse risorse umane umane competenza di qualificate programmazione Codice riusabilità nessuna riusabilità configurazione configurazione dell'ambiente dell'ambiente Difficoltà più adatto per difficile per coverage debug dei test calcoli in meno requisiti che complessi tempo difficile Costo cambiano alto rischio velocemente affidabilit di errori àe costi alti degli velocità costo inferiore per strumenti progetti brevi Tempo esecuzione tempi di più tempo test in sviluppo e parallelo flessibilità manutenzione prolungati