Caratteristiche del cetriolo: una panoramica

Pubblicato: 2022-04-20

Introduzione

Gherkin è un linguaggio ancora utilizzato in molti framework di automazione dei test. A volte è perché il cliente ci chiede di usarlo, a volte è perché il team decide di farlo.

Ad essere sincero, per me non è stato amore a prima vista. Personalmente ho fatto un viaggio piuttosto lungo con Gherkin: dall'apprezzare all'inizio, dall'odiare la lingua per un po', e poi finire per apprezzarlo di nuovo. In questo articolo presenterò le funzionalità più importanti di Cucumber insieme all'implementazione di Java.

Ecco tutte le caratteristiche del cetriolo trattate in questo articolo:

Caratteristica Descrizione
Scenario Scenario semplice
Schema di scenario Richiede all'utente di fornire i dati del test nella sezione "Esempi".
Tabelle dati Richiede all'utente di fornire dati di test per la fase di test
Contesto dello scenario Condivisione dei valori tra le fasi del test
Tipi di dati di cetriolo Tipi di dati gestiti da cetriolo
Espressione regolare di cetriolo Utilizzo dell'espressione regolare negli scenari di cetriolo
Ganci di cetriolo Esegue codice aggiuntivo negli scenari di test
Tabella 1. Funzionalità di cetriolo e java trattate in questo articolo

File di caratteristiche

Prima di tutto, cos'è un file di funzionalità? Nel mondo tecnico è stato creato un approccio non tecnico per consentire a persone non tecniche di collaborare con il team durante lo sviluppo di un'app. Il linguaggio Gherkin è stato creato come livello aggiuntivo nell'approccio BDD. I test Gherkin si trovano nei cosiddetti file di funzionalità che sono incollati con il codice (Java, Kotlin, C# ecc.). Di solito Gherkin è molto facile da usare e richiede conoscenze di programmazione minime, ma ci sono funzionalità che richiedono un po' di codifica.

Cominciamo con qualcosa di facile.

Scenario

Ecco l'esempio più semplice e facile da usare del test del cetriolo:

 Caratteristica: Scenario

 Sfondo: prima degli scenari di prova
   Dato che eseguo prima del passaggio

 @Test
 Scenario: Scenario 
   Dato che utilizzo il passaggio parametrizzato di "Scenario 1"

Blocco codice 1. Scenario

Code Block 1. contiene alcune cose da spiegare:

  • Funzionalità : il titolo del file di funzionalità
  • Background : la parola chiave che consente all'utente di eseguire fasi di test prima di ogni scenario di test definito nel file di funzionalità
  • @Test : tag che indica al framework di test quale scenario di test deve essere eseguito. "Test" è definito dall'utente. Possiamo usare ad esempio "@SmokeTest"
  • Scenario : nome dello scenario di test

I test Cetriolino utilizzano le parole chiave [Given, When, Then, But] prima di ogni fase del test. Nel nostro unico passaggio di test, ad eccezione del passaggio Sfondo, utilizziamo un parametro in cui passiamo il valore "Scenario 1".

Ora, vediamo come appare il codice Java incollato:

 @Given("Eseguo prima del passaggio")
public void iExecuteBeforeStep() {
   //qualche implementazione
}

@Given("Uso il passaggio parametrizzato di {string}")
public void iUseParametrizedStepOf(String p) {
   //qualche implementazione
}

Code Block 2. Implementazione del codice Java di Scenario

Schema di scenario

Facciamo qualcosa di più complesso:

 Caratteristica: Schema di scenario

 @Test
 Schema dello scenario: Schema dello scenario
   Dato che eseguo il passaggio con "<parametro1>" e "<parametro2>"
 Esempi:
     | parametro1 | parametro2 |
     | parametro1a | parametro2a |
     | parametro1b | parametro2b |

Blocco di codice 3. Schema di scenario

Questa volta utilizzeremo lo Scenario Outline che ci consente di ripetere scenari di test con diverse configurazioni dei dati di test. Code Block 3. contiene alcune cose da spiegare:

  • Esempi : la matrice dei dati di prova da utilizzare negli scenari di prova. La prima riga è un'intestazione con i nomi dei parametri.

E implementazione java:

 @Given("Eseguo il passaggio con {string} e {string}")
public void iRunStepWithAnd(String p1, String p2) {
   //qualche implementazione
}

Code Block 4. Implementazione Java di Scenario Outline

Tabella dati

Lo Scenario Outline è molto utile, ma cosa succede se non si desidera ripetere l'intero scenario di test ma solo un passaggio di test? Gherkin ha un modo per farlo e si chiama "Data Table".

 Caratteristica: tabella dati

@Test
Scenario: Scenario tabella dati
 Dato che ho verificato che la colonna contiene il valore previsto
 | nomecolonna | valore previsto |
 | someColumnName | valoreprevisto |

Blocco codice 5. Tabella dati

Lo scenario con la tabella dei dati non differisce molto dallo schema dello scenario. L'unica cosa è che non mettiamo la parola chiave "Esempi" prima del tavolo.

L'implementazione Java sembra un po' più complessa rispetto ai casi precedenti:

 @Given("Verifico che la colonna contiene il valore previsto")
