SlideShare a Scribd company logo
1 of 47
Download to read offline
taringamberini.com
Lavora da sempre con tecnologie Java-based Free Software
ed Open Source presso la Regione Emilia-Romagna
È membro attivo del JUG Padova ed ha partecipato al
Tavolo di Lavoro delle Linee Guida dell'Art. 68 del
Codice dell’Amministrazione Digitale
È traduttore presso la Free Software Foundation Europe
Ha creato la lista di parole Diceware in italiano
Quando non cura le sue piantine officinali, si interessa di:
Object Oriented Design, Testing, Build Automation e
Continuous Delivery
Salsa Agile
Alcune Metodologie Agile
(1970 Waterfall Model)
1974 An adaptive software development process documented
1991 Rapid Application Development (RAD)
1995-99 DSDM, SCRUM, XP, FDD
(2001 Agile Manifesto)
2003 Lean Software Development
2006 Kanban
2008 Lean startup
2009 DevOps
Alcune Pratiche Agile
(1972 SCCS, 1986 CVS, 2000 SVN, 2005 GIT)
1998 Test Driven Development (TDD)
2003 Acceptance Test Driven Development (ATDD)
2003 Domain Driven Design (DDD)
2004 Behaviour Driven Development (BDD)
2000 Continuous Integration (CI)
2006 Continuous Deployment (CD)
www.agilealliance.org/agile101/practices-timeline
www.agilealliance.org/agile101/agile-glossary
Domain Driven Design (DDD)
Image source http://www.guggenheim.org/artwork/1924 - Composition 8 by Vasily Kandinsky
Si distingue per lo sforzo nella definizione di un linguaggio
condiviso, ubiquitous langauage, volto a consentire la
comunicazione di concetti, anche complessi, riducendo le
incomprensioni fra committente (Domain) e team di
sviluppo (Design)
L’ubiquitous langauage è usato in modo pervasivo:
usato da tutti, usato ovunque
discussioni, documentazione, requisiti, progettazione,
architettura, codice sorgente, database, servizi, api, ecc...
Test di Accettazione
Test di Accettazione
È un criterio di accettazione espresso come
esempio o scenario di utilizzo
Ha un esito binario:
test superato, test fallito
Test di Accettazione
Può essere scritto
(specificato) con
un linguaggio più
o meno formale
È possibile
automatizzarne
l’esecuzione
Per questi due aspetti è anche detto:
specifica eseguibile
(executable specification)
Gherkin
È un semplice linguaggio formale per esprimere in
linguaggio (quasi) naturale test di accettazione
Funzionalità,
Contesto, Scenario,
Schema dello scenario, Esempi,
Dato, Data, Dati, Date, Quando, Allora,
E, Ma
# comments, """ doc-strings,
| data-tables, @ tags
Gherkin non è Turing-completo, ha comunque una grammatica con relativo parser
Cucumber
Step Definition
Cucumber “capisce” test
di accettazione scritti in
Gherkin
Gli step definition
sono un conveniente
strato di codice
che “aggancia” la
specifica eseguibile
al prodotto software
(glue code)
Prodotto
Step
Definition
Executable
Specification
gherkin
java
Step
Definitions
java
glue
1
2
acquisto.feature
# language: it
Funzionalità: Acquisto
Scenario: Comprare una banana
Dato che il prezzo di una banana è 20 centesimi
Quando acquisto 2 banane
Allora il prezzo totale deve essere 40 centesimi
Una specifica eseguibile
è salvata in un file .feature
steps
Lanciamo Cucumber
You can implement missing steps with the snippets below:
@Dato("^che il prezzo di una banana è (d+) centesimi$")
public void cheIlPrezzoDiUnaBananaÈCentesimi(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Quando("^acquisto (d+) banane$")
public void acquistoBanane(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Allora("^il prezzo totale deve essere (d+) centesimi$")
public void ilPrezzoTotaleDeveEssereCentesimi(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Tests run: 7, Failures: 0, Errors: 0, Skipped: 4, Time elapsed: 0,344 sec
Confronto Feature/Step Definition
Dato che il prezzo di una
banana è 20 centesimi
@Dato("^che il prezzo di una
banana è (d+) centesimi$")
public void cheIlPrezzoDiUna
BananaÈCentesimi(int bananaCentesimi)
throws Throwable {
...
}
Gherkin
Java
Executable Specification
Step Definition
Feature
glue code
test: AcquistoStepDefinitions.java
public class AcquistoStepDefinitions {
@Dato("^che il prezzo
di una banana è (d+) centesimi$")
public void cheIlPrezzo
DiUnaBananaÈCentesimi(int bananaCentesimi)
throws Throwable {
// Write code here that turns the
//phrase above into concrete actions
throw new PendingException();
}
...
}
Lanciamo Cucumber
Scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
cucumber.api.PendingException: TODO: implement me
Quando acquisto 2 banane #
Allora il prezzo totale deve essere 40 centesimi #
1 Scenarios (1 pending)
3 Steps (2 skipped, 1 pending)
0m0,199s
test: AcquistoStepDefinitions.java
public class AcquistoStepDefinitions {
@Dato("^che il prezzo di una banana è (d+) centesimi$")
public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi)
throws Throwable {
int prezzoBanana = bananaCentesimi;
}
@Quando("^acquisto (d+) banane$")
public void acquistoBanane(int numeroBanane)
throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Allora("^il prezzo totale deve essere (d+) centesimi$")
public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi)
throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
}
Lanciamo Cucumber
Scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
Quando acquisto 2 banane #
cucumber.api.PendingException: TODO: implement me
Allora il prezzo totale deve essere 40 centesimi #
1 Scenarios (1 pending)
3 Steps (1 skipped, 1 pending, 1 passed)
0m0,122s
test: AcquistoStepDefinitions.java
public class AcquistoStepDefinitions {
private int prezzoBanana;
@Dato("^che il prezzo di una banana è (d+) centesimi$")
public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi)
throws Throwable {
prezzoBanana = bananaCentesimi;
}
@Quando("^acquisto (d+) banane$")
public void acquistoBanane(int numeroBanane)
throws Throwable {
Carrello carrello = new Carrello();
carrello.acquisto(numeroBanane, prezzoBanana);
}
@Allora("^il prezzo totale deve essere (d+) centesimi$")
public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi)
throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
}
src: Carrello.java
package com.taringamberini.linuxday2018ferrara;
/**
* @author Tarin Gamberini (www.taringamberini.com)
*/
public class Carrello {
}
test: AcquistoStepDefinitions.java
public class AcquistoStepDefinitions {
private int prezzoBanana;
@Dato("^che il prezzo di una banana è (d+) centesimi$")
public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi)
throws Throwable {
prezzoBanana = bananaCentesimi;
}
@Quando("^acquisto (d+) banane$")
public void acquistoBanane(int numeroBanane)
throws Throwable {
Carrello carrello = new Carrello();
carrello.acquisto(numeroBanane, prezzoBanana);
}
@Allora("^il prezzo totale deve essere (d+) centesimi$")
public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi)
throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
}
src: Carrello.java
package com.taringamberini.linuxday2018ferrara;
/**
* @author Tarin Gamberini (www.taringamberini.com)
*/
public class Carrello {
public void acquisto(int numeroBanane, int prezzoBanana) {
}
}
test: AcquistoStepDefinitions.java
public class AcquistoStepDefinitions {
private int prezzoBanana;
@Dato("^che il prezzo di una banana è (d+) centesimi$")
public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi)
throws Throwable {
prezzoBanana = bananaCentesimi;
}
@Quando("^acquisto (d+) banane$")
public void acquistoBanane(int numeroBanane)
throws Throwable {
Carrello carrello = new Carrello();
carrello.acquisto(numeroBanane, prezzoBanana);
}
@Allora("^il prezzo totale deve essere (d+) centesimi$")
public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi)
throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
}
Lanciamo Cucumber
Scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
Quando acquisto 2 banane #
Allora il prezzo totale deve essere 40 centesimi #
cucumber.api.PendingException: TODO: implement me
1 Scenarios (1 pending)
3 Steps (1 pending, 2 passed)
0m0,128s
test: AcquistoStepDefinitions.java
public class AcquistoStepDefinitions {
private int prezzoBanana;
private Carrello carrello;
@Dato("^che il prezzo di una banana è (d+) centesimi$")
public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi)
throws Throwable {
prezzoBanana = bananaCentesimi;
}
@Quando("^acquisto (d+) banane$")
public void acquistoBanane(int numeroBanane)
throws Throwable {
carrello = new Carrello();
carrello.acquisto(numeroBanane, prezzoBanana);
}
@Allora("^il prezzo totale deve essere (d+) centesimi$")
public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi)
throws Throwable {
assertEquals(totaleCentesimi, carrello.getTotaleAcquistato());
}
}
src: Carrello.java
package com.taringamberini.linuxday2018ferrara;
/**
* @author Tarin Gamberini (www.taringamberini.com)
*/
public class Carrello {
public void acquisto(int numeroBanane, int prezzoBanana) {
}
public int getTotaleAcquistato() {
return 40;
}
}
test: AcquistoStepDefinitions.java
public class AcquistoStepDefinitions {
private int prezzoBanana;
private Carrello carrello;
@Dato("^che il prezzo di una banana è (d+) centesimi$")
public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi)
throws Throwable {
prezzoBanana = bananaCentesimi;
}
@Quando("^acquisto (d+) banane$")
public void acquistoBanane(int numeroBanane)
throws Throwable {
carrello = new Carrello();
carrello.acquisto(numeroBanane, prezzoBanana);
}
@Allora("^il prezzo totale deve essere (d+) centesimi$")
public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi)
throws Throwable {
assertEquals(totaleCentesimi, carrello.getTotaleAcquistato());
}
}
Lanciamo Cucumber
Scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
Quando acquisto 2 banane #
Allora il prezzo totale deve essere 40 centesimi #
1 Scenarios (1 passed)
3 Steps (3 passed)
0m0,242s
acquisto.feature
# language: it
Funzionalità: Acquisto
Scenario: Comprare una banana
Dato che il prezzo di una banana è 20 centesimi
Quando acquisto 2 banane
Allora il prezzo totale deve essere 40 centesimi
Scenario: Comprare una banana
Dato che il prezzo di una banana è 20 centesimi
Quando acquisto 4 banane
Allora il prezzo totale deve essere 80 centesimi
scriviamoli meglio...
acquisto.feature
# language: it
Funzionalità: Acquisto
Schema dello scenario: Comprare una banana
Dato che il prezzo di una banana è 20 centesimi
Quando acquisto <numeroBanane> banane
Allora il prezzo totale deve essere <totale> centesimi
Esempi:
| numeroBanane | totale |
| 2 | 40 |
| 4 | 80 |
Lanciamo Cucumber
Schema dello scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
Quando acquisto 2 banane #
Allora il prezzo totale deve essere 40 centesimi #
Schema dello scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
Quando acquisto 4 banane #
Allora il prezzo totale deve essere 80 centesimi #
java.lang.AssertionError: expected:<80> but was:<40>
Failed scenarios:
test/acceptance/com/taringamberini/
linuxday2018ferrara/features/acquisto.feature:13 #
2 Scenarios (1 failed, 1 passed)
6 Steps (1 failed, 5 passed)
0m0,130s
src: Carrello.java
package com.taringamberini.linuxday2018ferrara;
/**
* @author Tarin Gamberini (www.taringamberini.com)
*/
public class Carrello {
private int totale;
public void acquisto(int numeroBanane, int prezzoBanana) {
totale = numeroBanane * prezzoBanana;
}
public int getTotaleAcquistato() {
// return 40
return totale;
}
}
Lanciamo Cucumber
Schema dello scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
Quando acquisto 2 banane #
Allora il prezzo totale deve essere 40 centesimi #
Schema dello scenario: Comprare una banana #
Dato che il prezzo di una banana è 20 centesimi #
Quando acquisto 4 banane #
Allora il prezzo totale deve essere 80 centesimi #
2 Scenarios (2 passed)
6 Steps (6 passed)
0m0,127s
Conclusioni
Cucumber automatizza l'esecuzione dei test di accettazione a
partire dalla lettura del comportamento espresso in linguaggio
naturale
Unica sorgente di verità: specifiche, i test e la
documentazione sono nello stesso documento
Documentazione vivente: le nostre specifiche sono sempre
aggiornate perché testate automaticamente da Cucumber
Focalizzato sul committente: Cucumber aiuta le persone
dell’azienda committente e dell’IT a collaborare per costruire una
comprensione condivisa degli obiettivi aziendali
it.linkedin.com/in/taringamberini
www.taringamberini.com

