unit-testing bad-practices by example
TRANSCRIPT
![Page 1: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/1.jpg)
Unit-Testing Bad-Practicesby Example
Benjamin Eberlei
direkt effekt GmbH
August 2009
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 1 / 49
![Page 2: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/2.jpg)
About Me
I Benjamin Eberlei
I direkt effekt GmBH (digital marketing)
I Zend Framework contributor
I Test-Driven-Development, Legacy Testing
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 2 / 49
![Page 3: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/3.jpg)
And You?
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 3 / 49
![Page 4: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/4.jpg)
Why Test Quality Matters
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 4 / 49
![Page 5: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/5.jpg)
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 5 / 49
“We spent 90% of the time
modifying existing tests to
acommodate for a relatively
minor change.“
(G. Meszaros, xUnit Test Patterns)
![Page 6: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/6.jpg)
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 6 / 49
“Walking on water and
developing software from a
specification are easy if both
are frozen.”
(Edward V. Berard)
![Page 7: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/7.jpg)
Safety Net vs Dead Weight
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 7 / 49
![Page 8: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/8.jpg)
Test Smells
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 8 / 49
“Smell you later!”
(Nelson, The Simpsons)
![Page 9: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/9.jpg)
Code Duplication
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 9 / 49
![Page 10: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/10.jpg)
ZF Controller Action
public function testInitView (){
Zend_Controller_Front :: getInstance ()->setControllerDirectory(’/_files ’);
require_once ’/_files/ViewController.php’;$controller = new ViewController(
new Zend_Controller_Request_Http (),new Zend_Controller_Response_Cli ()
);$view = $controller ->initView ();$this ->assertTrue($view instanceof Zend_View);$scriptPath = $view ->getScriptPaths ();$this ->assertTrue(is_array($scriptPath));$this ->assertEquals(’/views/scripts/’, $scriptPath [0])
;}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 10 / 49
![Page 11: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/11.jpg)
ZF Controller Action 2
public function testRenderByName (){
$request = new Zend_Controller_Request_Http ();$request ->setControllerName(’view’)
->setActionName(’test’);$response = new Zend_Controller_Response_Cli ();Zend_Controller_Front :: getInstance ()->
setControllerDirectory(’/_files ’);require_once ’/_files/ViewController.php’;$controller = new ViewController($request , $response);
$controller ->testAction ();$this ->assertContains(’In the index action view’,
$response ->getBody ());}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 11 / 49
![Page 12: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/12.jpg)
ZF Controller Refactoring
Extract Test Utility Method:public function createViewController($controllerName=null ,
$actionName=null){
$request = new Zend_Controller_Request_Http ();if($controllerName !== null) {
$request ->setControllerName($controllerName);}if($actionName !== null) {
$request ->setActionName($actionName);}$response = new Zend_Controller_Response_Cli ();
Zend_Controller_Front :: getInstance ()->setControllerDirectory(’/_files ’);
require_once ’/_files/ViewController.php’;
return new ViewController($request , $response);}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 12 / 49
![Page 13: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/13.jpg)
ZF Controller Refactoring 2
public function testInitViewRefactored (){
// fixture setup$controller = $this ->createViewController ();
// execution$view = $controller ->initView ();$scriptPath = $view ->getScriptPaths ();
// assertions$this ->assertTrue($view instanceof Zend_View);$this ->assertTrue(is_array($scriptPath));$this ->assertEquals(
’/views/scripts/’, $scriptPath [0]);
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 13 / 49
![Page 14: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/14.jpg)
ZF Controller Refactoring 3
public function testRenderByNameRefactored (){
// fixture setup$controller =
$this ->createViewController(’view’, ’test’);
// execution$controller ->testAction ();
// assertions$this ->assertContains(
’In the index action view’,$response ->getBody ()
);}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 14 / 49
![Page 15: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/15.jpg)
Assertion Roulette
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 15 / 49
![Page 16: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/16.jpg)
Doctrine ResultSetMapping
public function testBasicResultSetMapping (){
// Fixture Setup$rsm = new ResultSetMapping ();$rsm ->addEntityResult(
’Doctrine\Tests\Models\CMS\CmsUser ’,’u’
);$rsm ->addFieldResult(’u’, ’id’, ’id’);$rsm ->addFieldResult(’u’, ’status ’, ’status ’);$rsm ->addFieldResult(’u’, ’user’, ’user’);$rsm ->addFieldResult(’u’, ’name’, ’name’);// [..]
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 16 / 49
![Page 17: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/17.jpg)
Doctrine ResultSetMapping 2
public function testBasicResultSetMapping (){
// [..]$this ->assertFalse($rsm ->isScalarResult(’id’));$this ->assertFalse($rsm ->isScalarResult(’status ’));$this ->assertFalse($rsm ->isScalarResult(’user’));$this ->assertFalse($rsm ->isScalarResult(’name’));
$this ->assertTrue($rsm ->getClass(’u’) ==’Doctrine\Tests\Models\CMS\CmsUser ’
);$class = $rsm ->getOwningClass(’id’);$this ->assertTrue(
$class == ’Doctrine\Tests\Models\CMS\CmsUser ’);
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 17 / 49
![Page 18: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/18.jpg)
Doctrine ResultSetMapping 3
public function testBasicResultSetMapping (){
// [..]$this ->assertEquals(’u’, $rsm ->getAlias(’id’));$this ->assertEquals(’u’, $rsm ->getAlias(’status ’));$this ->assertEquals(’u’, $rsm ->getAlias(’user’));$this ->assertEquals(’u’, $rsm ->getAlias(’name’));
$this ->assertEquals(’id’, $rsm ->getField(’id’));$this ->assertEquals(’status ’, $rsm ->getField(’status ’));$this ->assertEquals(’username ’, $rsm ->getField(’user’));$this ->assertEquals(’name’, $rsm ->getField(’name’));
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 18 / 49
![Page 19: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/19.jpg)
Eager Test
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 19 / 49
![Page 20: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/20.jpg)
ezcUrl Test
public function testRemoveOrderedParameter (){
$urlCfg = new ezcUrlConfiguration ();$urlCfg ->addOrderedParameter( ’section ’ );$urlCfg ->addOrderedParameter( ’module ’ );$urlCfg ->addOrderedParameter( ’view’ );
$u = ’http :// www.example.com/doc/components ’;$url = new ezcUrl($u, $urlCfg);
//[..]}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 20 / 49
![Page 21: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/21.jpg)
ezcUrl Test 2
public function testRemoveOrderedParameter (){
// [..]
// functionality tested in other tests before$this ->assertEquals(
array(’section ’ => 0, ’module ’ => 1, ’view’ => 2),$url ->configuration ->orderedParameters
);$this ->assertEquals(’doc’, $url ->getParam(’section ’));$this ->assertEquals(
’components ’, $url ->getParam(’module ’));
// [..]}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 21 / 49
![Page 22: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/22.jpg)
ezcUrl Test 3
public function testRemoveOrderedParameter (){
// [..]
// Primary Assertion according to test method name$url ->configuration ->removeOrderedParameter(’view’);$this ->assertEquals(
array( ’section ’ => 0, ’module ’ => 1 ),$url ->configuration ->orderedParameters
);
// [..]?}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 22 / 49
![Page 23: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/23.jpg)
ezcUrl Test 4
public function testRemoveOrderedParameter (){
// [..]
try{
$this ->assertEquals(null , $url ->getParam(’view’));$this ->fail(’Expected exception was not thrown.’);
} catch ( ezcUrlInvalidParameterException $e ) {$expected = "...";$this ->assertEquals($expected , $e->getMessage ());
}
// [..]?}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 23 / 49
![Page 24: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/24.jpg)
ezcUrl Test 5
public function testRemoveOrderedParameter (){
// [..]
// try removing again - nothing bad should happen$url ->configuration ->removeOrderedParameter(’view’);try{
$this ->assertEquals(null , $url ->getParam(’view’));$this ->fail(’Expected exception was not thrown.’);
} catch ( ezcUrlInvalidParameterException $e ) {$expected = "...";$this ->assertEquals($expected , $e->getMessage ());
}}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 24 / 49
![Page 25: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/25.jpg)
Fragile Test
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 25 / 49
![Page 26: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/26.jpg)
Zend SOAP Wsdl Testfunction testAddBinding () {$wsdl = new Zend_Soap_Wsdl(
’MyService ’, ’http :// localhost/MyService.php’);$wsdl ->addPortType(’myPortType ’);$wsdl ->addBinding(’MyServiceBinding ’, ’myPortType ’);
$this ->assertEquals($wsdl ->toXml ()),’<?xml version ="1.0"? >’ .’<definitions xmlns ="http :// schemas.xmlsoap.org/wsdl/" ’. ’xmlns:tns="http :// localhost/MyService.php" ’. ’xmlns:soap="http :// schemas.xmlsoap.org/wsdl/soap/" ’. ’xmlns:xsd="http ://www.w3.org /2001/ XMLSchema" ’. ’xmlns:soap -enc="http :// schemas.xmlsoap.org/soap/
encoding /" ’. ’xmlns:wsdl="http :// schemas.xmlsoap.org/wsdl/" ’. ’name=" MyService" targetNamespace ="http :// localhost/
MyService.php">’. ’<portType name=" myPortType "/>’. ’<binding name=" MyServiceBinding" type=" myPortType "/>’
. ’</definitions >’ );}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 26 / 49
![Page 27: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/27.jpg)
Obscure Tests
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 27 / 49
![Page 28: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/28.jpg)
Global State: Zend Framework
// Zend_Controller_Action_Helper_ViewRendererTestprotected function setUp(){
$this ->request = new Zend_Controller_Request_Http ();$this ->response = new Zend_Controller_Response_Http ();$this ->front = Zend_Controller_Front :: getInstance ()
;$this ->front ->resetInstance ();$this ->front ->addModuleDirectory(’/_files/modules ’)
->setRequest($this ->request)->setResponse($this ->response);
$this ->helper = newZend_Controller_Action_Helper_ViewRenderer ();
Zend_Controller_Action_HelperBroker :: addHelper($this ->helper
);}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 28 / 49
![Page 29: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/29.jpg)
Indirect Tests: ezcMvcfunction testInternalRedirect () {
$config = new simpleConfiguration ();$config ->route = ’IRController ’;$dispatcher = new ezcMvcConfigurableDispatcher(
$config );$dispatcher ->run();self:: assertEquals("BODY: Name: name , ".
"Vars: array ([CR] ’nonRedirVar ’ => 4,"."[CR] ’ReqRedirVar ’ => 4,[CR])", $config ->store);
}
function testExternalRedirect () {$config = new simpleConfiguration ();$config ->route = ’IRController ’;$dispatcher = new ezcMvcConfigurableDispatcher(
$config );$dispatcher ->run();self:: assertEquals("BODY: Name: name , ".
"Vars: array ([CR] ’nonRedirVar ’ => 4,"."[CR] ’ReqRedirVar ’ => 4,[CR])", $config ->store);
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 29 / 49
![Page 30: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/30.jpg)
Test-Names: FLOW3 MVC
I dispatchCallsTheControllersProcessRequestMethodUntilTheIsDispatchedFlagInTheRequestObjectIsSet()
I dispatchThrowsAnInfiniteLoopExceptionIfTheRequestCouldNotBeDispachedAfter99Iterations()
I resolveControllerReturnsTheNotFoundControllerDefinedInTheFLOW3SettingsAndInjectsCorrectExceptionIfTheResolvedControllerDoesNotExist()
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 30 / 49
![Page 31: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/31.jpg)
Slow Tests
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 31 / 49
![Page 32: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/32.jpg)
Zend Service Amazon
public function setUp (){
$this ->_amazon = new Zend_Service_Amazon ();$this ->_query = new Zend_Service_Amazon_Query ()
$this ->_httpClient =new Zend_Http_Client_Adapter_Socket ();
$this ->_amazon ->getRestClient ()->getHttpClient ()->setAdapter($this ->_httpClient);
// terms of use compliance:// no more than one query per secondsleep (1);
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 32 / 49
![Page 33: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/33.jpg)
Zend Service Amazon 2
public function testItemSearchMusicMozart (){
$resultSet = $this ->_amazon ->itemSearch(array(’SearchIndex ’ => ’Music ’,’Keywords ’ => ’Mozart ’,’ResponseGroup ’ => ’Small ,Tracks ,Offers ’
));
foreach ($resultSet as $item) {$this ->assertTrue(
$item instanceof Zend_Service_Amazon_Item);
}}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 33 / 49
![Page 34: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/34.jpg)
Zend Amazon Refactored
public function setUpRefactored (){
$this ->_amazon = new Zend_Service_Amazon ();
$this ->_httpClient =new Zend_Http_Client_Adapter_Test ();
$this ->_amazon ->getRestClient ()->getHttpClient ()->setAdapter($this ->_httpClient);
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 34 / 49
![Page 35: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/35.jpg)
Zend Amazon Refactored 2
public function testItemSearchMusicMozartRefactored (){
$this ->_httpClient ->setResponse(file_get_contents("ExpectedTestResponse.txt")
);
$resultSet = $this ->_amazon ->itemSearch(array(’SearchIndex ’ => ’Music ’,’Keywords ’ => ’Mozart ’,’ResponseGroup ’ => ’Small ,Tracks ,Offers ’
));
foreach ($resultSet as $item) {$this ->assertTrue(
$item instanceof Zend_Service_Amazon_Item);// Assert some relevant stuff now!
}}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 35 / 49
![Page 36: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/36.jpg)
Conditional Logic
“Everyone knows that debugging is
twice as hard as writing a program in
the first place. So if you’re as clever as
you can be when you write it, how will
you ever debug it?” (Brian Kernighan)
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 36 / 49
![Page 37: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/37.jpg)
FLOW3 Cache Frontend
public function theConstructorAcceptsValidIdentifiers () {$mockBackend = $this ->createMockBackend ();
$identifiers = array(’x’, ’someValue ’, ’123 fivesixseveneight ’,’some&’, ’ab_cd%’,rawurlencode(’package :// some/ $ &% sadf’),str_repeat(’x’, 250)
);
foreach ($identifiers as $identifier) {$abstractCache = $this ->getMock(
’F3\FLOW3\Cache\Frontend\StringFrontend ’,array(),array($identifier , $mockBackend)
);}
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 37 / 49
![Page 38: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/38.jpg)
FLOW3 Cache Refactored/*** @dataProvider dataAcceptValidIdentifier*/
public function constructorAcceptsValidIdentifier($id) {$mockBackend = $this ->createMockBackend ();
$abstractCache = $this ->getMock(’F3\FLOW3\Cache\Frontend\StringFrontend ’,array(),array($id , $mockBackend)
);}static public function dataAcceptValidIdentifier () {
return array(array(’x’), array(’someValue ’),array(’123 fivesixseveneight ’),array(’some&’), array(’ab_cd%’),array(
rawurlencode(’package :// some/ $ &% sadf’)),array(str_repeat(’x’, 250))
);}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 38 / 49
![Page 39: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/39.jpg)
Zend Server ReflectionClass
public function testGetMethods (){
$r = new Zend_Server_Reflection_Class(new ReflectionClass(’Zend_Server_Reflection ’)
);
$methods = $r->getMethods ();$this ->assertTrue(is_array($methods));foreach ($methods as $m) {
$this ->assertTrue($m instanceof Zend_Server_Reflection_Method
);}
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 39 / 49
![Page 40: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/40.jpg)
A working implementation
class Zend_Server_Reflection_Class (){
public function getMethods (){
return array ();}
}
Great, all tests pass!
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 40 / 49
![Page 41: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/41.jpg)
Zend Server ReflectionClassTest Refactoring
public function testGetMethodsRefactored (){
$r = new Zend_Server_Reflection_Class(new ReflectionClass(’Zend_Server_Reflection ’)
);
$methods = $r->getMethods ();$this ->assertTrue(is_array($methods));$this ->assertEquals (3, count($methods)); // (!!)foreach ($methods as $m) {
$this ->assertTrue($m instanceof Zend_Server_Reflection_Method
);}
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 41 / 49
![Page 42: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/42.jpg)
Zend Server ReflectionClassTest Refactoring 2
public function assertReflMethods($methods , $expected){
$this ->assertTye(’array ’, $methods);$this ->assertEquals($expected , count($methods));foreach ($methods as $m) {
$this ->assertTrue($m instanceof Zend_Server_Reflection_Method
);}
}public function testGetMethodsRefactored (){
$r = new Zend_Server_Reflection_Class(new ReflectionClass(’Zend_Server_Reflection ’)
);$this ->assertReflMethods($r->getMethods (), 3);
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 42 / 49
![Page 43: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/43.jpg)
ezcPersistentObject Relations
public function testIsRelatedSuccess (){
$person = $this ->session ->load( "TestPerson", 1 );$addresses = $this ->session ->getRelatedObjects(
$person , ’TestAddress ’);
foreach ( $addresses as $address ) {$this ->assertTrue(
$this ->session ->isRelated( $person , $address ));
}}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 43 / 49
![Page 44: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/44.jpg)
Mock-Overkill
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 44 / 49
![Page 45: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/45.jpg)
FLOW3 MVC Dispatcher
public function testDispatch () {$mockRequest = $this ->getMock(’F3\FLOW3\MVC\
RequestInterface ’);$mockRequest ->expects($this ->at(0))
->method(’isDispatched ’)->will($this ->returnValue(FALSE));
$mockRequest ->expects($this ->at(1))->method(’isDispatched ’)->will($this ->returnValue(FALSE));
$mockRequest ->expects($this ->at(2))->method(’isDispatched ’)->will($this ->returnValue(TRUE));
$mockResponse = $this ->getMock(’F3\FLOW3\MVC\ResponseInterface ’
);
// [..]}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 45 / 49
![Page 46: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/46.jpg)
FLOW3 MVC Dispatcher 2public function testDispatch () {
// [..]$mockController = $this ->getMock(
’F3\FLOW3\MVC\Controller\ControllerInterface ’,array(’processRequest ’, ’canProcessRequest ’)
);$mockController ->expects($this ->exactly (2))
->method(’processRequest ’)->with($mockRequest , $mockResponse);
$dispatcher = $this ->getMock(’F3\FLOW3\MVC\Dispatcher ’, array(’
resolveController ’),array(), ’’, FALSE
);$dispatcher ->expects($this ->any())
->method(’resolveController ’)->will($this ->returnValue($mockController))
;$dispatcher ->dispatch($mockRequest , $mockResponse);
}
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 46 / 49
![Page 47: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/47.jpg)
Conclusion
I Don’t use global state (Singleton
Anti-Pattern)
I Use utility methods for Assertions, Object
and Mock Creation
I Use Mocks (but not exclusively)
I Give meaningful test-names
I Dont test through the UI
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 47 / 49
![Page 48: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/48.jpg)
Further Readings
I xUnit Test Patterns
Book by Gerald Meszaros, http://xunitpatterns.com/Test%20Smells.html
I TDD Anti Patterns
http://blog.james-carr.org/2006/11/03/tdd-anti-patterns/
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 48 / 49
![Page 49: Unit-Testing Bad-Practices by Example](https://reader034.vdocuments.us/reader034/viewer/2022052505/554f84b2b4c905435d8b4b2a/html5/thumbnails/49.jpg)
Thank You!
E-Mail: [email protected]
Twitter: beberlei
Slides: http://www.whitewashing.de
PHP Quality Assurance Book, Early 2010!
Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 49 / 49