64
© 2010 Mayflower GmbH Max Köhler I 02. Dezember 2010 Unit Test Fun: Mock Objects, Fixtures, Stubs & Dependency Injection

Unit Test Fun

Embed Size (px)

Citation preview

Page 1: Unit Test Fun

© 2010 Mayflower GmbH

Max Köhler I 02. Dezember 2010

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

Page 2: Unit Test Fun

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

Wer macht UnitTests?

2

Page 3: Unit Test Fun

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

Page 4: Unit Test Fun

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

Page 5: Unit Test Fun

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%

Page 6: Unit Test Fun

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

Test der kompletten Architektur?

6

Page 7: Unit Test Fun

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

MVC?

7

View

Controller

Model

Page 8: Unit Test Fun

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

Wie testet Ihr eure Models?

8

Page 9: Unit Test Fun

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

Direkter DB-Zugriff?

9

Page 10: Unit Test Fun

STOP

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

Keine UnitTests!

10

Page 11: Unit Test Fun

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

Integration Tests!

11

Page 12: Unit Test Fun

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

Wie testet Ihr eure Controller?

12

Page 13: Unit Test Fun

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

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

13

Page 14: Unit Test Fun

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

STOP

Keine UnitTests!

Page 15: Unit Test Fun

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

Was wollen wir testen?

15

Page 16: Unit Test Fun

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

Page 17: Unit Test Fun

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

Page 18: Unit Test Fun

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

Test Doubles

18

Page 19: Unit Test Fun

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

Stubs

19

Page 20: Unit Test Fun

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

Fake that returns canned data...

Page 21: Unit Test Fun

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' => '[email protected]');

$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();

Page 22: Unit Test Fun

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

Mocks

22

Page 23: Unit Test Fun

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

Spy with expectations...

Page 24: Unit Test Fun

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

Page 25: Unit Test Fun

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('[email protected]'));

$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' => '[email protected]', 'comment' => 'super comment')));

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

Page 26: Unit Test Fun

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

!==

Page 27: Unit Test Fun

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

Fixtures

27

Page 28: Unit Test Fun

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 ...

Page 29: Unit Test Fun

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

Page 30: Unit Test Fun

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

Page 31: Unit Test Fun

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

Test Suite ...

31

Page 32: Unit Test Fun

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

...wirkt sich auf die Architektur aus.

32

Page 33: Unit Test Fun

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

Wenn nicht...

33

Page 34: Unit Test Fun

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

Developer

Page 35: Unit Test Fun

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

Was kann man machen?

35

Page 36: Unit Test Fun

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

Production Code überarbeiten

36

Page 37: Unit Test Fun

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

Dependency Injection

37

Page 38: Unit Test Fun

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

Bemerkt?

38

Page 39: Unit Test Fun

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

Page 40: Unit Test Fun

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

Besser aber ...

40

Page 41: Unit Test Fun

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

... Begeisterung sieht anders aus!

Page 42: Unit Test Fun

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

Was könnte noch helfen?

42

Page 43: Unit Test Fun

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

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

Test Driven Development

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

TDD?

43

Page 44: Unit Test Fun

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

Probleme früh erkennen!

44

Page 45: Unit Test Fun

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

Page 46: Unit Test Fun

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

Page 47: Unit Test Fun

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

Page 48: Unit Test Fun

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

Page 49: Unit Test Fun

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

Und wieder...

49

Page 50: Unit Test Fun

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

Developer

Page 51: Unit Test Fun

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

Und jetzt?

51

Page 52: Unit Test Fun

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 !

Page 53: Unit Test Fun

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

Monate später...

Page 54: Unit Test Fun

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

Gibts noch was?

54

Page 55: Unit Test Fun

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

Darf ich vorstellen:„Bug“

Page 56: Unit Test Fun

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

Regression Testing

56

orTest your Bugs!

Page 57: Unit Test Fun

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

Page 58: Unit Test Fun

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

Page 59: Unit Test Fun

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

Page 60: Unit Test Fun

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)

Page 61: Unit Test Fun

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() {

Page 62: Unit Test Fun

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

Noch Fragen?

62

Page 63: Unit Test Fun

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/

Page 64: Unit Test Fun

Vielen Dank für Ihre Aufmerksamkeit!

© 2010 Mayflower GmbH

Kontakt Max Kö[email protected]+49 89 242054-1160

Mayflower GmbHMannhardtstr. 680538 München