More Related Content

Similar to Test di Accettazione con Cucumber (LinuxDay 2018 Ferrara)

Mocking Objects Practices
Mocking Objects PracticesMocking Objects Practices
Mocking Objects PracticesGrUSP
 
Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Davide Cerbo
 
Javascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerJavascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerMatteo Magni
 
corso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascriptcorso web developer - Introduzione a Javascript
corso web developer - Introduzione a JavascriptRiccardo Piccioni
 
Write less do more...with jQuery
Write less do more...with jQueryWrite less do more...with jQuery
Write less do more...with jQueryXeDotNet
 
Reactive programming principles
Reactive programming principlesReactive programming principles
Reactive programming principlesRiccardo Cardin
 
Javascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerJavascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerMatteo Magni
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacyTommaso Torti
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5Matteo Baccan
 
Aspettando Go.2 - Meetup golang milano - 27 settembre 2018
Aspettando Go.2 - Meetup golang milano - 27 settembre 2018Aspettando Go.2 - Meetup golang milano - 27 settembre 2018
Aspettando Go.2 - Meetup golang milano - 27 settembre 2018r3vit
 
Asp.net gestione della_memoria
Asp.net gestione della_memoriaAsp.net gestione della_memoria
Asp.net gestione della_memoriaCrismer La Pignola
 