public void iVerifyColumnValuesInTableUsingQueryFromFileOnSchema(DataTable dataTable) {
   List<Map<String, String>> data = dataTable.asMaps();
   for (Map<String, String> form: data) {
       String nomecolonna = form.get("nomecolonna");
       Stringa ExpectResult = form.get("expectedValue");
       //qualche implementazione
       }
   }
}

Code Block 6. Implementazione Java di Data Table

Per accedere ai dati da una tabella dati, creiamo una speciale variabile dataTable di tipo “DataTable”. Tutti i dati verranno archiviati nella variabile List.

Contesto dello scenario

Utilizzando il Contesto dello scenario possiamo condividere i dati tra i passaggi. Supponiamo di avere uno scenario in due fasi in cui vogliamo passare il valore "dati" dal passaggio 1 al passaggio 2 (blocco codice 7).

 @Test
Scenario: Contesto dello scenario
 Dato che ho impostato il valore del contesto dello scenario "dati"
 Dato che uso il valore del contesto dello scenario

Blocco di codice 7. Contesto dello scenario

In primo luogo abbiamo bisogno di costruire una classe speciale chiamata ScenarioContext con le funzionalità del contesto dello scenario per l'impostazione e il recupero dei dati (Code Block 8). Il nostro contesto di scenario è una HashMap con una coppia chiave-valore. Identificheremo i valori tramite la sua chiave.

  • scenarioContext() : HashMap della coppia chiave-valore
  • setContext() : metodo valore-chiave per memorizzare i dati del contesto dello scenario
  • getContext() : metodo per ottenere i dati che forniscono la chiave
 public class ScenarioContext {

   private Map<String, Object> scenarioContext;

   public scenarioContext(){
       scenarioContext = nuova HashMap<>();
   }

   public void setContext(Chiave contesto, Valore oggetto) {
       scenarioContext.put(key.toString(), valore);
   }

   public Object getContext(Chiave di contesto){
       return scenarioContext.get(key.toString());
   }

}

enum pubblico Contesto {
   ID;
}

Code Block 8. Implementazione Java della classe Scenario Context

Avendo questo possiamo fare uso di metodi implementati. Nel passaggio 1 impostiamo quindi il valore nel contesto dello scenario e nel passaggio 2 otteniamo il valore (blocco codice 9).

 ScenarioContext scenarioContext = new ScenarioContext();

@Given("Ho impostato il valore del contesto dello scenario {string}")
public void iSetScenarioContextValue (valore stringa) {
   scenarioContext.setContext(Context.ID, valore);
}

@Given("Uso il valore del contesto dello scenario")
public void iUseScenarioContextValue() {
   Stringa sharedValue = scenarioContext.getContext(Context.ID).toString();
}

Blocco di codice 9. Passaggi del contesto dello scenario

Tipi di dati di cetriolo

Cucumber gestisce un numero limitato di tipi di dati. Possiamo definire stringhe, interi e valori float ma nel caso di valori booleani abbiamo bisogno di codificare alcune soluzioni alternative.

 @Test
Scenario: Scenario con variabili
 Dato che uso la stringa "string", int 1, float 1.1 e booleano "false"

Blocco di codice 10. Tipi di dati del cetriolo

Il codice Java sarebbe simile a questo:

 @Given("Uso string {string}, int {int}, float {float} e boolean {string}")
public void iUseStringIntFloatAndBoolean(String var1, int var2, double var3, String var4) {
   booleano f = Booleano.valueOf(var4);
   //un po' di codice
}

Code Block 11. Implementazione Java dei tipi di dati Cucumber

Espressione regolare di cetriolo

Questa è un'altra caratteristica usata di frequente. Il blocco di codice 12 mostra uno scenario in due fasi che differiscono solo per l'utilizzo di valori variabili diversi (var1 e var2). Questo è infatti solo un passaggio, e nel codice Java (Code Block 13) definiamo un solo metodo ma con regex e un parametro var.

 @Test
Scenario: scenario di espressioni regolari
 Dato che uso la variabile var1
 Dato che uso la variabile var2

Blocco di codice 12. Espressione regolare in cetriolo

 @Given("^Io uso la variabile (.*)")
public void examTimeTableInSummerSeason(String var) {
   se (var.equals("var1")){
       //un po' di codice
   }
   altrimenti se(var.equals("var2")){
       //un po' di codice
   }
}

Code Block 13. Implementazione Java dell'espressione regolare Cucumber

Ganci di cetriolo

Ultimo ma non meno importante: ganci di cetriolo.

Il blocco di codice 14 presenta i 4 hook più importanti:

  • @Before : esegue il codice prima di ogni scenario di test
  • @After : esegue il codice dopo ogni scenario di test
  • @BeforeStep : esegue il codice prima di ogni passaggio del test
  • @AfterStep : esegue il codice dopo ogni passaggio del test
 @Prima
public void beforeScenario() {
   //un po' di codice
}

@Dopo
public void afterScenario() {
   //un po' di codice
}

@BeforeStep
public void beforeStep() {
   //un po' di codice
}

@Dopo il passo
public void afterStep() {
   //un po' di codice
}

Blocco di codice 14. Ganci di cetriolo

Riepilogo

Spero di averti convinto a usare Gherkin nei tuoi test. Queste poche funzionalità renderanno i tuoi test più leggibili e più facili da capire da parte di persone non tecniche. Anche per i neoassunti sarà più facile comprendere le logiche di business e diminuire i tempi di onboarding.