SlideShare a Scribd company logo
Unit-Testing Bad-Practices
            by Example

                              Benjamin Eberlei
                                 direkt effekt GmbH

                                August 2009


Eberlei (direkt effekt GmbH)    Unit-Testing Bad-Practices   August 2009   1 / 49
About Me


          Benjamin Eberlei
          direkt effekt GmBH (digital marketing)
          Zend Framework contributor
          Test-Driven-Development, Legacy Testing



Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   2 / 49
And You?




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   3 / 49
Why Test Quality Matters




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   4 / 49
“We spent 90% of the time
      modifying existing tests to
      acommodate for a relatively
      minor change.“
      (G. Meszaros, xUnit Test Patterns)




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   5 / 49
“Walking on water and
                              developing software from a
                              specification are easy if both
                              are frozen.”
                              (Edward V. Berard)




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   6 / 49
Safety Net vs Dead Weight




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   7 / 49
Test Smells

                                       “Smell you later!”
                                       (Nelson, The Simpsons)




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   8 / 49
Code Duplication




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   9 / 49
ZF Controller Action
   public function testInitView ()
   {
       Zen d_ C o n t r o l l e r _ Front :: getInstance () ->
            s e t C o n t r o l l er Dir ec to ry ( ’/ _files ’) ;
       require_once ’/ _files / ViewController . php ’;
       $controller = new ViewController (
             new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () ,
             new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ C l i ()
       );
       $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
ZF Controller Action 2

   public function testRenderByName ()
   {
       $request = new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () ;
       $request - > set ControllerName ( ’ view ’)
                     -> setActionName ( ’ test ’) ;
       $response = new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ C l i () ;
       Zen d_ C o n t r o l l e r _ Front :: getInstance () ->
            s e t C o n t r o l l er Dir ec to ry ( ’/ _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
ZF Controller Refactoring
  Extract Test Utility Method:
   public function c r e ateViewController ( $controllerName = null ,
        $actionName = null )
   {
       $request = new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () ;
       if ( $controllerName !== null ) {
             $request - > setControllerName ( $controllerName ) ;
       }
       if ( $actionName !== null ) {
             $request - > setActionName ( $actionName ) ;
       }
       $response = new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ C l i () ;
        Zen d_ C o n t r o l l e r _ Front :: getInstance ()
             -> s e t C o n t r o l le rD ire ct or y ( ’/ _files ’) ;
        require_once ’/ _files / ViewController . php ’;

        return new ViewController ( $request , $response ) ;
   }


Eberlei (direkt effekt GmbH)    Unit-Testing Bad-Practices        August 2009   12 / 49
ZF Controller Refactoring 2
   public function t e s tI nit Vi ew Ref ac to red ()
   {
       // 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
ZF Controller Refactoring 3

   public function t e s t R e n d e r B y N a m e R e f a c t o r e d ()
   {
       // fixture setup
       $controller =
           $this - > c r e a teViewController ( ’ 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
Assertion Roulette




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   15 / 49
Doctrine ResultSetMapping

   public function t e s t B a s i c Re s u l t S e t M a p p i n g ()
   {
       // 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
Doctrine ResultSetMapping 2
   public function t e s t B a s i c Re s u l t S e t M a p p i n g ()
   {
       // [..]
       $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
Doctrine ResultSetMapping 3

   public function t e s t B a s i c Re s u l t S e t M a p p i n g ()
   {
     // [..]
     $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
Eager Test




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   19 / 49
ezcUrl Test

   public function t e s t R e m o v e O r d e r e d P a r a m e t e r ()
   {
       $urlCfg = new e zcUrlConfiguration () ;
       $urlCfg - > a d dO r d eredParameter ( ’ section ’ ) ;
       $urlCfg - > a d dO r d eredParameter ( ’ module ’ ) ;
       $urlCfg - > a d dO r d eredParameter ( ’ 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
ezcUrl Test 2
   public function t e s t R e m o v e O r d e r e d P a r a m e t e r ()
   {
       // [..]

         // 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
ezcUrl Test 3

   public function t e s t R e m o v e O r d e r e d P a r a m e t e r ()
   {
       // [..]
         // Primary Assertion according to test method name
         $url - > configuration - > r em ove Or de re dPa ra me ter ( ’ view ’) ;
         $this - > assertEquals (
              array ( ’ section ’ = > 0 , ’ module ’ = > 1 ) ,
              $url - > configuration - > orderedParameters
         );

         // [..]?
   }




Eberlei (direkt effekt GmbH)        Unit-Testing Bad-Practices          August 2009   22 / 49
ezcUrl Test 4

   public function t e s t R e m o v e O r d e r e d P a r a m e t e r ()
   {
       // [..]
         try
         {
             $this - > assertEquals ( null , $url - > getParam ( ’ view ’) ) ;
             $this - > fail ( ’ Expected exception was not thrown . ’) ;
         } catch ( e z c U r l I n v a l i d P a r a m e t e r E x c e p t i o n $e ) {
             $expected = " ... " ;
             $this - > assertEquals ( $expected , $e - > getMessage () ) ;
         }

         // [..]?
   }




Eberlei (direkt effekt GmbH)        Unit-Testing Bad-Practices          August 2009   23 / 49
ezcUrl Test 5

   public function t e s t R e m o v e O r d e r e d P a r a m e t e r ()
   {
       // [..]
         // try removing again - nothing bad should happen
         $url - > configuration - > r em ove Or de re dPa ra me ter ( ’ view ’) ;
         try
         {
              $this - > assertEquals ( null , $url - > getParam ( ’ view ’) ) ;
              $this - > fail ( ’ Expected exception was not thrown . ’) ;
         } catch ( e z c U r l I n v a l i d P a r a m e t e r E x c e p t i o n $e ) {
              $expected = " ... " ;
              $this - > assertEquals ( $expected , $e - > getMessage () ) ;
         }
   }




Eberlei (direkt effekt GmbH)        Unit-Testing Bad-Practices          August 2009   24 / 49
Fragile Test




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   25 / 49
Zend SOAP Wsdl Test
   function 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
Obscure Tests




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   27 / 49
Global State: Zend Framework
   // Z e n d _ C o n t r o l l e r _ A c t i o n _ H e l p e r _ V i e w R e n d e r e r T e s t
   protected function setUp ()
   {
        $this - > request = new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () ;
        $this - > response = new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ H t t p () ;
        $this - > front                 = Ze nd_C ontro ller _Fron t :: getInstance ()
               ;
        $this - > front - > resetInstance () ;
        $this - > front - > a ddModuleDirectory ( ’/ _files / modules ’)
                                -> setRequest ( $this - > request )
                                -> setResponse ( $this - > response ) ;

         $this - > helper = new
                Z e n d _ C o n t r o l l e r _ A c t i o n _ H e l p e r _ V i e w R e n d e r e r () ;
         Z e n d _ C o n t r o l l e r _ A c t i o n _ H e l p e r B r o k e r :: addHelper (
                 $this - > helper
         );
   }




Eberlei (direkt effekt GmbH)             Unit-Testing Bad-Practices                   August 2009           28 / 49
Indirect Tests: ezcMvc
   function t e s t I n t e r n alRedirect () {
       $config = new s impleConfiguration () ;
       $config - > route = ’ IRController ’;
       $dispatcher = new e z c M v c C o n f i g u r a b l e D i s p a t c h e r (
           $config ) ;
       $dispatcher - > run () ;
       self :: assertEquals ( " BODY : Name : name , " .
            " Vars : array ([ CR ] ’ nonRedirVar ’ = > 4 , " .
            " [ CR ] ’ ReqRedirVar ’ = > 4 ,[ CR ]) " , $config - > store ) ;
   }

   function t e s t E x t e r n alRedirect () {
       $config = new s impleConfiguration () ;
       $config - > route = ’ IRController ’;
       $dispatcher = new e z c M v c C o n f i g u r a b l e D i s p a t c h e r (
           $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
Test-Names: FLOW3 MVC
          dispatchCallsTheControllersProcess
          RequestMethodUntilTheIsDispatchedFlag
          InTheRequestObjectIsSet()
          dispatchThrowsAnInfiniteLoopException
          IfTheRequestCouldNotBeDispached
          After99Iterations()
          resolveControllerReturnsTheNotFound
          ControllerDefinedInTheFLOW3Settings
          AndInjectsCorrectException
          IfTheResolvedControllerDoesNotExist()

Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   30 / 49
Slow Tests




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   31 / 49
Zend Service Amazon
   public function setUp ()
   {
       $this - > _amazon = new Zend_Service_Amazon () ;
       $this - > _query = new Z e n d _ S e r v i ce _ A m a z o n _ Q u e r y ()

         $this - > _httpClient =
             new Z e n d _ H t t p _ C l i e n t _ A d a p t e r _ S o c k e t () ;
         $this - > _amazon - > getRestClient ()
                               -> getHttpClient ()
                               -> setAdapter ( $this - > _httpClient ) ;

         // terms of use compliance :
         // no more than one query per second
         sleep (1) ;
   }




Eberlei (direkt effekt GmbH)          Unit-Testing Bad-Practices              August 2009   32 / 49
Zend Service Amazon 2

   public function t e s t I t e m S ea r c h M u s i c M o z a r t ()
   {
       $resultSet = $this - > _amazon - > itemSearch ( array (
           ’ SearchIndex ’         = > ’ Music ’ ,
           ’ Keywords ’            = > ’ Mozart ’ ,
           ’ ResponseGroup ’ = > ’ Small , Tracks , Offers ’
       ));
        foreach ( $resultSet as $item ) {
            $this - > assertTrue (
                $item instanceof Z e n d_ S e r vi c e _ Am a z o n_ I t e m
            );
        }
   }




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices      August 2009      33 / 49
Zend Amazon Refactored

   public function setUpRefactored ()
   {
       $this - > _amazon = new Zend_Service_Amazon () ;

        $this - > _httpClient =
            new Z e n d _ H t t p _ C l i e n t _ A d a p t e r _ T e s t () ;

        $this - > _amazon - > getRestClient ()
                              -> getHttpClient ()
                              -> setAdapter ( $this - > _httpClient ) ;
   }




Eberlei (direkt effekt GmbH)         Unit-Testing Bad-Practices              August 2009   34 / 49
Zend Amazon Refactored 2
   public function t e s t I t e m S e a r c h M u s i c M o z a r t R e f a c t o r e d ()
   {
       $this - > _httpClient - > setResponse (
           fil e_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 Z e n d_ S e r vi c e _ Am a z o n_ I t e m
             );
             // Assert some relevant stuff now !
         }
   }



Eberlei (direkt effekt GmbH)         Unit-Testing Bad-Practices            August 2009         35 / 49
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
FLOW3 Cache Frontend
   public function t h e C o n s t r u c t o r A c c e p t s V a l i d I d e n t i f i e r s () {
       $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
FLOW3 Cache Refactored
   /* *
    * @dataProvider d a t a A c c e p t V a l i d I d e n t i f ie r
    */
   public function c o n s t r u c t o r A c c e p t s V a l i d I d e n t i f i e r ( $id ) {
        $mockBackend = $this - > createMockBackend () ;

         $abstractCache = $this - > getMock (
             ’ F3  FLOW3  Cache  Frontend  StringFrontend ’ ,
             array () ,
             array ( $id , $mockBackend )
         );
   }
   static public function d a t a A c c e p tV a l i d I d e n t i f i e r () {
       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
Zend Server ReflectionClass

   public function testGetMethods ()
   {
       $r = new Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s (
           new ReflectionClass ( ’ Ze nd_ Se rv er_ Re fl ect io n ’)
       );

        $methods = $r - > getMethods () ;
        $this - > assertTrue ( is_array ( $methods ) ) ;
        foreach ( $methods as $m ) {
            $this - > assertTrue (
                   $m instanceof Z e n d _ S e r v e r _ R e f l e c t i o n _ M e t h o d
            );
        }
   }




Eberlei (direkt effekt GmbH)      Unit-Testing Bad-Practices           August 2009        39 / 49
A working implementation

   class Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s ()
   {
       public function getMethods ()
       {
             return array () ;
       }
   }


  Great, all tests pass!



Eberlei (direkt effekt GmbH)           Unit-Testing Bad-Practices      August 2009   40 / 49
Zend Server ReflectionClass
Test Refactoring
   public function t e s t G e tM e t ho d s R ef a c t or e d ()
   {
       $r = new Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s (
           new ReflectionClass ( ’ Ze nd_ Se rv er_ Re fl ect io n ’)
       );

        $methods = $r - > getMethods () ;
        $this - > assertTrue ( is_array ( $methods ) ) ;
        $this - > assertEquals (3 , count ( $methods ) ) ; // (!!)
        foreach ( $methods as $m ) {
            $this - > assertTrue (
                   $m instanceof Z e n d _ S e r v e r _ R e f l e c t i o n _ M e t h o d
            );
        }
   }




Eberlei (direkt effekt GmbH)      Unit-Testing Bad-Practices           August 2009        41 / 49
Zend Server ReflectionClass
Test Refactoring 2
   public function ass ertReflMethods ( $methods , $expected )
   {
       $this - > assertTye ( ’ array ’ , $methods ) ;
       $this - > assertEquals ( $expected , count ( $methods ) ) ;
       foreach ( $methods as $m ) {
           $this - > assertTrue (
                  $m instanceof Z e n d _ S e r v e r _ R e f l e c t i o n _ M e t h o d
           );
       }
   }
   public function t e s t G e tM e t ho d s R ef a c t or e d ()
   {
       $r = new Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s (
           new ReflectionClass ( ’ Ze nd_ Se rv er_ Re fl ect io n ’)
       );
       $this - > as sertRe flMethods ( $r - > getMethods () , 3) ;
   }


Eberlei (direkt effekt GmbH)       Unit-Testing Bad-Practices          August 2009       42 / 49
ezcPersistentObject Relations

   public function t e s tIsRelatedSuccess ()
   {
       $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
Mock-Overkill




Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   44 / 49
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
FLOW3 MVC Dispatcher 2
   public 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 ( ’
                  reso lveController ’) ,
            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
Conclusion

          Don’t use global state (Singleton
          Anti-Pattern)
          Use utility methods for Assertions, Object
          and Mock Creation
          Use Mocks (but not exclusively)
          Give meaningful test-names
          Dont test through the UI

Eberlei (direkt effekt GmbH)   Unit-Testing Bad-Practices   August 2009   47 / 49
Further Readings


          xUnit Test Patterns
          Book by Gerald Meszaros, http://xunitpatterns.com/Test%20Smells.html


          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
Thank You!

              E-Mail: kontakt@beberlei.de
                     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

More Related Content

What's hot

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
mfrost503
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnitferca_sl
 
Oracle PL/SQL - Creative Conditional Compilation
Oracle PL/SQL - Creative Conditional CompilationOracle PL/SQL - Creative Conditional Compilation
Oracle PL/SQL - Creative Conditional Compilation
Scott Wesley
 
Stub you!
Stub you!Stub you!
Stub you!
Andrea Giuliano
 
A Test of Strength
A Test of StrengthA Test of Strength
A Test of Strength
Chris Oldwood
 
ISSTA 2010 Presentation
ISSTA 2010 PresentationISSTA 2010 Presentation
ISSTA 2010 Presentation
Julian Dolby
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven Development
Augusto Pascutti
 
Con5623 pdf 5623_001
Con5623 pdf 5623_001Con5623 pdf 5623_001
Con5623 pdf 5623_001
Euegene Fedorenko
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented Javascript
Daniel Ku
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
Konstantin Kudryashov
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
jeresig
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
Konstantin Kudryashov
 
Feature Flags Are Flawed: Let's Make Them Better - DPC
Feature Flags Are Flawed: Let's Make Them Better - DPCFeature Flags Are Flawed: Let's Make Them Better - DPC
Feature Flags Are Flawed: Let's Make Them Better - DPC
Stephen Young
 
Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)
Arnaud Langlade
 
AssertJ quick introduction
AssertJ quick introductionAssertJ quick introduction
AssertJ quick introduction
Thiago Schoppen Veronese
 
Calculon
CalculonCalculon
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
Divante
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
JOYITAKUNDU1
 

What's hot (20)

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnit
 
Oracle PL/SQL - Creative Conditional Compilation
Oracle PL/SQL - Creative Conditional CompilationOracle PL/SQL - Creative Conditional Compilation
Oracle PL/SQL - Creative Conditional Compilation
 
Stub you!
Stub you!Stub you!
Stub you!
 
Deep dive into Oracle ADF
Deep dive into Oracle ADFDeep dive into Oracle ADF
Deep dive into Oracle ADF
 
A Test of Strength
A Test of StrengthA Test of Strength
A Test of Strength
 
Hidden rocks in Oracle ADF
Hidden rocks in Oracle ADFHidden rocks in Oracle ADF
Hidden rocks in Oracle ADF
 
ISSTA 2010 Presentation
ISSTA 2010 PresentationISSTA 2010 Presentation
ISSTA 2010 Presentation
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven Development
 
Con5623 pdf 5623_001
Con5623 pdf 5623_001Con5623 pdf 5623_001
Con5623 pdf 5623_001
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented Javascript
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Feature Flags Are Flawed: Let's Make Them Better - DPC
Feature Flags Are Flawed: Let's Make Them Better - DPCFeature Flags Are Flawed: Let's Make Them Better - DPC
Feature Flags Are Flawed: Let's Make Them Better - DPC
 
Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)
 
AssertJ quick introduction
AssertJ quick introductionAssertJ quick introduction
AssertJ quick introduction
 
Calculon
CalculonCalculon
Calculon
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 

Viewers also liked

Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
Benjamin Eberlei
 
Mockist vs. Classicists TDD
Mockist vs. Classicists TDDMockist vs. Classicists TDD
Mockist vs. Classicists TDD
David Völkel
 
Василий Сорокин, “Google C++ Mocking and Test Frameworks”
Василий Сорокин, “Google C++ Mocking and Test Frameworks”Василий Сорокин, “Google C++ Mocking and Test Frameworks”
Василий Сорокин, “Google C++ Mocking and Test Frameworks”
Platonov Sergey
 
Практика использования Dependency Injection
Практика использования Dependency InjectionПрактика использования Dependency Injection
Практика использования Dependency Injection
Platonov Sergey
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
Platonov Sergey
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
yaevents
 
Павел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.ioПавел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.io
Sergey Platonov
 
Practical unit testing in c & c++
Practical unit testing in c & c++Practical unit testing in c & c++
Practical unit testing in c & c++
Matt Hargett
 
Clean Unit Test Patterns
Clean Unit Test PatternsClean Unit Test Patterns
Clean Unit Test Patterns
Frank Appel
 
Как писать красивый код или основы SOLID
Как писать красивый код или основы SOLIDКак писать красивый код или основы SOLID
Как писать красивый код или основы SOLID
Pavel Tsukanov
 
Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++
Lars Thorup
 

Viewers also liked (11)

Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 
Mockist vs. Classicists TDD
Mockist vs. Classicists TDDMockist vs. Classicists TDD
Mockist vs. Classicists TDD
 
Василий Сорокин, “Google C++ Mocking and Test Frameworks”
Василий Сорокин, “Google C++ Mocking and Test Frameworks”Василий Сорокин, “Google C++ Mocking and Test Frameworks”
Василий Сорокин, “Google C++ Mocking and Test Frameworks”
 
Практика использования Dependency Injection
Практика использования Dependency InjectionПрактика использования Dependency Injection
Практика использования Dependency Injection
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
 
Павел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.ioПавел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.io
 
Practical unit testing in c & c++
Practical unit testing in c & c++Practical unit testing in c & c++
Practical unit testing in c & c++
 
Clean Unit Test Patterns
Clean Unit Test PatternsClean Unit Test Patterns
Clean Unit Test Patterns
 
Как писать красивый код или основы SOLID
Как писать красивый код или основы SOLIDКак писать красивый код или основы SOLID
Как писать красивый код или основы SOLID
 
Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++Automated Testing for Embedded Software in C or C++
Automated Testing for Embedded Software in C or C++
 

Similar to Unit-Testing Bad-Practices by Example

Unittesting Bad-Practices by Example
Unittesting Bad-Practices by ExampleUnittesting Bad-Practices by Example
Unittesting Bad-Practices by Example
Benjamin Eberlei
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
Bastian Feder
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
Lars Jankowfsky
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
Kent Cowgill
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
Bastian Feder
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
Jeroen van Dijk
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
Tagged Social
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
markstory
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
(Unit )-Testing for Joomla
(Unit )-Testing for Joomla(Unit )-Testing for Joomla
(Unit )-Testing for Joomla
David Jardin
 
Feature flagsareflawed
Feature flagsareflawedFeature flagsareflawed
Feature flagsareflawed
Stephen Young
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
Lean Teams Consultancy
 
Feature Flags Are Flawed: Let's Make Them Better
Feature Flags Are Flawed: Let's Make Them BetterFeature Flags Are Flawed: Let's Make Them Better
Feature Flags Are Flawed: Let's Make Them Better
Stephen Young
 
Commencer avec le TDD
Commencer avec le TDDCommencer avec le TDD
Commencer avec le TDD
Eric Hogue
 
Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Bernhard Schussek
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
Jay Harris
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
Marcello Duarte
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
Bastian Feder
 

Similar to Unit-Testing Bad-Practices by Example (20)

Unittesting Bad-Practices by Example
Unittesting Bad-Practices by ExampleUnittesting Bad-Practices by Example
Unittesting Bad-Practices by Example
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
(Unit )-Testing for Joomla
(Unit )-Testing for Joomla(Unit )-Testing for Joomla
(Unit )-Testing for Joomla
 
Feature flagsareflawed
Feature flagsareflawedFeature flagsareflawed
Feature flagsareflawed
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Feature Flags Are Flawed: Let's Make Them Better
Feature Flags Are Flawed: Let's Make Them BetterFeature Flags Are Flawed: Let's Make Them Better
Feature Flags Are Flawed: Let's Make Them Better
 
Commencer avec le TDD
Commencer avec le TDDCommencer avec le TDD
Commencer avec le TDD
 
Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Best Practice Testing with Lime 2
Best Practice Testing with Lime 2
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 

Recently uploaded

Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 

Recently uploaded (20)

Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 

Unit-Testing Bad-Practices by Example

  • 1. Unit-Testing Bad-Practices by Example Benjamin Eberlei direkt effekt GmbH August 2009 Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 1 / 49
  • 2. About Me Benjamin Eberlei direkt effekt GmBH (digital marketing) Zend Framework contributor Test-Driven-Development, Legacy Testing Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 2 / 49
  • 3. And You? Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 3 / 49
  • 4. Why Test Quality Matters Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 4 / 49
  • 5. “We spent 90% of the time modifying existing tests to acommodate for a relatively minor change.“ (G. Meszaros, xUnit Test Patterns) Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 5 / 49
  • 6. “Walking on water and developing software from a specification are easy if both are frozen.” (Edward V. Berard) Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 6 / 49
  • 7. Safety Net vs Dead Weight Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 7 / 49
  • 8. Test Smells “Smell you later!” (Nelson, The Simpsons) Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 8 / 49
  • 9. Code Duplication Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 9 / 49
  • 10. ZF Controller Action public function testInitView () { Zen d_ C o n t r o l l e r _ Front :: getInstance () -> s e t C o n t r o l l er Dir ec to ry ( ’/ _files ’) ; require_once ’/ _files / ViewController . php ’; $controller = new ViewController ( new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () , new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ C l i () ); $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
  • 11. ZF Controller Action 2 public function testRenderByName () { $request = new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () ; $request - > set ControllerName ( ’ view ’) -> setActionName ( ’ test ’) ; $response = new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ C l i () ; Zen d_ C o n t r o l l e r _ Front :: getInstance () -> s e t C o n t r o l l er Dir ec to ry ( ’/ _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
  • 12. ZF Controller Refactoring Extract Test Utility Method: public function c r e ateViewController ( $controllerName = null , $actionName = null ) { $request = new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () ; if ( $controllerName !== null ) { $request - > setControllerName ( $controllerName ) ; } if ( $actionName !== null ) { $request - > setActionName ( $actionName ) ; } $response = new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ C l i () ; Zen d_ C o n t r o l l e r _ Front :: getInstance () -> s e t C o n t r o l le rD ire ct or y ( ’/ _files ’) ; require_once ’/ _files / ViewController . php ’; return new ViewController ( $request , $response ) ; } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 12 / 49
  • 13. ZF Controller Refactoring 2 public function t e s tI nit Vi ew Ref ac to red () { // 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
  • 14. ZF Controller Refactoring 3 public function t e s t R e n d e r B y N a m e R e f a c t o r e d () { // fixture setup $controller = $this - > c r e a teViewController ( ’ 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
  • 15. Assertion Roulette Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 15 / 49
  • 16. Doctrine ResultSetMapping public function t e s t B a s i c Re s u l t S e t M a p p i n g () { // 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
  • 17. Doctrine ResultSetMapping 2 public function t e s t B a s i c Re s u l t S e t M a p p i n g () { // [..] $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
  • 18. Doctrine ResultSetMapping 3 public function t e s t B a s i c Re s u l t S e t M a p p i n g () { // [..] $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
  • 19. Eager Test Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 19 / 49
  • 20. ezcUrl Test public function t e s t R e m o v e O r d e r e d P a r a m e t e r () { $urlCfg = new e zcUrlConfiguration () ; $urlCfg - > a d dO r d eredParameter ( ’ section ’ ) ; $urlCfg - > a d dO r d eredParameter ( ’ module ’ ) ; $urlCfg - > a d dO r d eredParameter ( ’ 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
  • 21. ezcUrl Test 2 public function t e s t R e m o v e O r d e r e d P a r a m e t e r () { // [..] // 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
  • 22. ezcUrl Test 3 public function t e s t R e m o v e O r d e r e d P a r a m e t e r () { // [..] // Primary Assertion according to test method name $url - > configuration - > r em ove Or de re dPa ra me ter ( ’ view ’) ; $this - > assertEquals ( array ( ’ section ’ = > 0 , ’ module ’ = > 1 ) , $url - > configuration - > orderedParameters ); // [..]? } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 22 / 49
  • 23. ezcUrl Test 4 public function t e s t R e m o v e O r d e r e d P a r a m e t e r () { // [..] try { $this - > assertEquals ( null , $url - > getParam ( ’ view ’) ) ; $this - > fail ( ’ Expected exception was not thrown . ’) ; } catch ( e z c U r l I n v a l i d P a r a m e t e r E x c e p t i o n $e ) { $expected = " ... " ; $this - > assertEquals ( $expected , $e - > getMessage () ) ; } // [..]? } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 23 / 49
  • 24. ezcUrl Test 5 public function t e s t R e m o v e O r d e r e d P a r a m e t e r () { // [..] // try removing again - nothing bad should happen $url - > configuration - > r em ove Or de re dPa ra me ter ( ’ view ’) ; try { $this - > assertEquals ( null , $url - > getParam ( ’ view ’) ) ; $this - > fail ( ’ Expected exception was not thrown . ’) ; } catch ( e z c U r l I n v a l i d P a r a m e t e r E x c e p t i o n $e ) { $expected = " ... " ; $this - > assertEquals ( $expected , $e - > getMessage () ) ; } } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 24 / 49
  • 25. Fragile Test Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 25 / 49
  • 26. Zend SOAP Wsdl Test function 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
  • 27. Obscure Tests Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 27 / 49
  • 28. Global State: Zend Framework // Z e n d _ C o n t r o l l e r _ A c t i o n _ H e l p e r _ V i e w R e n d e r e r T e s t protected function setUp () { $this - > request = new Z e n d _ C o n t r o l l e r _ R e q u e s t _ H t t p () ; $this - > response = new Z e n d _ C o n t r o l l e r _ R e s p o n s e _ H t t p () ; $this - > front = Ze nd_C ontro ller _Fron t :: getInstance () ; $this - > front - > resetInstance () ; $this - > front - > a ddModuleDirectory ( ’/ _files / modules ’) -> setRequest ( $this - > request ) -> setResponse ( $this - > response ) ; $this - > helper = new Z e n d _ C o n t r o l l e r _ A c t i o n _ H e l p e r _ V i e w R e n d e r e r () ; Z e n d _ C o n t r o l l e r _ A c t i o n _ H e l p e r B r o k e r :: addHelper ( $this - > helper ); } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 28 / 49
  • 29. Indirect Tests: ezcMvc function t e s t I n t e r n alRedirect () { $config = new s impleConfiguration () ; $config - > route = ’ IRController ’; $dispatcher = new e z c M v c C o n f i g u r a b l e D i s p a t c h e r ( $config ) ; $dispatcher - > run () ; self :: assertEquals ( " BODY : Name : name , " . " Vars : array ([ CR ] ’ nonRedirVar ’ = > 4 , " . " [ CR ] ’ ReqRedirVar ’ = > 4 ,[ CR ]) " , $config - > store ) ; } function t e s t E x t e r n alRedirect () { $config = new s impleConfiguration () ; $config - > route = ’ IRController ’; $dispatcher = new e z c M v c C o n f i g u r a b l e D i s p a t c h e r ( $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
  • 30. Test-Names: FLOW3 MVC dispatchCallsTheControllersProcess RequestMethodUntilTheIsDispatchedFlag InTheRequestObjectIsSet() dispatchThrowsAnInfiniteLoopException IfTheRequestCouldNotBeDispached After99Iterations() resolveControllerReturnsTheNotFound ControllerDefinedInTheFLOW3Settings AndInjectsCorrectException IfTheResolvedControllerDoesNotExist() Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 30 / 49
  • 31. Slow Tests Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 31 / 49
  • 32. Zend Service Amazon public function setUp () { $this - > _amazon = new Zend_Service_Amazon () ; $this - > _query = new Z e n d _ S e r v i ce _ A m a z o n _ Q u e r y () $this - > _httpClient = new Z e n d _ H t t p _ C l i e n t _ A d a p t e r _ S o c k e t () ; $this - > _amazon - > getRestClient () -> getHttpClient () -> setAdapter ( $this - > _httpClient ) ; // terms of use compliance : // no more than one query per second sleep (1) ; } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 32 / 49
  • 33. Zend Service Amazon 2 public function t e s t I t e m S ea r c h M u s i c M o z a r t () { $resultSet = $this - > _amazon - > itemSearch ( array ( ’ SearchIndex ’ = > ’ Music ’ , ’ Keywords ’ = > ’ Mozart ’ , ’ ResponseGroup ’ = > ’ Small , Tracks , Offers ’ )); foreach ( $resultSet as $item ) { $this - > assertTrue ( $item instanceof Z e n d_ S e r vi c e _ Am a z o n_ I t e m ); } } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 33 / 49
  • 34. Zend Amazon Refactored public function setUpRefactored () { $this - > _amazon = new Zend_Service_Amazon () ; $this - > _httpClient = new Z e n d _ H t t p _ C l i e n t _ A d a p t e r _ T e s t () ; $this - > _amazon - > getRestClient () -> getHttpClient () -> setAdapter ( $this - > _httpClient ) ; } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 34 / 49
  • 35. Zend Amazon Refactored 2 public function t e s t I t e m S e a r c h M u s i c M o z a r t R e f a c t o r e d () { $this - > _httpClient - > setResponse ( fil e_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 Z e n d_ S e r vi c e _ Am a z o n_ I t e m ); // Assert some relevant stuff now ! } } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 35 / 49
  • 36. 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
  • 37. FLOW3 Cache Frontend public function t h e C o n s t r u c t o r A c c e p t s V a l i d I d e n t i f i e r s () { $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
  • 38. FLOW3 Cache Refactored /* * * @dataProvider d a t a A c c e p t V a l i d I d e n t i f ie r */ public function c o n s t r u c t o r A c c e p t s V a l i d I d e n t i f i e r ( $id ) { $mockBackend = $this - > createMockBackend () ; $abstractCache = $this - > getMock ( ’ F3 FLOW3 Cache Frontend StringFrontend ’ , array () , array ( $id , $mockBackend ) ); } static public function d a t a A c c e p tV a l i d I d e n t i f i e r () { 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
  • 39. Zend Server ReflectionClass public function testGetMethods () { $r = new Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s ( new ReflectionClass ( ’ Ze nd_ Se rv er_ Re fl ect io n ’) ); $methods = $r - > getMethods () ; $this - > assertTrue ( is_array ( $methods ) ) ; foreach ( $methods as $m ) { $this - > assertTrue ( $m instanceof Z e n d _ S e r v e r _ R e f l e c t i o n _ M e t h o d ); } } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 39 / 49
  • 40. A working implementation class Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s () { public function getMethods () { return array () ; } } Great, all tests pass! Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 40 / 49
  • 41. Zend Server ReflectionClass Test Refactoring public function t e s t G e tM e t ho d s R ef a c t or e d () { $r = new Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s ( new ReflectionClass ( ’ Ze nd_ Se rv er_ Re fl ect io n ’) ); $methods = $r - > getMethods () ; $this - > assertTrue ( is_array ( $methods ) ) ; $this - > assertEquals (3 , count ( $methods ) ) ; // (!!) foreach ( $methods as $m ) { $this - > assertTrue ( $m instanceof Z e n d _ S e r v e r _ R e f l e c t i o n _ M e t h o d ); } } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 41 / 49
  • 42. Zend Server ReflectionClass Test Refactoring 2 public function ass ertReflMethods ( $methods , $expected ) { $this - > assertTye ( ’ array ’ , $methods ) ; $this - > assertEquals ( $expected , count ( $methods ) ) ; foreach ( $methods as $m ) { $this - > assertTrue ( $m instanceof Z e n d _ S e r v e r _ R e f l e c t i o n _ M e t h o d ); } } public function t e s t G e tM e t ho d s R ef a c t or e d () { $r = new Z e n d _ S e r v e r _ R e f l e c t i o n _ C l a s s ( new ReflectionClass ( ’ Ze nd_ Se rv er_ Re fl ect io n ’) ); $this - > as sertRe flMethods ( $r - > getMethods () , 3) ; } Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 42 / 49
  • 43. ezcPersistentObject Relations public function t e s tIsRelatedSuccess () { $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
  • 44. Mock-Overkill Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 44 / 49
  • 45. 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
  • 46. FLOW3 MVC Dispatcher 2 public 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 ( ’ reso lveController ’) , 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
  • 47. Conclusion Don’t use global state (Singleton Anti-Pattern) Use utility methods for Assertions, Object and Mock Creation Use Mocks (but not exclusively) Give meaningful test-names Dont test through the UI Eberlei (direkt effekt GmbH) Unit-Testing Bad-Practices August 2009 47 / 49
  • 48. Further Readings xUnit Test Patterns Book by Gerald Meszaros, http://xunitpatterns.com/Test%20Smells.html 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
  • 49. Thank You! E-Mail: kontakt@beberlei.de 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