Let's give it a GO!
Let's give it a GO!Let's give it a GO!
Let's give it a GO!MarioTraetta
 
How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript Stefano Marchisio
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewFrancesco Sciuti
 

Similar to Test di Accettazione con Cucumber (LinuxDay 2018 Ferrara) (20)

Mocking Objects Practices
Mocking Objects PracticesMocking Objects Practices
Mocking Objects Practices
 
CleanCode
CleanCodeCleanCode
CleanCode
 
Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)
 
Javascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerJavascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesigner
 
corso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascriptcorso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascript
 
Write less do more...with jQuery
Write less do more...with jQueryWrite less do more...with jQuery
Write less do more...with jQuery
 
Reactive programming principles
Reactive programming principlesReactive programming principles
Reactive programming principles
 
Javascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerJavascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesigner
 
Hexagonal architecture ita
Hexagonal architecture itaHexagonal architecture ita
Hexagonal architecture ita
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacy
 
Unit testing 101
Unit testing 101Unit testing 101
Unit testing 101
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5
 
XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13
 
Aspettando Go.2 - Meetup golang milano - 27 settembre 2018
Aspettando Go.2 - Meetup golang milano - 27 settembre 2018Aspettando Go.2 - Meetup golang milano - 27 settembre 2018
Aspettando Go.2 - Meetup golang milano - 27 settembre 2018
 
