SlideShare a Scribd company logo
1 of 56
Download to read offline
MANTENERE UNA DISTRIBUZIONE DRUPAL
ATTRAVERSO TEST COVERAGE
PADDLE CASE STUDY
https://github.com/brummbar/drupal-day-2015
ABOUT ME
FRANCESCO SARDARA
Backend e frontend
Email:
francesco.sardara@kanooh.be
D.o: Sardara
PER CHI LAVORO
COSA È PADDLE
FLEMISH GOVERNMENT
Framework contract
Unico referente per sito web, hosting e supporto;
frontend che segue le specifiche di branding del governo
Fiammingo;
focus sulla gestione dei contenuti (revisioni, workflow);
usabilità del backend per utenti non esperti;
commenti, multilingua, contatti, quiz, rss, newsletter,
protected pages.
WORKFLOW DI LAVORO
Sprint di 2 settimane
↓
Soft release
↓
Hard release
Rilascio in produzione
ORGANIZZAZIONE DELLO SPRINT
Open/Reopened
Development
Testing
QA
UAT
ANATOMIA DI UN TICKET
User story / descrizione bug
UAT steps
Definition of done
DEFINITION OF DONE
Functionally complete
Automated tests cover UAT instructions
Automated Simpletest tests passing within the last 24h
Automated Selenium tests passing within the last 24h
Working upgrade path from the last release in place
...
AUTOMATED TESTS
Simpletest e Selenium
Shoov.io / Webdrivercss
Eseguiti su server tramite Jenkins CI
Esecuzioni giornaliere automatiche
Esecuzioni manuali per ticket
Esecuzione remota su Browserstack
SELENIUM
automatizzazione di test su applicazioni web
ampiamente supportato in svariati linguaggi
Selenium IDE e Webdriver
COSA TESTIAMO IN SELENIUM
funzionalità personalizzate
integrazioni tra moduli
funzionalità Javascript
regressioni
QUALCHE NUMERO
746 test
10966 asserzioni
tempo di esecuzione di 18 ore
richiedono 2/3 del tempo di sviluppo
PAGE OBJECT PATTERN
PUNTI CHIAVE
riduzione della duplicazione del codice
facilità nell’aggiornare la relativa classe se gli elementi
della pagina cambiano
possibilità di sfruttare appieno i meccanismi di ereditarietà
REGOLE
solo la classe deve contenere XPath / selettori CSS
relativi all’elemento
nessuna assertion deve essere fatta all’interno della
classe
PAGE OBJECT PATTERN IN
PADDLE
STRUTTURA CARTELLE
ANATOMIA DI UNA CLASSE PAGE OBJECT
Il metodo costruttore contiene sempre una referenza a
Webdriver e all'oggetto Selenium.
/**
* Construct a new GlossaryDefinitionTableRow.
*
* @param WebDriverTestCase $webdriver
* The Selenium web driver test case.
* @param PHPUnit_Extensions_Selenium2TestCase_Element $element
* The webdriver element of the definition table row.
*/
public function __construct(WebDriverTestCase $webdriver, $element)
{
parent::__construct($webdriver);
$this->element = $element;
}
Tutte le proprietà che rappresentano altri Page Object sono
gestite tramite magic get.
/**
* {@inheritdoc}
*/
public function __get($name)
{
switch ($name) {
case 'saveButton':
return $this->element->byXPath('.//input[contains(@id, "edit-save")]'
break;
case 'definition':
return new Text($this->webdriver, $this->element->byName('definition'
break;
case 'description':
return new Wysiwyg($this->webdriver, 'edit-field-glossary-description
break;
}
throw new FormFieldNotDefinedException($name);
}
PERCHÉ USARE __GET() ?
Legacy code
Separazione dalle proprietà
Linearità di lettura
$this->configurePage->go();
$this->configurePage->contextualToolbar->buttonAdd->click();
$modal->form->definition->fill($title);
$modal->form->description->setBodyText($description);
$modal->form->saveButton->click();
$modal->waitUntilClosed();
ESEMPIO DI TEST CASE
GlossaryTest.php
testGlossaryDefinitionHighlighting
RISULTATO DEL TEST
SOPRAVVIVERE AI TEST
Approcci e best practices
RANDOM FAILING TESTS
Per RFT si indicano quei test che senza nessun
cambiamento nel codice o nei dati di test(*), il loro risultato
non è costante.
Cause comuni:
differenze hardware
dati di test
IMPLICIT E EXPLICIT WAITS
Il tempo di attesa implicito rappresenta per quanto tempo
Webdriver deve interrogare il DOM in attesa di trovare un
elemento se esso non è disponibile immediatamente.
Il tempo di attesa esplicito rappresenta per quanto tempo
Webdriver deve aspettare una certa condizione prima di
proseguire con l'esecuzione.
IMPLICIT WAIT
// Add a new definition.
$this->configurePage->contextualToolbar->buttonAdd->click();
$modal = new GlossaryDefinitionModal($this);
$modal->form->definition->fill('The awesome definition');
EXPLICIT WAIT
// Add a new definition.
$this->configurePage->contextualToolbar->buttonAdd->click();
$modal = new GlossaryDefinitionModal($this);
$modal->waitUntilOpened();
$modal->form->definition->fill('The awesome definition');
public function waitUntilOpened()
{
$callable = new SerializableClosure(...);
$this->webdriver->waitUntil($callable, $this->timeout);
}
RANDOMIZZARE I DATI DI TEST
Pro
Evitare parzialmente "collisioni"
tra contenuti
Trovare casi limite
Simulare un vero utilizzo del
sistema
Contro
La randomizzazione rende il
test non completamente
prevedibile
L'APPROCCIO DI PADDLE
La generazione dei contenuti è randomizzata.
I contenuti vengono lasciati intatti a meno che la loro
presenza non complichi la realizzazione del test.
SOPRAVVIVERE AI TEST
(REPRISE)
Approcci in Paddle
CKEDITOR
/**
* Sets the body text.
*
* @param string $text
* The text to enter in the body.
*/
public function setBodyText($text)
{
$this->webdriver->byId('cke_' . $this->editorId);
$this->webdriver->execute(
array(
'script' => "CKEDITOR.instances['{$this->editorId}'].setData('"
'args' => array(),
)
);
}
AJAX CALLBACKS
// ...
$form['list_id'] = array(
'#type' => 'select',
'#title' => t('List'),
'#required' => TRUE,
'#ajax' => array(
'callback' => 'mailchimp_campaign_list_segment_callback',
),
);
// ...
/**
* Marks the element as if it is waiting for AJAX callbacks.
*
* @see KanoohPaddlePagesElementFormAutoCompletedText::markAsWaitingForAuto
*/
public function markAsWaitingForAjaxCallback(PHPUnit_Extensions_Selenium2TestCas
{
$this->webdriver->execute(
array(
'script' => "arguments[0].className += ' progress-disabled';",
'args' => array($element->toWebDriverObject()),
)
);
}
MASTERING THE STALE
// ...
$form = $image_pane_type->getForm();
$form->showCaption->check();
// Submit the form and reload the modal.
$form->submit();
// Test something else.
$form->captionTextArea->fill('Oooops');
// ...
EXPLOITING THE STALE
// Waits until the current page is loaded.
public function waitUntilPageIsLoaded()
{
$body = $this->bodyElement;
$webdriver = $this->webdriver;
$callable = new SerializableClosure(
function () use ($body, $webdriver) {
try {
$body->click();
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException
return true;
}
}
);
$this->webdriver->waitUntil($callable, $this->webdriver->getTimeout());
$this->webdriver->waitUntilElementIsDisplayed('//body');
}
IMPROVING SELENIUM
RESULTS
RIPETIZIONI MULTIPLE PER EVITARE L'INTRODUZIONE DI RFT
$ base_url=http://paddle.dev ./vendor/bin/phpunit --repeat=3 
tests/Kanooh/Paddle/App/ContactPerson/EnableDisableTest.php
RICONOSCERE LE RFT
$ ./vendor/bin/phpunit --repeat=2 --only-repeat-failed tests/
VELOCIZZARE L'ESECUZIONE
esecuzione in parallelo dei test
sfruttare drupal/drupal-driver per rimuovere interazioni
browser non necessarie
VISUAL REGRESSION
WEBDRIVERCSS E SHOOV.IO
WEBDRIVERCSS
Tool di automatizzazione per test di visual regression per
WebdriverIO.
SHOOV.IO
Tool di visual regression e live monitoring.
Wrapper per Webdrivercss
Headless Drupal per lo storage degli screenshot
Angular.js web-app per il confronto visuale
Integrazione con Github (login, commits, pull request)
Gratuito (?)
L'APPROCCIO DI PADDLE AL VR
Configuration
Single test
https://github.com/brummbar/visual-regression
Q&A
Per domande o suggerimenti, scrivetemi
francesco.sardara@kanooh.be
GRAZIE PER
L'ATTENZIONE.
Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

More Related Content

What's hot

jQuery - 1 | WebMaster & WebDesigner
jQuery - 1 | WebMaster & WebDesignerjQuery - 1 | WebMaster & WebDesigner
jQuery - 1 | WebMaster & WebDesignerMatteo Magni
 
jQuery - 4 | WebMaster & WebDesigner
jQuery - 4 | WebMaster & WebDesignerjQuery - 4 | WebMaster & WebDesigner
jQuery - 4 | WebMaster & WebDesignerMatteo Magni
 
Sviluppo web dall'antichità all'avanguardia e ritorno
Sviluppo web  dall'antichità all'avanguardia e ritornoSviluppo web  dall'antichità all'avanguardia e ritorno
Sviluppo web dall'antichità all'avanguardia e ritornolordarthas
 
Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2Diego Drigani
 
Luca Masini: Introduzione a GWT 2.0
Luca Masini: Introduzione a GWT 2.0Luca Masini: Introduzione a GWT 2.0
Luca Masini: Introduzione a GWT 2.0firenze-gtug
 
Applicazioni distribuite con Symfony2
Applicazioni distribuite con Symfony2Applicazioni distribuite con Symfony2
Applicazioni distribuite con Symfony2Matteo Galli
 
Autenticazione delle api con jwt e symfony (Italian)
Autenticazione delle api con jwt e symfony (Italian)Autenticazione delle api con jwt e symfony (Italian)
Autenticazione delle api con jwt e symfony (Italian)Marco Albarelli
 
ZoeFX: un framework MVC per JavaFX
ZoeFX: un framework MVC per JavaFXZoeFX: un framework MVC per JavaFX
ZoeFX: un framework MVC per JavaFXTiziano Lattisi
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerMatteo Magni
 
jQuery e i suoi plugin
jQuery e i suoi pluginjQuery e i suoi plugin
jQuery e i suoi pluginPasquale Puzio
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerMatteo Magni
 
PHP Template Engine (introduzione)
PHP Template Engine (introduzione)PHP Template Engine (introduzione)
PHP Template Engine (introduzione)Asmir Mustafic
 

What's hot (20)

jQuery - 1 | WebMaster & WebDesigner
jQuery - 1 | WebMaster & WebDesignerjQuery - 1 | WebMaster & WebDesigner
jQuery - 1 | WebMaster & WebDesigner
 
Amazon S3 in Perl
Amazon S3 in PerlAmazon S3 in Perl
Amazon S3 in Perl
 
Perl Template Toolkit
Perl Template ToolkitPerl Template Toolkit
Perl Template Toolkit
 
jQuery - 4 | WebMaster & WebDesigner
jQuery - 4 | WebMaster & WebDesignerjQuery - 4 | WebMaster & WebDesigner
jQuery - 4 | WebMaster & WebDesigner
 
Ajax e jQuery
Ajax e jQueryAjax e jQuery
Ajax e jQuery
 
Sviluppo web dall'antichità all'avanguardia e ritorno
Sviluppo web  dall'antichità all'avanguardia e ritornoSviluppo web  dall'antichità all'avanguardia e ritorno
Sviluppo web dall'antichità all'avanguardia e ritorno
 
Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2
 
Luca Masini: Introduzione a GWT 2.0
Luca Masini: Introduzione a GWT 2.0Luca Masini: Introduzione a GWT 2.0
Luca Masini: Introduzione a GWT 2.0
 
Applicazioni distribuite con Symfony2
Applicazioni distribuite con Symfony2Applicazioni distribuite con Symfony2
Applicazioni distribuite con Symfony2
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
 
Umarells
UmarellsUmarells
Umarells
 
Autenticazione delle api con jwt e symfony (Italian)
Autenticazione delle api con jwt e symfony (Italian)Autenticazione delle api con jwt e symfony (Italian)
Autenticazione delle api con jwt e symfony (Italian)
 
ZoeFX: un framework MVC per JavaFX
ZoeFX: un framework MVC per JavaFXZoeFX: un framework MVC per JavaFX
ZoeFX: un framework MVC per JavaFX
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesigner
 
Introduzione a jQuery
Introduzione a jQueryIntroduzione a jQuery
Introduzione a jQuery
 
jQuery e i suoi plugin
jQuery e i suoi pluginjQuery e i suoi plugin
jQuery e i suoi plugin
 
JavaFX2: una panoramica
JavaFX2: una panoramicaJavaFX2: una panoramica
JavaFX2: una panoramica
 
Aws Simple DB
Aws Simple DBAws Simple DB
Aws Simple DB
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesigner
 
PHP Template Engine (introduzione)
PHP Template Engine (introduzione)PHP Template Engine (introduzione)
PHP Template Engine (introduzione)
 

Viewers also liked

Come progettare e realizzare una distribuzione in Drupal 8
Come progettare e realizzare una distribuzione in Drupal 8Come progettare e realizzare una distribuzione in Drupal 8
Come progettare e realizzare una distribuzione in Drupal 8DrupalDay
 
Drupal per la PA
Drupal per la PADrupal per la PA
Drupal per la PADrupalDay
 
Da X a Drupal 8, migra tutto e vivi sereno
Da X a Drupal 8, migra tutto e vivi serenoDa X a Drupal 8, migra tutto e vivi sereno
Da X a Drupal 8, migra tutto e vivi serenoDrupalDay
 
Once you go cloud you never go down
Once you go cloud you never go downOnce you go cloud you never go down
Once you go cloud you never go downDrupalDay
 
Tooling per il tema in Drupal 8
Tooling per il tema in Drupal 8Tooling per il tema in Drupal 8
Tooling per il tema in Drupal 8DrupalDay
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your CodeDrupalDay
 
[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8DrupalDay
 
[drupalday2017] - Devel - D8 release party
[drupalday2017] - Devel - D8 release party[drupalday2017] - Devel - D8 release party
[drupalday2017] - Devel - D8 release partyDrupalDay
 
[drupalday2017] - Async navigation with a lightweight ES6 framework
[drupalday2017] - Async navigation with a lightweight ES6 framework[drupalday2017] - Async navigation with a lightweight ES6 framework
[drupalday2017] - Async navigation with a lightweight ES6 frameworkDrupalDay
 
[drupalday2017] - Drupal 4 Stakeholders
[drupalday2017] - Drupal 4 Stakeholders[drupalday2017] - Drupal 4 Stakeholders
[drupalday2017] - Drupal 4 StakeholdersDrupalDay
 
[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.
[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.
[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.DrupalDay
 
[drupalday2017] - Behat per Drupal: test automatici e molto di più
[drupalday2017] - Behat per Drupal: test automatici e molto di più[drupalday2017] - Behat per Drupal: test automatici e molto di più
[drupalday2017] - Behat per Drupal: test automatici e molto di piùDrupalDay
 
[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8DrupalDay
 
[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a time
[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a time[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a time
[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a timeDrupalDay
 
[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...
[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...
[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...DrupalDay
 
[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...
[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...
[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...DrupalDay
 
[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di Sapienza
[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di Sapienza[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di Sapienza
[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di SapienzaDrupalDay
 
[drupalday2017] - Quando l’informazione è un servizio
[drupalday2017] - Quando l’informazione è un servizio[drupalday2017] - Quando l’informazione è un servizio
[drupalday2017] - Quando l’informazione è un servizioDrupalDay
 
[drupalday2017] - Venezia & Drupal. Venezia è Drupal!
[drupalday2017] - Venezia & Drupal. Venezia è Drupal![drupalday2017] - Venezia & Drupal. Venezia è Drupal!
[drupalday2017] - Venezia & Drupal. Venezia è Drupal!DrupalDay
 
[drupalday2017] - Cosa significa convertire un modulo da D7 a D8
[drupalday2017] - Cosa significa convertire un modulo da D7 a D8[drupalday2017] - Cosa significa convertire un modulo da D7 a D8
[drupalday2017] - Cosa significa convertire un modulo da D7 a D8DrupalDay
 

Viewers also liked (20)

Come progettare e realizzare una distribuzione in Drupal 8
Come progettare e realizzare una distribuzione in Drupal 8Come progettare e realizzare una distribuzione in Drupal 8
Come progettare e realizzare una distribuzione in Drupal 8
 
Drupal per la PA
Drupal per la PADrupal per la PA
Drupal per la PA
 
Da X a Drupal 8, migra tutto e vivi sereno
Da X a Drupal 8, migra tutto e vivi serenoDa X a Drupal 8, migra tutto e vivi sereno
Da X a Drupal 8, migra tutto e vivi sereno
 
Once you go cloud you never go down
Once you go cloud you never go downOnce you go cloud you never go down
Once you go cloud you never go down
 
Tooling per il tema in Drupal 8
Tooling per il tema in Drupal 8Tooling per il tema in Drupal 8
Tooling per il tema in Drupal 8
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8
 
[drupalday2017] - Devel - D8 release party
[drupalday2017] - Devel - D8 release party[drupalday2017] - Devel - D8 release party
[drupalday2017] - Devel - D8 release party
 
[drupalday2017] - Async navigation with a lightweight ES6 framework
[drupalday2017] - Async navigation with a lightweight ES6 framework[drupalday2017] - Async navigation with a lightweight ES6 framework
[drupalday2017] - Async navigation with a lightweight ES6 framework
 
[drupalday2017] - Drupal 4 Stakeholders
[drupalday2017] - Drupal 4 Stakeholders[drupalday2017] - Drupal 4 Stakeholders
[drupalday2017] - Drupal 4 Stakeholders
 
[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.
[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.
[drupalday 2017] - Accessibilità Web: Finalità, metodologie e strumenti.
 
[drupalday2017] - Behat per Drupal: test automatici e molto di più
[drupalday2017] - Behat per Drupal: test automatici e molto di più[drupalday2017] - Behat per Drupal: test automatici e molto di più
[drupalday2017] - Behat per Drupal: test automatici e molto di più
 
[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8[drupalday2017] - DevOps: strumenti di automazione per Drupal8
[drupalday2017] - DevOps: strumenti di automazione per Drupal8
 
[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a time
[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a time[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a time
[drupalday2017 - KEYNOTE] - Saving the world one Open Source project at a time
 
[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...
[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...
[drupalday2017] - Contenuti educativi digitali aperti, creare contenuti e dis...
 
[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...
[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...
[drupalday2017] - Open Data con Drupal nella PA: considerazioni su licensing ...
 
[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di Sapienza
[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di Sapienza[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di Sapienza
[drupalday2017] - DRUPAL per la PA: il modello della Trasparenza di Sapienza
 
[drupalday2017] - Quando l’informazione è un servizio
[drupalday2017] - Quando l’informazione è un servizio[drupalday2017] - Quando l’informazione è un servizio
[drupalday2017] - Quando l’informazione è un servizio
 
[drupalday2017] - Venezia & Drupal. Venezia è Drupal!
[drupalday2017] - Venezia & Drupal. Venezia è Drupal![drupalday2017] - Venezia & Drupal. Venezia è Drupal!
[drupalday2017] - Venezia & Drupal. Venezia è Drupal!
 
[drupalday2017] - Cosa significa convertire un modulo da D7 a D8
[drupalday2017] - Cosa significa convertire un modulo da D7 a D8[drupalday2017] - Cosa significa convertire un modulo da D7 a D8
[drupalday2017] - Cosa significa convertire un modulo da D7 a D8
 

Similar to Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

Rich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryRich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryAlberto Buschettu
 
Come Drupal costruisce le tue pagine
Come Drupal costruisce le tue pagineCome Drupal costruisce le tue pagine
Come Drupal costruisce le tue paginesparkfabrik
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacyTommaso Torti
 
Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Davide Cerbo
 
E suap - tecnologie client
E suap - tecnologie client E suap - tecnologie client
E suap - tecnologie client Sabino Labarile
 
Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...
Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...
Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...Codemotion
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Railsjekil
 
DDAY2014 - Performance in Drupal 8
DDAY2014 - Performance in Drupal 8DDAY2014 - Performance in Drupal 8
DDAY2014 - Performance in Drupal 8DrupalDay
 
JAMP DAY 2010 - ROMA (4)
JAMP DAY 2010 - ROMA (4)JAMP DAY 2010 - ROMA (4)
JAMP DAY 2010 - ROMA (4)jampslide
 
Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8Luca Lusso
 

Similar to Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study (20)

Rich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryRich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in Jquery
 
Come Drupal costruisce le tue pagine
Come Drupal costruisce le tue pagineCome Drupal costruisce le tue pagine
Come Drupal costruisce le tue pagine
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacy
 
react-it.pdf
react-it.pdfreact-it.pdf
react-it.pdf
 
Yagwto
YagwtoYagwto
Yagwto
 
Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)
 
Javascript
JavascriptJavascript
Javascript
 
E suap - tecnologie client
E suap - tecnologie client E suap - tecnologie client
E suap - tecnologie client
 
SaaS con Symfony2
SaaS con Symfony2SaaS con Symfony2
SaaS con Symfony2
 
Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...
Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...
Tech Webinar: Advanced AngularJS, tecniche avanzate per padroneggiare il fram...
 
Html5 e PHP
Html5 e PHPHtml5 e PHP
Html5 e PHP
 
AngularJS-Intro
AngularJS-IntroAngularJS-Intro
AngularJS-Intro
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Rails
 
ReactJS for beginners
ReactJS for beginnersReactJS for beginners
ReactJS for beginners
 
Novità di Asp.Net 4.0
Novità di Asp.Net 4.0Novità di Asp.Net 4.0
Novità di Asp.Net 4.0
 
#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2
 
Java Advanced
Java AdvancedJava Advanced
Java Advanced
 
DDAY2014 - Performance in Drupal 8
DDAY2014 - Performance in Drupal 8DDAY2014 - Performance in Drupal 8
DDAY2014 - Performance in Drupal 8
 
JAMP DAY 2010 - ROMA (4)
JAMP DAY 2010 - ROMA (4)JAMP DAY 2010 - ROMA (4)
JAMP DAY 2010 - ROMA (4)
 
Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8
 

More from DrupalDay

[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...
[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...
[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...DrupalDay
 
[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client Manager
[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client Manager[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client Manager
[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client ManagerDrupalDay
 
[drupalday2017] - Drupal & Patternlab: un nuovo approccio al theming
[drupalday2017] - Drupal & Patternlab: un nuovo approccio al theming[drupalday2017] - Drupal & Patternlab: un nuovo approccio al theming
[drupalday2017] - Drupal & Patternlab: un nuovo approccio al themingDrupalDay
 
[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5
[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5
[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5DrupalDay
 
[drupalday2017] - Speed-up your Drupal instance!
[drupalday2017] - Speed-up your Drupal instance![drupalday2017] - Speed-up your Drupal instance!
[drupalday2017] - Speed-up your Drupal instance!DrupalDay
 
[drupalday2017] - REST in pieces
[drupalday2017] - REST in pieces[drupalday2017] - REST in pieces
[drupalday2017] - REST in piecesDrupalDay
 
Invisiblefarm condivide l'esperienza DrupalGIS
Invisiblefarm condivide l'esperienza DrupalGISInvisiblefarm condivide l'esperienza DrupalGIS
Invisiblefarm condivide l'esperienza DrupalGISDrupalDay
 
La semantica per automatizzare una redazione web: l'esperienza di Innolabplus.eu
La semantica per automatizzare una redazione web: l'esperienza di Innolabplus.euLa semantica per automatizzare una redazione web: l'esperienza di Innolabplus.eu
La semantica per automatizzare una redazione web: l'esperienza di Innolabplus.euDrupalDay
 
"Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen...
"Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen..."Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen...
"Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen...DrupalDay
 
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...DrupalDay
 

More from DrupalDay (10)

[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...
[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...
[drupalday2017] - Cloud e integrazione per la PA: la sfida dell'Open Source t...
 
[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client Manager
[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client Manager[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client Manager
[drupalday2017] - Drupal come frontend che consuma servizi: HTTP Client Manager
 
[drupalday2017] - Drupal & Patternlab: un nuovo approccio al theming
[drupalday2017] - Drupal & Patternlab: un nuovo approccio al theming[drupalday2017] - Drupal & Patternlab: un nuovo approccio al theming
[drupalday2017] - Drupal & Patternlab: un nuovo approccio al theming
 
[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5
[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5
[drupalday2017] - Decoupled frontend con Drupal 8 e OpenUI 5
 
[drupalday2017] - Speed-up your Drupal instance!
[drupalday2017] - Speed-up your Drupal instance![drupalday2017] - Speed-up your Drupal instance!
[drupalday2017] - Speed-up your Drupal instance!
 
[drupalday2017] - REST in pieces
[drupalday2017] - REST in pieces[drupalday2017] - REST in pieces
[drupalday2017] - REST in pieces
 
Invisiblefarm condivide l'esperienza DrupalGIS
Invisiblefarm condivide l'esperienza DrupalGISInvisiblefarm condivide l'esperienza DrupalGIS
Invisiblefarm condivide l'esperienza DrupalGIS
 
La semantica per automatizzare una redazione web: l'esperienza di Innolabplus.eu
La semantica per automatizzare una redazione web: l'esperienza di Innolabplus.euLa semantica per automatizzare una redazione web: l'esperienza di Innolabplus.eu
La semantica per automatizzare una redazione web: l'esperienza di Innolabplus.eu
 
"Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen...
"Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen..."Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen...
"Twig e i belli dentro": panoramica sui nuovi standard di frontend-developmen...
 
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
 

Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

  • 1.
  • 2. MANTENERE UNA DISTRIBUZIONE DRUPAL ATTRAVERSO TEST COVERAGE PADDLE CASE STUDY https://github.com/brummbar/drupal-day-2015
  • 4. FRANCESCO SARDARA Backend e frontend Email: francesco.sardara@kanooh.be D.o: Sardara
  • 7.
  • 8. FLEMISH GOVERNMENT Framework contract Unico referente per sito web, hosting e supporto; frontend che segue le specifiche di branding del governo Fiammingo; focus sulla gestione dei contenuti (revisioni, workflow); usabilità del backend per utenti non esperti; commenti, multilingua, contatti, quiz, rss, newsletter, protected pages.
  • 10. Sprint di 2 settimane ↓ Soft release ↓ Hard release Rilascio in produzione
  • 12. ANATOMIA DI UN TICKET User story / descrizione bug UAT steps Definition of done
  • 13. DEFINITION OF DONE Functionally complete Automated tests cover UAT instructions Automated Simpletest tests passing within the last 24h Automated Selenium tests passing within the last 24h Working upgrade path from the last release in place ...
  • 14. AUTOMATED TESTS Simpletest e Selenium Shoov.io / Webdrivercss Eseguiti su server tramite Jenkins CI Esecuzioni giornaliere automatiche Esecuzioni manuali per ticket Esecuzione remota su Browserstack
  • 15.
  • 16. SELENIUM automatizzazione di test su applicazioni web ampiamente supportato in svariati linguaggi Selenium IDE e Webdriver
  • 17. COSA TESTIAMO IN SELENIUM funzionalità personalizzate integrazioni tra moduli funzionalità Javascript regressioni
  • 18. QUALCHE NUMERO 746 test 10966 asserzioni tempo di esecuzione di 18 ore richiedono 2/3 del tempo di sviluppo
  • 20. PUNTI CHIAVE riduzione della duplicazione del codice facilità nell’aggiornare la relativa classe se gli elementi della pagina cambiano possibilità di sfruttare appieno i meccanismi di ereditarietà
  • 21. REGOLE solo la classe deve contenere XPath / selettori CSS relativi all’elemento nessuna assertion deve essere fatta all’interno della classe
  • 22. PAGE OBJECT PATTERN IN PADDLE
  • 24.
  • 25. ANATOMIA DI UNA CLASSE PAGE OBJECT
  • 26. Il metodo costruttore contiene sempre una referenza a Webdriver e all'oggetto Selenium. /** * Construct a new GlossaryDefinitionTableRow. * * @param WebDriverTestCase $webdriver * The Selenium web driver test case. * @param PHPUnit_Extensions_Selenium2TestCase_Element $element * The webdriver element of the definition table row. */ public function __construct(WebDriverTestCase $webdriver, $element) { parent::__construct($webdriver); $this->element = $element; }
  • 27. Tutte le proprietà che rappresentano altri Page Object sono gestite tramite magic get. /** * {@inheritdoc} */ public function __get($name) { switch ($name) { case 'saveButton': return $this->element->byXPath('.//input[contains(@id, "edit-save")]' break; case 'definition': return new Text($this->webdriver, $this->element->byName('definition' break; case 'description': return new Wysiwyg($this->webdriver, 'edit-field-glossary-description break; } throw new FormFieldNotDefinedException($name); }
  • 28. PERCHÉ USARE __GET() ? Legacy code Separazione dalle proprietà Linearità di lettura $this->configurePage->go(); $this->configurePage->contextualToolbar->buttonAdd->click(); $modal->form->definition->fill($title); $modal->form->description->setBodyText($description); $modal->form->saveButton->click(); $modal->waitUntilClosed();
  • 29. ESEMPIO DI TEST CASE GlossaryTest.php testGlossaryDefinitionHighlighting
  • 31.
  • 32. SOPRAVVIVERE AI TEST Approcci e best practices
  • 33. RANDOM FAILING TESTS Per RFT si indicano quei test che senza nessun cambiamento nel codice o nei dati di test(*), il loro risultato non è costante. Cause comuni: differenze hardware dati di test
  • 34. IMPLICIT E EXPLICIT WAITS Il tempo di attesa implicito rappresenta per quanto tempo Webdriver deve interrogare il DOM in attesa di trovare un elemento se esso non è disponibile immediatamente. Il tempo di attesa esplicito rappresenta per quanto tempo Webdriver deve aspettare una certa condizione prima di proseguire con l'esecuzione.
  • 35. IMPLICIT WAIT // Add a new definition. $this->configurePage->contextualToolbar->buttonAdd->click(); $modal = new GlossaryDefinitionModal($this); $modal->form->definition->fill('The awesome definition');
  • 36. EXPLICIT WAIT // Add a new definition. $this->configurePage->contextualToolbar->buttonAdd->click(); $modal = new GlossaryDefinitionModal($this); $modal->waitUntilOpened(); $modal->form->definition->fill('The awesome definition'); public function waitUntilOpened() { $callable = new SerializableClosure(...); $this->webdriver->waitUntil($callable, $this->timeout); }
  • 37. RANDOMIZZARE I DATI DI TEST Pro Evitare parzialmente "collisioni" tra contenuti Trovare casi limite Simulare un vero utilizzo del sistema Contro La randomizzazione rende il test non completamente prevedibile
  • 38. L'APPROCCIO DI PADDLE La generazione dei contenuti è randomizzata. I contenuti vengono lasciati intatti a meno che la loro presenza non complichi la realizzazione del test.
  • 40. CKEDITOR /** * Sets the body text. * * @param string $text * The text to enter in the body. */ public function setBodyText($text) { $this->webdriver->byId('cke_' . $this->editorId); $this->webdriver->execute( array( 'script' => "CKEDITOR.instances['{$this->editorId}'].setData('" 'args' => array(), ) ); }
  • 41. AJAX CALLBACKS // ... $form['list_id'] = array( '#type' => 'select', '#title' => t('List'), '#required' => TRUE, '#ajax' => array( 'callback' => 'mailchimp_campaign_list_segment_callback', ), ); // ...
  • 42. /** * Marks the element as if it is waiting for AJAX callbacks. * * @see KanoohPaddlePagesElementFormAutoCompletedText::markAsWaitingForAuto */ public function markAsWaitingForAjaxCallback(PHPUnit_Extensions_Selenium2TestCas { $this->webdriver->execute( array( 'script' => "arguments[0].className += ' progress-disabled';", 'args' => array($element->toWebDriverObject()), ) ); }
  • 43. MASTERING THE STALE // ... $form = $image_pane_type->getForm(); $form->showCaption->check(); // Submit the form and reload the modal. $form->submit(); // Test something else. $form->captionTextArea->fill('Oooops'); // ...
  • 44. EXPLOITING THE STALE // Waits until the current page is loaded. public function waitUntilPageIsLoaded() { $body = $this->bodyElement; $webdriver = $this->webdriver; $callable = new SerializableClosure( function () use ($body, $webdriver) { try { $body->click(); } catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException return true; } } ); $this->webdriver->waitUntil($callable, $this->webdriver->getTimeout()); $this->webdriver->waitUntilElementIsDisplayed('//body'); }
  • 46. RIPETIZIONI MULTIPLE PER EVITARE L'INTRODUZIONE DI RFT $ base_url=http://paddle.dev ./vendor/bin/phpunit --repeat=3 tests/Kanooh/Paddle/App/ContactPerson/EnableDisableTest.php
  • 47. RICONOSCERE LE RFT $ ./vendor/bin/phpunit --repeat=2 --only-repeat-failed tests/
  • 48. VELOCIZZARE L'ESECUZIONE esecuzione in parallelo dei test sfruttare drupal/drupal-driver per rimuovere interazioni browser non necessarie
  • 50. WEBDRIVERCSS Tool di automatizzazione per test di visual regression per WebdriverIO.
  • 51. SHOOV.IO Tool di visual regression e live monitoring. Wrapper per Webdrivercss Headless Drupal per lo storage degli screenshot Angular.js web-app per il confronto visuale Integrazione con Github (login, commits, pull request) Gratuito (?)
  • 52. L'APPROCCIO DI PADDLE AL VR Configuration Single test https://github.com/brummbar/visual-regression
  • 53. Q&A
  • 54. Per domande o suggerimenti, scrivetemi francesco.sardara@kanooh.be