Test double - un'introduzione (PHP)

Carmelantonio Zolfo
Carmelantonio ZolfoIT specialist 2nd level at IBM
Test Double
UN’INTRODUZIONE DI
CARMELANTONIO ZOLFO
TDD, un breve riepilogo
 Test Driven Development: metodologia di sviluppo

software che antepone la stesura di test allo sviluppo
reale delle funzionalità.
 Come?
Scrivo test che
fallisce e lo
eseguo

Rifattorizzo il
codice

Scrivo codice che
soddisfi il test
TDD, un breve riepilogo
 Perché scrivere prima il test?
 Previene/fa regredire/mette in luce bug;
 Assicura copertura del codice;
 Permette di comprendere finalità e modalità della

funzione testata;
 Permette refactoring, sperimentazioni e
cambiamenti nel codice preesistente
TDD, un breve riepilogo
 Come deve essere un buon test?
 Automatizzato;
 Isolato;
 Ripetibile;
 Facile da scrivere, leggere => facile da mantenere
Fasi di un test

 SUT: system under test (classe, oggetto o metodo testato)
Fasi di un test

VS metodo scientifico

 Ipotesi
 Tesi
 Dimostrazione
Test classico 1/2
class OrderTest extends PHPUnit_Framework_TestCase {
const DISARONNO = ‘Amaretto di Saronno’;
const BACARDI = ‘Bacardi Superior’;
private $warehouse;
public function setUp()
{
$this->warehouse = new Warehouse();
$this->warehouse->add(self::DISARONNO, 50);
$this->warehouse->add(self::BACARDI, 25);
}
public function testFillingRemovesInventoryIfInStock()
{
$order = new Order(self::DISARONNO, 50); //fase setup II parte
$order->fill($this->warehouse); //fase exercise
$this->assertTrue($order->isFilled()); //fase verification
$this->assertCount(0, $this->warehouse->getInventory(self::DISARONNO));
}
Test classico 2/2
public function testFillingRemovesInventoryIfInStock()
{
$order = new Order(self::DISARONNO, 51);
$order->fill($this->warehouse);
$this->assertFalse($order->isFilled());
$this->assertCount(50, $this->warehouse->getInventory(self::DISARONNO));
}
}
Test Double
Test Double, quando entrano in gioco?
Indirect output

Indirect input

 DOC: depended on component
Test Double, quando entrano in gioco?
Indirect output

Indirect input

 Il Test Double sostituisce il DOC in fase di test
Test Double, varianti
 Dummy Object: un placeholder passato al SUT ma





