Unit Test Fun

Preview:

Citation preview

© 2010 Mayflower GmbH

Max Köhler I 02. Dezember 2010

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Wer macht UnitTests?

2

2007 2008 2009 2010Ohne Titel 1Ohne Titel 2Ohne Titel 3Ohne Titel 4Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Code Coverage?

3

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Wer glaubt, dass die Tests gut sind?

4

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Kann die Qualität gesteigert werden?

5

0%

100%

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Test der kompletten Architektur?

6

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

MVC?

7

View

Controller

Model

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Wie testet Ihr eure Models?

8

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Direkter DB-Zugriff?

9

STOP

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Keine UnitTests!

10

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Integration Tests!

11

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Wie testet Ihr eure Controller?

12

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Routes, Auth-Mock, Session-Mock, ...?

13

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 14

STOP

Keine UnitTests!

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Was wollen wir testen?

15

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 16

Unit Testing

Integration

Testing

System - Integration

Testing

Acceptance

Testing

Regression

Testing

System Testing

Unit Testing

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 17

The goal of unit testing is to isolate each part of the program and show that the individual parts are

correct

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Test Doubles

18

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Stubs

19

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 20

Fake that returns canned data...

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Beispiel für ein Auth-Stub

21

$storageData = array( 'accountId' => 29, 'username' => 'Hugo', 'jid' => 'hugo@example.org');

$storage = $this->getMock('Zend_Auth_Storage_Session', array('read')); $storage->expects($this->any()) ->method('read') ->will($this->returnValue($storageData));

Zend_Auth::getInstance()->setStorage($storage);

// ...

/* * Bei jedem Aufruf wird nun das Mock als Storage * verwendet und dessen Daten ausgelesen */ $session = Zend_Auth::getInstance()->getIdentity();

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Mocks

22

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 23

Spy with expectations...

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Model Mapper Beispiel

24

class Application_Model_GuestbookMapper{ protected $_dbTable;

public function setDbTable(Zend_Db_Table_Abstract $dbTable) { $this->_dbTable = $dbTable; return $this; }

public function getDbTable() { return $this->_dbTable; }

public function getEmail() {} public function getComment() {}

public function save(Application_Model_Guestbook $guestbook) { $data = array( 'email' => $guestbook->getEmail(), 'comment' => $guestbook->getComment(), );

$this->getDbTable()->insert($data); }}

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Testen der save() Funktion

25