Asp.net gestione della_memoria
Asp.net gestione della_memoriaAsp.net gestione della_memoria
Asp.net gestione della_memoria
 
Let's give it a GO!
Let's give it a GO!Let's give it a GO!
Let's give it a GO!
 
How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript
 
Html5 e PHP
Html5 e PHPHtml5 e PHP
Html5 e PHP
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript Overview
 
Pycon Jungle
Pycon JunglePycon Jungle
Pycon Jungle
 

More from Tarin Gamberini

MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system Tarin Gamberini
 
MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system Tarin Gamberini
 
Commit messages - Good practices
Commit messages - Good practicesCommit messages - Good practices
Commit messages - Good practicesTarin Gamberini
 

More from Tarin Gamberini (6)

MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
 
MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system
 
Commit messages - Good practices
Commit messages - Good practicesCommit messages - Good practices
Commit messages - Good practices
 
Apache Maven
Apache MavenApache Maven
Apache Maven
 
Log4j in 8 slides
Log4j in 8 slidesLog4j in 8 slides
Log4j in 8 slides
 
MVC and Struts 1
MVC and Struts 1MVC and Struts 1
MVC and Struts 1
 

Test di Accettazione con Cucumber (LinuxDay 2018 Ferrara)

  • 1.
  • 2. taringamberini.com Lavora da sempre con tecnologie Java-based Free Software ed Open Source presso la Regione Emilia-Romagna È membro attivo del JUG Padova ed ha partecipato al Tavolo di Lavoro delle Linee Guida dell'Art. 68 del Codice dell’Amministrazione Digitale È traduttore presso la Free Software Foundation Europe Ha creato la lista di parole Diceware in italiano Quando non cura le sue piantine officinali, si interessa di: Object Oriented Design, Testing, Build Automation e Continuous Delivery
  • 3.
  • 5. Alcune Metodologie Agile (1970 Waterfall Model) 1974 An adaptive software development process documented 1991 Rapid Application Development (RAD) 1995-99 DSDM, SCRUM, XP, FDD (2001 Agile Manifesto) 2003 Lean Software Development 2006 Kanban 2008 Lean startup 2009 DevOps
  • 6.
  • 7.
  • 8.
  • 9.
  • 10. Alcune Pratiche Agile (1972 SCCS, 1986 CVS, 2000 SVN, 2005 GIT) 1998 Test Driven Development (TDD) 2003 Acceptance Test Driven Development (ATDD) 2003 Domain Driven Design (DDD) 2004 Behaviour Driven Development (BDD) 2000 Continuous Integration (CI) 2006 Continuous Deployment (CD) www.agilealliance.org/agile101/practices-timeline www.agilealliance.org/agile101/agile-glossary
  • 11.
  • 12.
  • 13. Domain Driven Design (DDD) Image source http://www.guggenheim.org/artwork/1924 - Composition 8 by Vasily Kandinsky Si distingue per lo sforzo nella definizione di un linguaggio condiviso, ubiquitous langauage, volto a consentire la comunicazione di concetti, anche complessi, riducendo le incomprensioni fra committente (Domain) e team di sviluppo (Design) L’ubiquitous langauage è usato in modo pervasivo: usato da tutti, usato ovunque discussioni, documentazione, requisiti, progettazione, architettura, codice sorgente, database, servizi, api, ecc...
  • 14.
  • 15.
  • 17.
  • 18. Test di Accettazione È un criterio di accettazione espresso come esempio o scenario di utilizzo Ha un esito binario: test superato, test fallito
  • 19. Test di Accettazione Può essere scritto (specificato) con un linguaggio più o meno formale È possibile automatizzarne l’esecuzione Per questi due aspetti è anche detto: specifica eseguibile (executable specification)
  • 20. Gherkin È un semplice linguaggio formale per esprimere in linguaggio (quasi) naturale test di accettazione Funzionalità, Contesto, Scenario, Schema dello scenario, Esempi, Dato, Data, Dati, Date, Quando, Allora, E, Ma # comments, """ doc-strings, | data-tables, @ tags Gherkin non è Turing-completo, ha comunque una grammatica con relativo parser
  • 21.
  • 23. Step Definition Cucumber “capisce” test di accettazione scritti in Gherkin Gli step definition sono un conveniente strato di codice che “aggancia” la specifica eseguibile al prodotto software (glue code) Prodotto Step Definition Executable Specification gherkin java Step Definitions java glue 1 2
  • 24. acquisto.feature # language: it Funzionalità: Acquisto Scenario: Comprare una banana Dato che il prezzo di una banana è 20 centesimi Quando acquisto 2 banane Allora il prezzo totale deve essere 40 centesimi Una specifica eseguibile è salvata in un file .feature steps
  • 25. Lanciamo Cucumber You can implement missing steps with the snippets below: @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUnaBananaÈCentesimi(int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @Quando("^acquisto (d+) banane$") public void acquistoBanane(int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @Allora("^il prezzo totale deve essere (d+) centesimi$") public void ilPrezzoTotaleDeveEssereCentesimi(int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } Tests run: 7, Failures: 0, Errors: 0, Skipped: 4, Time elapsed: 0,344 sec
  • 26. Confronto Feature/Step Definition Dato che il prezzo di una banana è 20 centesimi @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUna BananaÈCentesimi(int bananaCentesimi) throws Throwable { ... } Gherkin Java Executable Specification Step Definition Feature glue code
  • 27. test: AcquistoStepDefinitions.java public class AcquistoStepDefinitions { @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzo DiUnaBananaÈCentesimi(int bananaCentesimi) throws Throwable { // Write code here that turns the //phrase above into concrete actions throw new PendingException(); } ... }
  • 28. Lanciamo Cucumber Scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # cucumber.api.PendingException: TODO: implement me Quando acquisto 2 banane # Allora il prezzo totale deve essere 40 centesimi # 1 Scenarios (1 pending) 3 Steps (2 skipped, 1 pending) 0m0,199s
  • 29. test: AcquistoStepDefinitions.java public class AcquistoStepDefinitions { @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi) throws Throwable { int prezzoBanana = bananaCentesimi; } @Quando("^acquisto (d+) banane$") public void acquistoBanane(int numeroBanane) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @Allora("^il prezzo totale deve essere (d+) centesimi$") public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } }
  • 30. Lanciamo Cucumber Scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # Quando acquisto 2 banane # cucumber.api.PendingException: TODO: implement me Allora il prezzo totale deve essere 40 centesimi # 1 Scenarios (1 pending) 3 Steps (1 skipped, 1 pending, 1 passed) 0m0,122s
  • 31. test: AcquistoStepDefinitions.java public class AcquistoStepDefinitions { private int prezzoBanana; @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi) throws Throwable { prezzoBanana = bananaCentesimi; } @Quando("^acquisto (d+) banane$") public void acquistoBanane(int numeroBanane) throws Throwable { Carrello carrello = new Carrello(); carrello.acquisto(numeroBanane, prezzoBanana); } @Allora("^il prezzo totale deve essere (d+) centesimi$") public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } }
  • 32. src: Carrello.java package com.taringamberini.linuxday2018ferrara; /** * @author Tarin Gamberini (www.taringamberini.com) */ public class Carrello { }
  • 33. test: AcquistoStepDefinitions.java public class AcquistoStepDefinitions { private int prezzoBanana; @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi) throws Throwable { prezzoBanana = bananaCentesimi; } @Quando("^acquisto (d+) banane$") public void acquistoBanane(int numeroBanane) throws Throwable { Carrello carrello = new Carrello(); carrello.acquisto(numeroBanane, prezzoBanana); } @Allora("^il prezzo totale deve essere (d+) centesimi$") public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } }
  • 34. src: Carrello.java package com.taringamberini.linuxday2018ferrara; /** * @author Tarin Gamberini (www.taringamberini.com) */ public class Carrello { public void acquisto(int numeroBanane, int prezzoBanana) { } }
  • 35. test: AcquistoStepDefinitions.java public class AcquistoStepDefinitions { private int prezzoBanana; @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi) throws Throwable { prezzoBanana = bananaCentesimi; } @Quando("^acquisto (d+) banane$") public void acquistoBanane(int numeroBanane) throws Throwable { Carrello carrello = new Carrello(); carrello.acquisto(numeroBanane, prezzoBanana); } @Allora("^il prezzo totale deve essere (d+) centesimi$") public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } }
  • 36. Lanciamo Cucumber Scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # Quando acquisto 2 banane # Allora il prezzo totale deve essere 40 centesimi # cucumber.api.PendingException: TODO: implement me 1 Scenarios (1 pending) 3 Steps (1 pending, 2 passed) 0m0,128s
  • 37. test: AcquistoStepDefinitions.java public class AcquistoStepDefinitions { private int prezzoBanana; private Carrello carrello; @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi) throws Throwable { prezzoBanana = bananaCentesimi; } @Quando("^acquisto (d+) banane$") public void acquistoBanane(int numeroBanane) throws Throwable { carrello = new Carrello(); carrello.acquisto(numeroBanane, prezzoBanana); } @Allora("^il prezzo totale deve essere (d+) centesimi$") public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi) throws Throwable { assertEquals(totaleCentesimi, carrello.getTotaleAcquistato()); } }
  • 38. src: Carrello.java package com.taringamberini.linuxday2018ferrara; /** * @author Tarin Gamberini (www.taringamberini.com) */ public class Carrello { public void acquisto(int numeroBanane, int prezzoBanana) { } public int getTotaleAcquistato() { return 40; } }
  • 39. test: AcquistoStepDefinitions.java public class AcquistoStepDefinitions { private int prezzoBanana; private Carrello carrello; @Dato("^che il prezzo di una banana è (d+) centesimi$") public void cheIlPrezzoDiUnaBananaÈCentesimi(int bananaCentesimi) throws Throwable { prezzoBanana = bananaCentesimi; } @Quando("^acquisto (d+) banane$") public void acquistoBanane(int numeroBanane) throws Throwable { carrello = new Carrello(); carrello.acquisto(numeroBanane, prezzoBanana); } @Allora("^il prezzo totale deve essere (d+) centesimi$") public void ilPrezzoTotaleDeveEssereCentesimi(int totaleCentesimi) throws Throwable { assertEquals(totaleCentesimi, carrello.getTotaleAcquistato()); } }
  • 40. Lanciamo Cucumber Scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # Quando acquisto 2 banane # Allora il prezzo totale deve essere 40 centesimi # 1 Scenarios (1 passed) 3 Steps (3 passed) 0m0,242s
  • 41. acquisto.feature # language: it Funzionalità: Acquisto Scenario: Comprare una banana Dato che il prezzo di una banana è 20 centesimi Quando acquisto 2 banane Allora il prezzo totale deve essere 40 centesimi Scenario: Comprare una banana Dato che il prezzo di una banana è 20 centesimi Quando acquisto 4 banane Allora il prezzo totale deve essere 80 centesimi scriviamoli meglio...
  • 42. acquisto.feature # language: it Funzionalità: Acquisto Schema dello scenario: Comprare una banana Dato che il prezzo di una banana è 20 centesimi Quando acquisto <numeroBanane> banane Allora il prezzo totale deve essere <totale> centesimi Esempi: | numeroBanane | totale | | 2 | 40 | | 4 | 80 |
  • 43. Lanciamo Cucumber Schema dello scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # Quando acquisto 2 banane # Allora il prezzo totale deve essere 40 centesimi # Schema dello scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # Quando acquisto 4 banane # Allora il prezzo totale deve essere 80 centesimi # java.lang.AssertionError: expected:<80> but was:<40> Failed scenarios: test/acceptance/com/taringamberini/ linuxday2018ferrara/features/acquisto.feature:13 # 2 Scenarios (1 failed, 1 passed) 6 Steps (1 failed, 5 passed) 0m0,130s
  • 44. src: Carrello.java package com.taringamberini.linuxday2018ferrara; /** * @author Tarin Gamberini (www.taringamberini.com) */ public class Carrello { private int totale; public void acquisto(int numeroBanane, int prezzoBanana) { totale = numeroBanane * prezzoBanana; } public int getTotaleAcquistato() { // return 40 return totale; } }
  • 45. Lanciamo Cucumber Schema dello scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # Quando acquisto 2 banane # Allora il prezzo totale deve essere 40 centesimi # Schema dello scenario: Comprare una banana # Dato che il prezzo di una banana è 20 centesimi # Quando acquisto 4 banane # Allora il prezzo totale deve essere 80 centesimi # 2 Scenarios (2 passed) 6 Steps (6 passed) 0m0,127s
  • 46. Conclusioni Cucumber automatizza l'esecuzione dei test di accettazione a partire dalla lettura del comportamento espresso in linguaggio naturale Unica sorgente di verità: specifiche, i test e la documentazione sono nello stesso documento Documentazione vivente: le nostre specifiche sono sempre aggiornate perché testate automaticamente da Cucumber Focalizzato sul committente: Cucumber aiuta le persone dell’azienda committente e dell’IT a collaborare per costruire una comprensione condivisa degli obiettivi aziendali