mai utilizzato
Test Stub: sostituisce un DOC per avere un punto di
controllo sugli indirect input necessari al SUT
Test Spy: offre un punto di osservazione sugli
indirect input necessari al SUT
Mock Object: costituisce un punto di osservazione
sugli indirect output erogati dal SUT
Fake Object: sostituisce le funzionalità di un DOC
con una implementazione semplificata senza fornire
controllo sugli indirect input/output del SUT
Test Double – Mock 1/2
class OrderTest extends PHPUnit_Framework_TestCase
{
const DISARONNO = ‘Amaretto di Saronno’;
public function testFillingRemovesInventoryIfInStock()
{
//setup - dati
$order = new Order(self::DISARONNO, 50);
$warehouseMock = $this->getMock('Warehouse', array('hasInventory', 'remove'));

$warehouseMock->expects($this->at(0)) //setup - expectations
->method('hasInventory')
->with($this->equalTo(self::DISARONNO), $this->equalTo(50)) //indirect output
->will($this->returnValue(true)); //indirect input
$order->fill($warehouseMock); //exercise
Test Double – Mock 2/2
$this->assertTrue($order->isFilled()); //verify
}
public function testFillingDoesNotRemoveIfNotEnoughInStock() {
$order = new Order(self::DISARONNO, 51);
$warehouseMock = $this->getMock('Warehouse', array('hasInventory'));
$warehouseMock->expects($this->once())
->method("hasInventory”)
->will($this->returnValue(false));
$order->fill($warehouseMock);

$this->assertFalse($order->isFilled());
}
}
Test Double – Stub 1/2
interface MailService {
public function send (Message $msg);
}
class MailServiceStub implements MailService {
private $messages = array();
public function send (Message $msg)
{
$this->messages[] = $msg;
}
public function numberSent()
{
return count($this->messages);
}
}
Test Double – Stub 2/2
class OrderTest extends PHPUnit_Framework_TestCase
{
…
public function testOrderSendsMailIfUnfilled() {
$order = new Order(self::DISARONNO, 51);
...
$mailServiceStub = new MailServiceStub();
$order->setMailer($mailServiceStub);
$order->fill($warehouse);
$this->assertEquals(1, $mailer->numberSent());
}
}
Test Double – Stub vs Mock as Spy
class OrderTest extends PHPUnit_Framework_TestCase
{
…
public function testOrderSendsMailIfUnfilled() {
$order = new Order(self::DISARONNO, 51);
…
$mailServiceMock = $this->getMock('MailService', array('send'));

$order->setMailer($mailServiceMock);
$mailServiceMock->expects($this->once())
->method("send");

$order->fill($warehouse);
}
}
Credits & Contacts
 PHPUnit – manuale - http://phpunit.de/manual/
 xUnit Patterns – Test Double, Gerard Meszaros -

http://xunitpatterns.com/Test%20Double.html
 Mocks arent Stubs, Martin Fowler -

http://martinfowler.com/articles/mocksArentStubs.html

Test Double, un’introduzione
di Carmelantonio Zolfo
carmelantonio.zolfo@gmail.com
1 of 18

Recommended

Googletest, tdd e mock by
Googletest, tdd e mockGoogletest, tdd e mock
Googletest, tdd e mockyuroller
224 views33 slides
Java codestyle & tipstricks by
Java codestyle & tipstricksJava codestyle & tipstricks
Java codestyle & tipstricksDomenico Briganti
564 views67 slides
Js intro by
Js introJs intro
Js introDaniele Cruciani
358 views26 slides
Consigli per iniziare tdd by
Consigli per iniziare tddConsigli per iniziare tdd
Consigli per iniziare tddTassoman ☺
833 views19 slides
Javaday 2006: Java 5 by
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5Matteo Baccan
634 views35 slides
iContract by
iContractiContract
iContractguest891383
296 views29 slides

More Related Content

What's hot

Applicazioni native in java by
Applicazioni native in javaApplicazioni native in java
Applicazioni native in javaFederico Paparoni
1K views23 slides
Dispensa di PL-SQL by
Dispensa di PL-SQLDispensa di PL-SQL
Dispensa di PL-SQLAntonio Tandoi
64 views11 slides
Java 8 by
Java 8Java 8
Java 8alessiostalla
1.5K views34 slides
Odoo connector PyCon 2015 by
Odoo connector  PyCon 2015Odoo connector  PyCon 2015
Odoo connector PyCon 2015Franco Tampieri
651 views21 slides
Lezione 12 (28 marzo 2012) by
Lezione 12 (28 marzo 2012)Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)STELITANO
214 views33 slides
Assembly and Reverse Engineering by
Assembly and Reverse EngineeringAssembly and Reverse Engineering
Assembly and Reverse Engineeringluigi capuzzello
1.6K views25 slides

Similar to Test double - un'introduzione (PHP)