class Applicatoin_Model_GuestbookMapperTest extends PHPUnit_Framework_TestCase{ public function testSave() { $modelStub = $this->getMock('Application_Model_Guestbook', array('getEmail', ,getComment'));

$modelStub->expects($this->once()) ->method('getEmail') ->will($this->returnValue('super@email.de'));

$modelStub->expects($this->once()) ->method('getComment') ->will($this->returnValue('super comment'));

$tableMock = $this->getMock('Zend_Db_Table_Abstract', array('insert'), array(), '', false); $tableMock->expects($this->once()) ->method('insert') ->with($this->equalTo(array(

'email' => 'super@email.de', 'comment' => 'super comment')));

$model = new Application_Model_GuestbookMapper(); $model->setDbTable($tableMock); // << MOCK $model->save($modelStub); // << STUB }}

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 26

Spy with expectations...

MockFake that

returns canned data...

Stub

!==

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Fixtures

27

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 28

Set the world up in a known

state ...

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Fixture-Beispiel

29

class Fixture extends PHPUnit_Framework_TestCase{ protected $fixture;

protected function setUp() { $this->fixture = array(); }

public function testEmpty() { $this->assertTrue(empty($this->fixture)); }

public function testPush() { array_push($this->fixture, 'foo'); $this->assertEquals('foo', $this->fixture[0]); }

public function testPop() { array_push($this->fixture, 'foo'); $this->assertEquals('foo', array_pop($this->fixture)); $this->assertTrue(empty($this->fixture)); }}

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Method Stack

30

public static function setUpBeforeClass() { }

protected function setUp() { }

public function testMyTest() { /* TEST */ }

protected function tearDown() { }

protected function onNotSuccessfulTest(Exception $e) { }

public static function tearDownAfterClass() { }

Ablauf

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Test Suite ...

31

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

...wirkt sich auf die Architektur aus.

32

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Wenn nicht...

33

Titel der Präsentation I Mayflower GmbH I xx. Juni 2010 I 34

Developer

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Was kann man machen?

35

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Production Code überarbeiten

36

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Dependency Injection

37

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Bemerkt?

38

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Dependency Injection

39

class Application_Model_GuestbookMapper{ protected $_dbTable;

public function setDbTable(Zend_Db_Table_Abstract $dbTable) { $this->_dbTable = $dbTable; return $this; }

public function getDbTable() { return $this->_dbTable; }

public function getEmail() {} public function getComment() {}

public function save(Application_Model_Guestbook $guestbook) { $data = array( 'email' => $guestbook->getEmail(), 'comment' => $guestbook->getComment(), );

$this->getDbTable()->insert($data); }}

class Application_Model_GuestbookMapper{ protected $_dbTable;

public function setDbTable(Zend_Db_Table_Abstract $dbTable) { $this->_dbTable = $dbTable; return $this; }

public function getDbTable() { return $this->_dbTable; }

public function getEmail() {} public function getComment() {}

public function save(Application_Model_Guestbook $guestbook) { $data = array( 'email' => $guestbook->getEmail(), 'comment' => $guestbook->getComment(), );

$this->getDbTable()->insert($data); }}

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Besser aber ...

40

Titel der Präsentation I Mayflower GmbH I xx. Juni 2010 I 41

... Begeisterung sieht anders aus!

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Was könnte noch helfen?

42

[~~~~~~~~~~]

[~~~~~~~~~~]

Test Driven Development

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

TDD?

43

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Probleme früh erkennen!

44

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Uncle Bob´s

45

Three Rules of TDD

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

“ You are not allowed to write any

production code unless it is to make a failing unit test pass.

46

#1

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 47

“ You are not allowed to write any more of

a unit test than is sufficient to fail; and compilation failures are failures.

#2

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 48

“ You are not allowed to write any more

production code than is sufficient to pass the one failing unit test.

#3

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Und wieder...

49

Titel der Präsentation I Mayflower GmbH I xx. Juni 2010 I 50

Developer

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Und jetzt?

51

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 52

Things get worst before they get

better !

Titel der Präsentation I Mayflower GmbH I xx. Juni 2010 I 53

Monate später...

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Gibts noch was?

54

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I 55

Darf ich vorstellen:„Bug“

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Regression Testing

56

orTest your Bugs!

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Regression Testing

57

class Calculate{ public function divide($dividend, $divisor) { return $dividend / $divisor; }}

1

2 Warning: Division by zero in /srv/phpunit-slides/Calculate.php on line 7

Bug

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Regression Testing

58

Test First!

3

/** * Regression-Test BUG-123 * * @group BUG-123 * * @return void */ public function testDivideByZero() { $calc = new Calculate(); $this->assertEquals(0, $calc->divide(1, 0)); }

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Regression Testing

59

Bugfix

4class Calculate{ public function divide($dividend, $divisor) { if (0 == $divisor) { return 0; } return $dividend / $divisor; }}

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Regression Testing

60

phpunit

5slides$ phpunit --colors --verbose CalculateTest.php PHPUnit 3.5.5 by Sebastian Bergmann.

CalculateTest......

Time: 0 seconds, Memory: 5.25Mb

OK (6 tests, 6 assertions)

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Regression Testing

61

@group

?slides$ phpunit --colors --verbose --group BUG-123 CalculateTest.php PHPUnit 3.5.5 by Sebastian Bergmann.

CalculateTest.

Time: 0 seconds, Memory: 5.25Mb

OK (1 tests, 1 assertions)

?

/** * Regression-Test BUG-123 * * @group BUG-123 * * @return void */ public function testDivideByZero() {

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Noch Fragen?

62

Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection I Mayflower GmbH I 02. Dezember 2010 I

Quellen

63

I Baby: ADDROX http://www.flickr.com/photos/addrox/2587484034/sizes/m/

I Fish: ADDROX http://www.flickr.com/photos/addrox/274632284/sizes/m/

I Happy: ADDROX http://www.flickr.com/photos/addrox/2610064689/sizes/m/

I Bug: ADDROX http://www.flickr.com/photos/addrox/284649644/sizes/m/

Vielen Dank für Ihre Aufmerksamkeit!

© 2010 Mayflower GmbH

Kontakt Max Köhlermax.koehler@mayflower.de+49 89 242054-1160

Mayflower GmbHMannhardtstr. 680538 München

Recommended