SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
1.
Test Double
UN’INTRODUZIONE DI
CARMELANTONIO ZOLFO
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
0 likes
Be the first to like this
Views
Total views
1,389
On SlideShare
0
From Embeds
0
Number of Embeds
16
You have now unlocked unlimited access to 20M+ documents!
Unlimited Reading
Learn faster and smarter from top experts
Unlimited Downloading
Download to take your learnings offline and on the go
You also get free access to Scribd!
Instant access to millions of ebooks, audiobooks, magazines, podcasts and more.
Read and listen offline with any device.
Free access to premium services like Tuneln, Mubi and more.