Unit testing 101 by
Unit testing 101Unit testing 101
Unit testing 101Daniel Londero
707 views61 slides
TDD in WordPress by
TDD in WordPressTDD in WordPress
TDD in WordPresslucatume
2K views43 slides
Introduzione al Test Driven Development by
Introduzione al Test Driven DevelopmentIntroduzione al Test Driven Development
Introduzione al Test Driven DevelopmentEnnio Masi
2K views61 slides
Testing by
TestingTesting
TestingDomenico Briganti
681 views53 slides
Il testing con zend framework by
Il testing con zend frameworkIl testing con zend framework
Il testing con zend frameworkZend by Rogue Wave Software
596 views51 slides
Il testing con zend framework by
Il testing con zend frameworkIl testing con zend framework
Il testing con zend frameworkZend by Rogue Wave Software
545 views51 slides

Similar to Test double - un'introduzione (PHP)(20)

TDD in WordPress by lucatume
TDD in WordPressTDD in WordPress
TDD in WordPress
lucatume2K views
Introduzione al Test Driven Development by Ennio Masi
Introduzione al Test Driven DevelopmentIntroduzione al Test Driven Development
Introduzione al Test Driven Development
Ennio Masi2K views
Mocking Objects Practices by GrUSP
Mocking Objects PracticesMocking Objects Practices
Mocking Objects Practices
GrUSP589 views
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua... by Alessandro Alpi
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...
Alessandro Alpi357 views
Software Testing & Test Driven Development by Sergio Santoro
Software Testing & Test Driven DevelopmentSoftware Testing & Test Driven Development
Software Testing & Test Driven Development
Sergio Santoro970 views
Sql Injection: attacchi e rimedi by Davide Micale
Sql Injection: attacchi e rimediSql Injection: attacchi e rimedi
Sql Injection: attacchi e rimedi
Davide Micale405 views
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ... by Davide Cerbo
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...
Davide Cerbo467 views
PASS Virtual Chapter - SQL Server Continuous Integration by Alessandro Alpi
PASS Virtual Chapter - SQL Server Continuous IntegrationPASS Virtual Chapter - SQL Server Continuous Integration
PASS Virtual Chapter - SQL Server Continuous Integration
Alessandro Alpi198 views
Introduzione a Node.js by Michele Capra
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.js
Michele Capra1.2K views
CONTINUOUS INTEGRATION CON SQL SERVER by DotNetCampus
CONTINUOUS INTEGRATION CON SQL SERVERCONTINUOUS INTEGRATION CON SQL SERVER
CONTINUOUS INTEGRATION CON SQL SERVER
DotNetCampus294 views
DotNetCampus - Continuous Integration con Sql Server by Alessandro Alpi
DotNetCampus - Continuous Integration con Sql ServerDotNetCampus - Continuous Integration con Sql Server
DotNetCampus - Continuous Integration con Sql Server
Alessandro Alpi524 views

