Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

56

Transcript of Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

Page 1: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study
Page 2: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

MANTENERE UNA DISTRIBUZIONE DRUPALATTRAVERSO TEST COVERAGE

PADDLE CASE STUDY

https://github.com/brummbar/drupal-day-2015

Page 3: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

ABOUT ME

Page 4: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

FRANCESCO SARDARA

Backend e frontend

Email:[email protected]: Sardara

Page 5: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

PER CHI LAVORO

Page 6: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

COSA È PADDLE

Page 7: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study
Page 8: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

FLEMISH GOVERNMENTFramework contract

Unico referente per sito web, hosting e supporto;frontend che segue le specifiche di branding del governoFiammingo;focus sulla gestione dei contenuti (revisioni, workflow);usabilità del backend per utenti non esperti;commenti, multilingua, contatti, quiz, rss, newsletter,protected pages.

Page 9: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

WORKFLOW DI LAVORO

Page 10: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

Sprint di 2 settimane↓

Soft release↓

Hard releaseRilascio in produzione

Page 11: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

ORGANIZZAZIONE DELLO SPRINTOpen/ReopenedDevelopmentTestingQAUAT

Page 12: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

ANATOMIA DI UN TICKETUser story / descrizione bugUAT stepsDefinition of done

Page 13: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

DEFINITION OF DONEFunctionally completeAutomated tests cover UAT instructionsAutomated Simpletest tests passing within the last 24hAutomated Selenium tests passing within the last 24hWorking upgrade path from the last release in place...

Page 14: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

AUTOMATED TESTSSimpletest e SeleniumShoov.io / WebdrivercssEseguiti su server tramite Jenkins CI

Esecuzioni giornaliere automaticheEsecuzioni manuali per ticket

Esecuzione remota su Browserstack

Page 15: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study
Page 16: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

SELENIUMautomatizzazione di test su applicazioni webampiamente supportato in svariati linguaggiSelenium IDE e Webdriver

Page 17: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

COSA TESTIAMO IN SELENIUMfunzionalità personalizzateintegrazioni tra modulifunzionalità Javascriptregressioni

Page 18: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

QUALCHE NUMERO746 test10966 asserzionitempo di esecuzione di 18 orerichiedono 2/3 del tempo di sviluppo

Page 19: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

PAGE OBJECT PATTERN

Page 20: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

PUNTI CHIAVEriduzione della duplicazione del codicefacilità nell’aggiornare la relativa classe se gli elementidella pagina cambianopossibilità di sfruttare appieno i meccanismi di ereditarietà

Page 21: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

REGOLEsolo la classe deve contenere XPath / selettori CSSrelativi all’elementonessuna assertion deve essere fatta all’interno dellaclasse

Page 22: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

PAGE OBJECT PATTERN INPADDLE

Page 23: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

STRUTTURA CARTELLE

Page 24: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study
Page 25: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

ANATOMIA DI UNA CLASSE PAGE OBJECT

Page 26: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

Il metodo costruttore contiene sempre una referenza aWebdriver 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; }

Page 27: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

Tutte le proprietà che rappresentano altri Page Object sonogestite 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-und-0-value' break; } throw new FormFieldNotDefinedException($name); }

Page 28: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

PERCHÉ USARE __GET() ?Legacy codeSeparazione 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();

Page 30: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

RISULTATO DEL TEST

Page 31: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study
Page 32: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

SOPRAVVIVERE AI TESTApprocci e best practices

Page 33: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

RANDOM FAILING TESTSPer RFT si indicano quei test che senza nessun

cambiamento nel codice o nei dati di test(*), il loro risultatonon è costante.Cause comuni:

differenze hardwaredati di test

Page 34: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

IMPLICIT E EXPLICIT WAITSIl tempo di attesa implicito rappresenta per quanto tempoWebdriver deve interrogare il DOM in attesa di trovare un

elemento se esso non è disponibile immediatamente.Il tempo di attesa esplicito rappresenta per quanto tempoWebdriver deve aspettare una certa condizione prima di

proseguire con l'esecuzione.

Page 35: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

IMPLICIT WAIT// Add a new definition. $this->configurePage->contextualToolbar->buttonAdd->click(); $modal = new GlossaryDefinitionModal($this); $modal->form->definition->fill('The awesome definition');

Page 36: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

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); }

Page 37: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

RANDOMIZZARE I DATI DI TESTPro

Evitare parzialmente "collisioni"tra contenutiTrovare casi limiteSimulare un vero utilizzo delsistema

Contro

La randomizzazione rende iltest non completamenteprevedibile

Page 38: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

L'APPROCCIO DI PADDLELa generazione dei contenuti è randomizzata.I contenuti vengono lasciati intatti a meno che la loropresenza non complichi la realizzazione del test.

Page 39: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

SOPRAVVIVERE AI TEST(REPRISE)

Approcci in Paddle

Page 40: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

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(), ) ); }

Page 41: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

AJAX CALLBACKS// ... $form['list_id'] = array( '#type' => 'select', '#title' => t('List'), '#required' => TRUE, '#ajax' => array( 'callback' => 'mailchimp_campaign_list_segment_callback', ), ); // ...

Page 42: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

/** * Marks the element as if it is waiting for AJAX callbacks. * * @see \Kanooh\Paddle\Pages\Element\Form\AutoCompletedText::markAsWaitingForAutoCompleteResults() */ public function markAsWaitingForAjaxCallback(\PHPUnit_Extensions_Selenium2TestCase_Element { $this->webdriver->execute( array( 'script' => "arguments[0].className += ' progress-disabled';", 'args' => array($element->toWebDriverObject()), ) ); }

Page 43: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

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'); // ...

Page 44: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

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'); }

Page 45: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

IMPROVING SELENIUMRESULTS

Page 46: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

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

Page 47: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

RICONOSCERE LE RFT$ ./vendor/bin/phpunit --repeat=2 --only-repeat-failed tests/

Page 48: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

VELOCIZZARE L'ESECUZIONEesecuzione in parallelo dei testsfruttare drupal/drupal-driver per rimuovere interazionibrowser non necessarie

Page 49: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

VISUAL REGRESSIONWEBDRIVERCSS E SHOOV.IO

Page 50: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

WEBDRIVERCSSTool di automatizzazione per test di visual regression per

WebdriverIO.

Page 51: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

SHOOV.IOTool di visual regression e live monitoring.

Wrapper per WebdrivercssHeadless Drupal per lo storage degli screenshotAngular.js web-app per il confronto visualeIntegrazione con Github (login, commits, pull request)Gratuito (?)

Page 53: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

Q&A

Page 54: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

Per domande o suggerimenti, [email protected]

Page 55: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study

GRAZIE PERL'ATTENZIONE.

Page 56: Mantenere una distribuzione Drupal attraverso test coverage: Paddle case study