• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Il testing con zend framework
 

Il testing con zend framework

on

  • 809 views

Il testing delle applicazioni MVC Zend Framework è spesso visto come una sorta di stregoneria, ma tutto sommato non lo è. In questo seminario web vedremo cosa e come testare, i pattern più comuni ...

Il testing delle applicazioni MVC Zend Framework è spesso visto come una sorta di stregoneria, ma tutto sommato non lo è. In questo seminario web vedremo cosa e come testare, i pattern più comuni per il testing e le possibili difficoltà che si possono incontrare. Verranno trattati inoltre alcuni elementi di base su PHPUnit in modo da fornire concetti fondamentali per l’operatività anche a chi non è esperto di testing.

Statistics

Views

Total Views
809
Views on SlideShare
809
Embed Views
0

Actions

Likes
1
Downloads
6
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Il testing con zend framework Il testing con zend framework Presentation Transcript

    • Il testing con ZendFrameworkEnrico ZimuelSenior Consultant & ArchitectZend Technologies © All rights reserved. Zend Technologies, Inc.
    • Sommario● Introduzione allo Unit Testing in PHP● Le funzionalità di base di test con ZF● Alcuni scenari avanzati di testing con ZF © All rights reserved. Zend Technologies, Inc.
    • Perchè testare il codice? © All rights reserved. Zend Technologies, Inc.
    • Semplificare la manutenzione● Il testing definisce le aspettative● Il testing descrive i comportamenti dellapplicazione● Il testing identifica i cambiamenti nel codice sorgente che violano (“rompono”) i comportamenti attesi del software © All rights reserved. Zend Technologies, Inc.
    • Quantificare la qualità del codice● Copertura del codice (code coverage) effettuata dagli strumenti di testing● I metodi di test documentano i comportamenti attesi del software © All rights reserved. Zend Technologies, Inc.
    • Benefici psicologici per gli sviluppatori Quando il test è ok, gli sviluppatori sono più confidenti e motivati!6 © All rights reserved. Zend Technologies, Inc.
    • Testing non è … ricaricare una pagina7 © All rights reserved. Zend Technologies, Inc.
    • Testing non è … var_dump()8 © All rights reserved. Zend Technologies, Inc.
    • Testing è … riproducibile9 © All rights reserved. Zend Technologies, Inc.
    • Testing è … automatizzabile10 © All rights reserved. Zend Technologies, Inc.
    • In un buon testing …● Si definiscono i comportamenti● Si forniscono esempi su scenari dutilizzo● Si definiscono le aspettative © All rights reserved. Zend Technologies, Inc.
    • PHP testing frameworks● PHPT ▶ Utilizzato da PHP, da PEAR e da alcune librerie indipendenti● SimpleTest ▶ Un framework di testing in stile JUnit● PHPUnit ▶ Un framework di testing in stile JUnit ▶ De facto lo standard di testing in PHP © All rights reserved. Zend Technologies, Inc.
    • Le basi del testing13 © All rights reserved. Zend Technologies, Inc.
    • Scrivere unit test● Creare una classe di test● Creare uno o più metodi che definiscono dei comportamenti ▶ Descrivere il comportamento in un linguaggio naturale● Scrivere codice che definisce il comportamento ▶ Scrivere codice utilizzando lAPI● Scrivere le asserzioni per definire il comportamento atteso © All rights reserved. Zend Technologies, Inc.
    • Creare una classe di test● Solitamente il nome termina per Test class EntryTest class EntryTest extends PHPUnit_Framework_TestCase extends PHPUnit_Framework_TestCase {{ }} © All rights reserved. Zend Technologies, Inc.
    • Scrivere un metodo che definisce ilcomportamento ● prefisso “test”class EntryTest class EntryTest extends PHPUnit_Framework_TestCase extends PHPUnit_Framework_TestCase{{ public function testMaySetTimestampWithString() public function testMaySetTimestampWithString() {{ }}}} © All rights reserved. Zend Technologies, Inc.
    • Scrivere il codice per il comportamentoclass EntryTest class EntryTest extends PHPUnit_Framework_TestCase extends PHPUnit_Framework_TestCase{{ public function testMaySetTimestampWithString() public function testMaySetTimestampWithString() {{ $string = Fri, 7 May 2010 09:26:03 -0700; $string = Fri, 7 May 2010 09:26:03 -0700; $ts $ts = strtotime($string); = strtotime($string); $this->entry->setTimestamp($string); $this->entry->setTimestamp($string); $setValue = $this->entry->getTimestamp(); $setValue = $this->entry->getTimestamp(); }}}} © All rights reserved. Zend Technologies, Inc.
    • Scrivere asserzioni per uncomportamento attesoclass EntryTest class EntryTest extends PHPUnit_Framework_TestCase extends PHPUnit_Framework_TestCase{{ public function testMaySetTimestampWithString() public function testMaySetTimestampWithString() {{ $string = Fri, 7 May 2010 09:26:03 -0700; $string = Fri, 7 May 2010 09:26:03 -0700; $ts $ts = strtotime($string); = strtotime($string); $this->entry->setTimestamp($string); $this->entry->setTimestamp($string); $setValue = $this->entry->getTimestamp(); $setValue = $this->entry->getTimestamp(); $this->assertSame($ts, $setValue); $this->assertSame($ts, $setValue); }}}} © All rights reserved. Zend Technologies, Inc.
    • Eseguire il test● Fallimento? ▶ Verifica il test e le asserzioni per eventuali errori di battitura o casi duso ▶ Verifica la classe che si stà testando ▶ Eseguire le correzioni e rilanciare il test● Successo? ▶ Creare il prossimo test di comportamento o continuare con le modifiche sul codice del software © All rights reserved. Zend Technologies, Inc.
    • Alcuni termini del testing20 © All rights reserved. Zend Technologies, Inc.
    • Test scaffolding● Essere sicuri che lambiente di testing sia libero da pre-requisiti● Inizializzare le dipendenze necessarie per eseguire il test● Di solito linizializzazione dellambiente di test avviene nel metodo setUp() © All rights reserved. Zend Technologies, Inc.
    • Test doubles● Stubs Sostituire un oggetto con un altro per continuare il test● Mock Objects Sostituire un oggetto con un altro forzandone le aspettative (restituendo valori prestabiliti per i metodi) © All rights reserved. Zend Technologies, Inc.
    • Alcune tipologie di test● Testing condizionali Testing solo al verificarsi di alcune condizioni dambiente● Testing funzionali e dintegrazione Testing del sistema per verificare i comportamenti attesi; testing delle unità e delle loro interazioni © All rights reserved. Zend Technologies, Inc.
    • Testing semi-funzionale in Zend Framework24 © All rights reserved. Zend Technologies, Inc.
    • Fasi principali● Setup dellambiente phpUnit● Creare uno scenario di test (TestCase) basato su un Controller (ControllerTestCase)● Bootstrap dellapplicazione● Creazione di una richiesta e dispatch● Eseguire asserzioni sulle risposte © All rights reserved. Zend Technologies, Inc.
    • Lambiente PHPUnit● Struttura delle directory tests tests |-- application |-- application || `-- controllers `-- controllers |-- Bootstrap.php |-- Bootstrap.php |-- library |-- library || `-- Custom `-- Custom `-- phpunit.xml `-- phpunit.xml 4 directories, 2 files 4 directories, 2 files © All rights reserved. Zend Technologies, Inc.
    • Lambiente PHPUnit (2)● phpunit.xml <phpunit bootstrap="./Bootstrap.php"> <phpunit bootstrap="./Bootstrap.php"> <testsuite name="Test Suite"> <testsuite name="Test Suite"> <directory>./</directory> <directory>./</directory> </testsuite> </testsuite> <filter> <filter> <whitelist> <whitelist> <directory <directory suffix=".php">../library/</directory> suffix=".php">../library/</directory> <directory <directory suffix=".php">../application/</directory> suffix=".php">../application/</directory> <exclude> <exclude> <directory <directory suffix=".phtml">../application/</directory> suffix=".phtml">../application/</directory> </exclude> </exclude> </whitelist> </whitelist> </filter> </filter> </phpunit> </phpunit> © All rights reserved. Zend Technologies, Inc.
    • Lambiente PHPUnit (3)● Bootstrap.php $rootPath == realpath(dirname(__DIR__)); $rootPath realpath(dirname(__DIR__)); if (!defined(APPLICATION_PATH)) {{ if (!defined(APPLICATION_PATH)) define(APPLICATION_PATH, define(APPLICATION_PATH, $rootPath .. /application); $rootPath /application); }} if (!defined(APPLICATION_ENV)) {{ if (!defined(APPLICATION_ENV)) define(APPLICATION_ENV, testing); define(APPLICATION_ENV, testing); }} set_include_path(implode(PATH_SEPARATOR, array( set_include_path(implode(PATH_SEPARATOR, array( ., ., $rootPath .. /library, $rootPath /library, get_include_path(), get_include_path(), ))); ))); require_once Zend/Loader/Autoloader.php; require_once Zend/Loader/Autoloader.php; $loader == Zend_Loader_Autoloader::getInstance(); $loader Zend_Loader_Autoloader::getInstance(); $loader->registerNamespace(Custom_); $loader->registerNamespace(Custom_); © All rights reserved. Zend Technologies, Inc.
    • Creare una classe di test● Estendere la Zend_Test_PHPUnit_ControllerTestCase class ExampleControllerTest class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {{ }} © All rights reserved. Zend Technologies, Inc.
    • Bootstrap dellapplicazione● Creare unistanza di Zend_Application e referenziarla nel setUp() class ExampleControllerTest class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {{ public function setUp() public function setUp() {{ $this->bootstrap = new Zend_Application( $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_ENV, APPLICATION_PATH APPLICATION_PATH . /configs/application.ini . /configs/application.ini ); ); parent::setUp(); parent::setUp(); }} }} © All rights reserved. Zend Technologies, Inc.
    • Creazione e dispatch di una richiesta● Metodo semplice: dispatch di una “url”class ExampleControllerTest class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase{{ // ... // ... public function testStaticPageHasGoodStructure() public function testStaticPageHasGoodStructure() {{ $this->dispatch(/example/page); $this->dispatch(/example/page); // ... // ... }}}} © All rights reserved. Zend Technologies, Inc.
    • Creazione e dispatch di una richiesta (2)● Avanzato: personalizzare loggetto della richiesta prima di eseguire il dispatch class ExampleControllerTest class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {{ // ... // ... public function testXhrRequestReturnsJson() public function testXhrRequestReturnsJson() {{ $this->getRequest() $this->getRequest() ->setHeader(X-Requested-With, ->setHeader(X-Requested-With, XMLHttpRequest) XMLHttpRequest) ->setQuery(format, json); ->setQuery(format, json); $this->dispatch(/example/xhr-endpoint); $this->dispatch(/example/xhr-endpoint); // ... // ... }} }} © All rights reserved. Zend Technologies, Inc.
    • Creare asserzioni● Tipiche asserzioni: ▶ Verifica della struttura della risposta e dei markup Utilizzando selettori CSS o query XPath ▶ Verificare il codice della risposta HTTP o lheader di pagina ▶ Verificare artefatti sulla richiesta e sulla risposta © All rights reserved. Zend Technologies, Inc.
    • Asserzioni con selettori CSS● assertQuery($path, $message = )● assertQueryContentContains( $path, $match, $message = )● assertQueryContentRegex( $path, $pattern, $message = )● assertQueryCount($path, $count, $message = )● assertQueryCountMin($path, $count, $message = )● assertQueryCountMax($path, $count, $message = )● ognuna ha una variante "Not" © All rights reserved. Zend Technologies, Inc.
    • Asserzioni con selettori XPath● assertXpath($path, $message = )● assertXpathContentContains( $path, $match, $message = )● assertXpathContentRegex( $path, $pattern, $message = )● assertXpathCount($path, $count, $message = )● assertXpathCountMin($path, $count, $message = )● assertXpathCountMax($path, $count, $message = )● ognuna ha una variante "Not" © All rights reserved. Zend Technologies, Inc.
    • Asserzioni su Redirect● assertRedirect($message = )● assertRedirectTo($url, $message = )● assertRedirectRegex($pattern, $message = )● ognuna ha una variante "Not" © All rights reserved. Zend Technologies, Inc.
    • Asserzioni sulle risposte● assertResponseCode($code, $message = )● assertHeader($header, $message = )● assertHeaderContains($header, $match, $message = )● assertHeaderRegex($header, $pattern, $message = )● ognuna ha una variante "Not" © All rights reserved. Zend Technologies, Inc.
    • Asserzioni sulle richieste● assertModule($module, $message = )● assertController($controller, $message = )● assertAction($action, $message = )● assertRoute($route, $message = )● ognuna ha una variante "Not" © All rights reserved. Zend Technologies, Inc.
    • Esempi di asserzionipublic function testSomeStaticPageHasGoodStructure() public function testSomeStaticPageHasGoodStructure(){{ $this->dispatch(/example/page); $this->dispatch(/example/page); $this->assertResponseCode(200); $this->assertResponseCode(200); $this->assertQuery(div#content p); $this->assertQuery(div#content p); $this->assertQueryCount(div#sidebar ul li, 3); $this->assertQueryCount(div#sidebar ul li, 3);}} © All rights reserved. Zend Technologies, Inc.
    • Esempi di asserzioni (2) public function testXhrRequestReturnsJson() public function testXhrRequestReturnsJson() {{ // ... // ... $this->assertNotRedirect(); $this->assertNotRedirect(); $this->assertHeaderContains( $this->assertHeaderContains( Content-Type, application/json); Content-Type, application/json); }} © All rights reserved. Zend Technologies, Inc.
    • Alcuni casi avanzati di testing41 © All rights reserved. Zend Technologies, Inc.
    • Testing di modelli e risorse● Problema: Queste classi non vengono caricate con il sistema di autoloading● Soluzione: Utilizzare il bootstrap di Zend_Application per caricare manualmente le risorse durante il setUp() © All rights reserved. Zend Technologies, Inc.
    • Esempio class Blog_Model_EntryTest class Blog_Model_EntryTest extends PHPUnit_Framework_TestCase extends PHPUnit_Framework_TestCase {{ public function setUp() public function setUp() {{ $this->bootstrap = new Zend_Application( $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_ENV, APPLICATION_PATH APPLICATION_PATH . /configs/application.ini . /configs/application.ini ); ); $this->bootstrap->bootstrap(modules); $this->bootstrap->bootstrap(modules); $this->model = new Blog_Model_Entry(); $this->model = new Blog_Model_Entry(); }} }} © All rights reserved. Zend Technologies, Inc.
    • Testing con autenticazione● Problema: Alcune azioni possono richiedere unautenticazione utente, come emularla in fase di testing?● Soluzione: Eseguire unautenticazione manuale utilizzando Zend_Auth prima di eseguire il dispatch() © All rights reserved. Zend Technologies, Inc.
    • Esempio class ExampleControllerTest class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {{ // ... // ... public function loginUser($user) public function loginUser($user) {{ $params = array(user => $user); $params = array(user => $user); $adapter = new Custom_Auth_TestAdapter( $adapter = new Custom_Auth_TestAdapter( $params); $params); $auth $auth = Zend_Auth::getInstance(); = Zend_Auth::getInstance(); $auth->authenticate($adapter); $auth->authenticate($adapter); $this->assertTrue($auth->hasIdentity()); $this->assertTrue($auth->hasIdentity()); }} }} © All rights reserved. Zend Technologies, Inc.
    • Esempio (2) class ExampleControllerTest class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {{ // ... // ... public function testAdminUserCanAccessAdmin() public function testAdminUserCanAccessAdmin() {{ $this->loginUser(admin); $this->loginUser(admin); $this->dispatch(/example/admin); $this->dispatch(/example/admin); $this->assertQuery(div#content.admin); $this->assertQuery(div#content.admin); }} © All rights reserved. Zend Technologies, Inc.
    • Testing di pagine che dipendono daaltre azioni● Problema: Alcune azioni possono dipendere dallesito di altre, ad esempio una pagina che evidenzia I risultati di unoperazione di ricerca● Soluzione: Eseguire un doppio dispatch, resettando la richiesta tra una chiamata e laltra © All rights reserved. Zend Technologies, Inc.
    • Esempioclass ExampleControllerTest class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase{{ // ... // ... public function testHighlightedTextAfterSearch() public function testHighlightedTextAfterSearch() {{ $this->getRequest()->setQuery( $this->getRequest()->setQuery( search, foobar); search, foobar); $this->dispatch(/search); $this->dispatch(/search); $this->resetRequest(); $this->resetRequest(); $this->resetResponse(); $this->resetResponse(); $this->dispatch(/example/page); $this->dispatch(/example/page); $this->assertQueryContains( $this->assertQueryContains( span.highlight, foobar); span.highlight, foobar); }} © All rights reserved. Zend Technologies, Inc.
    • Conclusioni49 © All rights reserved. Zend Technologies, Inc.
    • Eseguire sempre il test!● Test dei modelli, dei livelli di servizio, etc● Eseguire test funzionali e di accettazione per il workflow dellapplicazione, per la struttura delle pagine, etc● Testing = Scrivere codice migliore, più affidabile e di qualità © All rights reserved. Zend Technologies, Inc.
    • Grazie!Per maggiori informazioni:http://www.zend.comhttp://framework.zend.com © All rights reserved. Zend Technologies, Inc.