Test double - un'introduzione (PHP)

  • 2. TDD, un breve riepilogo  Test Driven Development: metodologia di sviluppo software che antepone la stesura di test allo sviluppo reale delle funzionalità.  Come? Scrivo test che fallisce e lo eseguo Rifattorizzo il codice Scrivo codice che soddisfi il test
  • 3. TDD, un breve riepilogo  Perché scrivere prima il test?  Previene/fa regredire/mette in luce bug;  Assicura copertura del codice;  Permette di comprendere finalità e modalità della funzione testata;  Permette refactoring, sperimentazioni e cambiamenti nel codice preesistente
  • 4. TDD, un breve riepilogo  Come deve essere un buon test?  Automatizzato;  Isolato;  Ripetibile;  Facile da scrivere, leggere => facile da mantenere
  • 5. Fasi di un test  SUT: system under test (classe, oggetto o metodo testato)
  • 6. Fasi di un test VS metodo scientifico  Ipotesi  Tesi  Dimostrazione
  • 7. Test classico 1/2 class OrderTest extends PHPUnit_Framework_TestCase { const DISARONNO = ‘Amaretto di Saronno’; const BACARDI = ‘Bacardi Superior’; private $warehouse; public function setUp() { $this->warehouse = new Warehouse(); $this->warehouse->add(self::DISARONNO, 50); $this->warehouse->add(self::BACARDI, 25); } public function testFillingRemovesInventoryIfInStock() { $order = new Order(self::DISARONNO, 50); //fase setup II parte $order->fill($this->warehouse); //fase exercise $this->assertTrue($order->isFilled()); //fase verification $this->assertCount(0, $this->warehouse->getInventory(self::DISARONNO)); }
  • 8. Test classico 2/2 public function testFillingRemovesInventoryIfInStock() { $order = new Order(self::DISARONNO, 51); $order->fill($this->warehouse); $this->assertFalse($order->isFilled()); $this->assertCount(50, $this->warehouse->getInventory(self::DISARONNO)); } }
  • 10. Test Double, quando entrano in gioco? Indirect output Indirect input  DOC: depended on component
  • 11. Test Double, quando entrano in gioco? Indirect output Indirect input  Il Test Double sostituisce il DOC in fase di test
  • 12. Test Double, varianti  Dummy Object: un placeholder passato al SUT ma     mai utilizzato Test Stub: sostituisce un DOC per avere un punto di controllo sugli indirect input necessari al SUT Test Spy: offre un punto di osservazione sugli indirect input necessari al SUT Mock Object: costituisce un punto di osservazione sugli indirect output erogati dal SUT Fake Object: sostituisce le funzionalità di un DOC con una implementazione semplificata senza fornire controllo sugli indirect input/output del SUT
  • 13. Test Double – Mock 1/2 class OrderTest extends PHPUnit_Framework_TestCase { const DISARONNO = ‘Amaretto di Saronno’; public function testFillingRemovesInventoryIfInStock() { //setup - dati $order = new Order(self::DISARONNO, 50); $warehouseMock = $this->getMock('Warehouse', array('hasInventory', 'remove')); $warehouseMock->expects($this->at(0)) //setup - expectations ->method('hasInventory') ->with($this->equalTo(self::DISARONNO), $this->equalTo(50)) //indirect output ->will($this->returnValue(true)); //indirect input $order->fill($warehouseMock); //exercise
  • 14. Test Double – Mock 2/2 $this->assertTrue($order->isFilled()); //verify } public function testFillingDoesNotRemoveIfNotEnoughInStock() { $order = new Order(self::DISARONNO, 51); $warehouseMock = $this->getMock('Warehouse', array('hasInventory')); $warehouseMock->expects($this->once()) ->method("hasInventory”) ->will($this->returnValue(false)); $order->fill($warehouseMock); $this->assertFalse($order->isFilled()); } }
  • 15. Test Double – Stub 1/2 interface MailService { public function send (Message $msg); } class MailServiceStub implements MailService { private $messages = array(); public function send (Message $msg) { $this->messages[] = $msg; } public function numberSent() { return count($this->messages); } }
  • 16. Test Double – Stub 2/2 class OrderTest extends PHPUnit_Framework_TestCase { … public function testOrderSendsMailIfUnfilled() { $order = new Order(self::DISARONNO, 51); ... $mailServiceStub = new MailServiceStub(); $order->setMailer($mailServiceStub); $order->fill($warehouse); $this->assertEquals(1, $mailer->numberSent()); } }
  • 17. Test Double – Stub vs Mock as Spy class OrderTest extends PHPUnit_Framework_TestCase { … public function testOrderSendsMailIfUnfilled() { $order = new Order(self::DISARONNO, 51); … $mailServiceMock = $this->getMock('MailService', array('send')); $order->setMailer($mailServiceMock); $mailServiceMock->expects($this->once()) ->method("send"); $order->fill($warehouse); } }
  • 18. Credits & Contacts  PHPUnit – manuale - http://phpunit.de/manual/  xUnit Patterns – Test Double, Gerard Meszaros - http://xunitpatterns.com/Test%20Double.html  Mocks arent Stubs, Martin Fowler - http://martinfowler.com/articles/mocksArentStubs.html Test Double, un’introduzione di Carmelantonio Zolfo carmelantonio.zolfo@gmail.com