SlideShare a Scribd company logo
1 of 77
Download to read offline
Testing untestable code
Stephan HochdĂśrfer, bitExpert AG
Testing untestable code

 About me

  Stephan Hochdörfer

  Head of IT at bitExpert AG, Germany

  enjoying PHP since 1999

  S.Hochdoerfer@bitExpert.de

  @shochdoerfer
Testing untestable code

 No excuse for writing bad code!
Testing untestable code




     "Hang the rules. They're more like
           guidelines anyway."
            Elizabeth Swann, Pirates of the Caribbean
Testing untestable code




     "There is no secret to writing tests,
       there are only secrets to write
               testable code!"
                          MiĹĄko Hevery
Testing untestable code

 What is „untestable code“?
Testing untestable code




    "...our test strategy requires us to
    have more control [...] of the sut."
    Gerard Meszaros, xUnit Test Patterns: Refactoring Test
                            Code
Testing untestable code

 In a perfect world...




                  Unittest
                   Unittest   SUT
                               SUT
Testing untestable code

 Legacy code is not perfect...


                                 Dependency
                                  Dependency

       Unittest
        Unittest          SUT
                           SUT


                                 Dependency
                                  Dependency
Testing untestable code
                                 ...
 Legacy code is not perfect...


                                 Dependency
                                  Dependency

       Unittest
        Unittest          SUT
                           SUT


                                 Dependency
                                  Dependency




                                  ...
Testing untestable code
                                 ...
 Legacy code is not perfect...


                                 Dependency
                                  Dependency

       Unittest
        Unittest          SUT
                           SUT


                                 Dependency
                                  Dependency




                                  ...
Testing untestable code

 How to get „testable“ code?
Testing untestable code

 How to get „testable“ code?




                   Refactoring
Testing untestable code




   "Before you start refactoring, check
      that you have a solid suite of
                  tests."
                  Martin Fowler, Refactoring
Testing untestable code

 Which path to take?
Testing untestable code

 Which path to take?




       Do not change existing code!
Testing untestable code

 Examples




 Object Construction      External resources   Language issues
Testing untestable code

 Object construction
 <?php
 class Car {
    private $Engine;

     public function __construct($sEngine) {
        $this­>Engine = Engine::getByType($sEngine);
     }

 }
Testing untestable code

 Object construction - Autoload
 <?php
 function run_autoload($psClass) {
    $sFileToInclude = strtolower($psClass).'.php';
    if(strtolower($psClass) == 'engine') {
       $sFileToInclude = '/custom/mocks/'.
       $sFileToInclude;
    }
    include($sFileToInclude);
 }


 // Testcase
 spl_autoload_register('run_autoload');
 $oCar = new Car('Diesel');
 echo $oCar­>run();
Testing untestable code

 Object construction
 <?php
 include('Engine.php');

 class Car {
    private $Engine;

     public function __construct($sEngine) {
        $this­>Engine = Engine::getByType($sEngine);
     }
 }
Testing untestable code

 Object construction - include_path
 <?php
 ini_set('include_path',
    '/custom/mocks/'.PATH_SEPARATOR.
    ini_get('include_path'));

 // Testcase
 include('car.php');

 $oCar = new Car('Diesel');
 echo $oCar­>run();
Testing untestable code

 Object construction – Stream Wrapper
 <?php
 class CustomWrapper {
   private $_handler;

   function stream_open($path, $mode, $options, 
 &$opened_path) {

     stream_wrapper_restore('file');
     // @TODO: modify $path before fopen
     $this­>_handler = fopen($path, $mode);
     stream_wrapper_unregister('file');
     stream_wrapper_register('file', 'CustomWrapper');
     return true;
   }
 }
Testing untestable code

 Object construction – Stream Wrapper
 stream_wrapper_unregister('file');
 stream_wrapper_register('file', 'CustomWrapper');
Testing untestable code

 Object construction – Stream Wrapper
 <?php
 class CustomWrapper {
    private $_handler;

    function stream_read($count) {
       $content = fread($this­>_handler, $count);
       $content = str_replace('Engine::getByType',
        'AbstractEngine::get', $content);
       return $content;
    }
 }
Testing untestable code

 External resources
Testing untestable code

 External resources



             Database     Webservice



            Filesystem    Mailserver
Testing untestable code

 External resources – Mock database
Testing untestable code

 External resources – Mock database




          Provide own implementation
Testing untestable code

 External resources – Mock database



                      ZF1 example:
          $db = new Custom_Db_Adapter(array());
          Zend_Db_Table::setDefaultAdapter($db);
Testing untestable code

 External resources – Mock database




PHPUnit_Extensions_Database_TestCase
Testing untestable code

 External resources – Mock database
 require_once 
 "PHPUnit/Extensions/Database/TestCase.php";

 class MySampleTest extends 
 PHPUnit_Extensions_Database_TestCase
 {
     public function getConnection() {
         $pdo = new PDO('sqlite::memory:');
         return $this­>createDefaultDBConnection
             $pdo, ':memory:');
     }

     public function getDataSet() {
         return $this­>createFlatXMLDataSet(
             dirname(__FILE__).'/_files/data.xml'
         );
     }
 }
Testing untestable code

 External resources – Mock database




            Proxy for your SQL Server
Testing untestable code

 External resources – Mock webservice
Testing untestable code

 External resources – Mock webservice




          Provide own implementation
Testing untestable code

 External resources – Mock webservice




           Host redirect via /etc/hosts
Testing untestable code

 External resources – Mock filesystem
Testing untestable code

 External resources – Mock filesystem
 <?php

 // set up test environmemt
 vfsStream::setup('exampleDir');

 // create directory in test enviroment
 mkdir(vfsStream::url('exampleDir').'/sample/');

 // check if directory was created
 echo vfsStreamWrapper::getRoot()­>hasChild('sample');
Testing untestable code

 External resources – Mock Mailserver
Testing untestable code

 External resources – Mock Mailserver




                 Use fake mail server
Testing untestable code

 External resources – Mock Mailserver
 $ cat /etc/php5/php.ini | grep sendmail_path
 sendmail_path=/usr/local/bin/logmail

 $ cat /usr/local/bin/logmail
 cat >> /tmp/logmail.log
Testing untestable code

 Dealing with language issues
Testing untestable code

 Dealing with language issues




             Testing your privates?
Testing untestable code

 Dealing with language issues
 <?php
 class CustomWrapper {
    private $_handler;

    function stream_read($count) {
       $content = fread($this­>_handler, $count);
       $content = str_replace(
          'private function',
          'public function', 
          $content
       );
       return $content;
    }
 }
Testing untestable code

 Dealing with language issues
 $myClass = new MyClass();

 $reflectionClass  = new ReflectionClass('MyClass');
 $reflectionMethod = $reflectionClass­>
                         getMethod('mydemo');
 $reflectionMethod­>setAccessible(true);
 $reflectionMethod­>invoke($myClass);
Testing untestable code

 Dealing with language issues




       Overwrite internal functions?
Testing untestable code

 Dealing with language issues




              pecl install runkit-0.9
Testing untestable code

 Dealing with language issues - Runkit
 <?php

 ini_set('runkit.internal_override', '1');

 runkit_function_redefine('mail','','return 
 true;');

 ?>
Testing untestable code

 Dealing with language issues




       pecl install funcall-0.3.0alpha
Testing untestable code

 Dealing with language issues - Funcall
 <?php
 function my_func($arg1, $arg2) {
     return $arg1.$arg2;
 }

 function post_cb($args,$result,
 $process_time) {
   // return custom result based on 
 $args
 }

 fc_add_post('my_func','post_cb');
 var_dump(my_func('php', 'c'));
Testing untestable code

 Dealing with language issues




               funcall for methods?
Testing untestable code

 Dealing with language issues




 git clone https://github/juliens/AOP
Testing untestable code

 Dealing with language issues - AOP
 <?php

 aop_add_after('Car::drive*', 
 'adviceForDrive');
Testing untestable code

 Dealing with language issues - AOP
 <?php

 $advice = function(AopTriggeredJoinpoint
 $jp) {
   $returnValue = 
      $jp­>getReturnedValue();

   // modify the return value
   $returnValue = 1234;

   $jp­>setReturnedValue($returnValue);
 };

 aop_add_after('Car­>drive()', $advice);
Testing untestable code

 And now? Spaghetti mess...
 <?php
 $all_tables_query  = ' SELECT table_name, MAX(version) as
 version FROM ...';
 $all_tables_result = 
 PMA_query_as_controluser($all_tables_query);

 // If a HEAD version exists
 if (PMA_DBI_num_rows($all_tables_result) > 0) {
 ?>
     <div id="tracked_tables">
     <h3><?php echo __('Tracked tables');?></h3>
 <?php
 }
Testing untestable code

 What else?




           Generative Programming
Testing untestable code

 Generative Programming

                          Configuration
                           Configuration
                             (DSL)
                              (DSL)



                                           1..n
   Implementation-
    Implementation-
     components
                          Generator
                          Generator          Product
      components                              Product
Testing untestable code

 Generative Programming

                          Configuration
                           Configuration
                             (DSL)
                              (DSL)
                                           Customer 22
                                            Customer



   Implementation-
    Implementation-
     components
                          Generator
                          Generator        Customer 11
      components                            Customer
Testing untestable code

 Generative Programming

                          Configuration
                           Configuration
                             (DSL)
                              (DSL)
                                              Test
                                               Test
                                           Enviroment
                                            Enviroment



   Implementation-
    Implementation-
     components
                          Generator
                          Generator          Prod.
                                              Prod.
      components                           Enviroment
                                            Enviroment
Testing untestable code

 Generative Programming




       A frame is a data structure
       for representing knowledge.
Testing untestable code

 Frame
 <?php
 class Car {
    private $Engine;

     public function __construct($sEngine) {
        $this­>Engine = <!{Factory}!>::
           getByType($sEngine);
     }

 }
Testing untestable code

 ContentProvider for the Frame
 public class MyContentProvider extends
     AbstractContentProvider {
     public SlotConfiguration computeSlots(
         FeatureConfiguration config) {
         SlotConfiguration sl = new SlotConfiguration();

         if(config.hasFeature("unittest")) {
             sl.put("Factory", "FactoryMock");
         } else {
             sl.put("Factory", "EngineFactory");
         }
         return sl;
     }
 }
Testing untestable code

 Generated result – Test Enviroment
 <?php
 class Car {
    private $Engine;

     public function __construct($sEngine) {
        $this­>Engine = FactoryMock::
           getByType($sEngine);
     }

 }
Testing untestable code

 Generated result – Prod. Enviroment
 <?php
 class Car {
    private $Engine;

     public function __construct($sEngine) {
        $this­>Engine = EngineFactory::
           getByType($sEngine);
     }

 }
Testing untestable code

 Curious for more?




                     http://replicatorframework.org
Thank you!
http://joind.in/7972
Testing untestable code

 Flickr Credits

 http://www.flickr.com/photos/andresrueda/3452940751/
 http://www.flickr.com/photos/andresrueda/3455410635/

More Related Content

What's hot

Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Heiko Behrens
 
Test and refactoring
Test and refactoringTest and refactoring
Test and refactoringKenneth Ceyer
 
Anti-Debugging - A Developers View
Anti-Debugging - A Developers ViewAnti-Debugging - A Developers View
Anti-Debugging - A Developers ViewTyler Shields
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy CodeNaresh Jain
 
JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014DA-14
 
Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Anna Khabibullina
 
Source Boston 2009 - Anti-Debugging A Developers Viewpoint
Source Boston 2009 - Anti-Debugging A Developers ViewpointSource Boston 2009 - Anti-Debugging A Developers Viewpoint
Source Boston 2009 - Anti-Debugging A Developers ViewpointTyler Shields
 
Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3makoto tsuyuki
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEAHamletDRC
 
Java if and else
Java if and elseJava if and else
Java if and elsepratik8897
 
IronSmalltalk
IronSmalltalkIronSmalltalk
IronSmalltalkESUG
 
Static Analysis and AST Transformations
Static Analysis and AST TransformationsStatic Analysis and AST Transformations
Static Analysis and AST TransformationsHamletDRC
 
UI testing in Xcode 7
UI testing in Xcode 7UI testing in Xcode 7
UI testing in Xcode 7Dominique Stranz
 
Invokedynamic / JSR-292
Invokedynamic / JSR-292Invokedynamic / JSR-292
Invokedynamic / JSR-292ytoshima
 
Java 7 new features
Java 7 new featuresJava 7 new features
Java 7 new featuresShivam Goel
 

What's hot (19)

Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
 
Test and refactoring
Test and refactoringTest and refactoring
Test and refactoring
 
Anti-Debugging - A Developers View
Anti-Debugging - A Developers ViewAnti-Debugging - A Developers View
Anti-Debugging - A Developers View
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014
 
Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)
 
C++ boot camp part 1/2
C++ boot camp part 1/2C++ boot camp part 1/2
C++ boot camp part 1/2
 
Source Boston 2009 - Anti-Debugging A Developers Viewpoint
Source Boston 2009 - Anti-Debugging A Developers ViewpointSource Boston 2009 - Anti-Debugging A Developers Viewpoint
Source Boston 2009 - Anti-Debugging A Developers Viewpoint
 
ZF2 Presentation @PHP Tour 2011 in Lille
ZF2 Presentation @PHP Tour 2011 in LilleZF2 Presentation @PHP Tour 2011 in Lille
ZF2 Presentation @PHP Tour 2011 in Lille
 
Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEA
 
Java if and else
Java if and elseJava if and else
Java if and else
 
IronSmalltalk
IronSmalltalkIronSmalltalk
IronSmalltalk
 
Static Analysis and AST Transformations
Static Analysis and AST TransformationsStatic Analysis and AST Transformations
Static Analysis and AST Transformations
 
UI testing in Xcode 7
UI testing in Xcode 7UI testing in Xcode 7
UI testing in Xcode 7
 
Invokedynamic / JSR-292
Invokedynamic / JSR-292Invokedynamic / JSR-292
Invokedynamic / JSR-292
 
Java 7 new features
Java 7 new featuresJava 7 new features
Java 7 new features
 
AMIS definer invoker rights
AMIS definer invoker rightsAMIS definer invoker rights
AMIS definer invoker rights
 

Viewers also liked

Manual de oftalmologia (Cirugia 2 - UPAO)
Manual de oftalmologia (Cirugia 2 - UPAO)Manual de oftalmologia (Cirugia 2 - UPAO)
Manual de oftalmologia (Cirugia 2 - UPAO)gianmarco109
 
Anamnesis espectro autista
Anamnesis espectro autistaAnamnesis espectro autista
Anamnesis espectro autistaFrancescaNa
 
Formulario de Aptitud FĂ­sica 2
Formulario de Aptitud FĂ­sica 2Formulario de Aptitud FĂ­sica 2
Formulario de Aptitud FĂ­sica 2Elena Feal
 
Historia clinica optometrica
Historia clinica optometricaHistoria clinica optometrica
Historia clinica optometricaArely Ruiz
 

Viewers also liked (7)

Manual de oftalmologia (Cirugia 2 - UPAO)
Manual de oftalmologia (Cirugia 2 - UPAO)Manual de oftalmologia (Cirugia 2 - UPAO)
Manual de oftalmologia (Cirugia 2 - UPAO)
 
Historia clinica
Historia clinica Historia clinica
Historia clinica
 
Historia clinica
Historia clinicaHistoria clinica
Historia clinica
 
Anamnesis espectro autista
Anamnesis espectro autistaAnamnesis espectro autista
Anamnesis espectro autista
 
Formulario de Aptitud FĂ­sica 2
Formulario de Aptitud FĂ­sica 2Formulario de Aptitud FĂ­sica 2
Formulario de Aptitud FĂ­sica 2
 
Historia clinica
Historia clinicaHistoria clinica
Historia clinica
 
Historia clinica optometrica
Historia clinica optometricaHistoria clinica optometrica
Historia clinica optometrica
 

Similar to Testing untestable code - ConFoo13

Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Stephan HochdĂśrfer
 
Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Stephan HochdĂśrfer
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend TestingNeil Crosby
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript TestingKissy Team
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023Caleb Jenkins
 
Unit Testing Android Applications
Unit Testing Android ApplicationsUnit Testing Android Applications
Unit Testing Android ApplicationsRody Middelkoop
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - GreachHamletDRC
 
"Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,...
"Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,..."Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,...
"Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,...Vladimir Ivanov
 
Test driven development for infrastructure as-a-code, the future trend_Gianfr...
Test driven development for infrastructure as-a-code, the future trend_Gianfr...Test driven development for infrastructure as-a-code, the future trend_Gianfr...
Test driven development for infrastructure as-a-code, the future trend_Gianfr...Katherine Golovinova
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD WorkshopWolfram Arnold
 
DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)Steve Upton
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Codeerikmsp
 
Unit tests & TDD
Unit tests & TDDUnit tests & TDD
Unit tests & TDDDror Helper
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockRobot Media
 
Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Codejameshalsall
 
PVS-Studio and static code analysis technique
PVS-Studio and static code analysis techniquePVS-Studio and static code analysis technique
PVS-Studio and static code analysis techniqueAndrey Karpov
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Unit test
Unit testUnit test
Unit testTran Duc
 

Similar to Testing untestable code - ConFoo13 (20)

Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Testing untestable code - oscon 2012
Testing untestable code - oscon 2012
 
Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
 
Unit Testing Android Applications
Unit Testing Android ApplicationsUnit Testing Android Applications
Unit Testing Android Applications
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
"Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,...
"Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,..."Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,...
"Formal Verification in Java" by Shura Iline, Vladimir Ivanov @ JEEConf 2013,...
 
Test
TestTest
Test
 
Test driven development for infrastructure as-a-code, the future trend_Gianfr...
Test driven development for infrastructure as-a-code, the future trend_Gianfr...Test driven development for infrastructure as-a-code, the future trend_Gianfr...
Test driven development for infrastructure as-a-code, the future trend_Gianfr...
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
 
DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Code
 
Unit tests & TDD
Unit tests & TDDUnit tests & TDD
Unit tests & TDD
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Code
 
PVS-Studio and static code analysis technique
PVS-Studio and static code analysis techniquePVS-Studio and static code analysis technique
PVS-Studio and static code analysis technique
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Unit test
Unit testUnit test
Unit test
 

More from Stephan HochdĂśrfer

Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...Stephan HochdÜrfer
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8Stephan HochdĂśrfer
 
Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Stephan HochdĂśrfer
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Stephan HochdĂśrfer
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Stephan HochdĂśrfer
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Stephan HochdĂśrfer
 
Offline Strategien fĂźr HTML5 Web Applikationen - dwx13
Offline Strategien fĂźr HTML5 Web Applikationen - dwx13 Offline Strategien fĂźr HTML5 Web Applikationen - dwx13
Offline Strategien fĂźr HTML5 Web Applikationen - dwx13 Stephan HochdĂśrfer
 
Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Stephan HochdĂśrfer
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Stephan HochdĂśrfer
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Stephan HochdĂśrfer
 
Offline-Strategien fĂźr HTML5 Web Applikationen - wmka
Offline-Strategien fĂźr HTML5 Web Applikationen - wmkaOffline-Strategien fĂźr HTML5 Web Applikationen - wmka
Offline-Strategien fĂźr HTML5 Web Applikationen - wmkaStephan HochdĂśrfer
 
Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13
Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13
Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13Stephan HochdĂśrfer
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Stephan HochdĂśrfer
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Stephan HochdĂśrfer
 
Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12
Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12
Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12Stephan HochdĂśrfer
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Stephan HochdĂśrfer
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Stephan HochdĂśrfer
 
Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12
Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12
Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12Stephan HochdÜrfer
 

More from Stephan HochdĂśrfer (20)

Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien fßr offlinefähige Applikationen in HTML5 - Herbst...
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
 
Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13
 
Offline Strategien fĂźr HTML5 Web Applikationen - dwx13
Offline Strategien fĂźr HTML5 Web Applikationen - dwx13 Offline Strategien fĂźr HTML5 Web Applikationen - dwx13
Offline Strategien fĂźr HTML5 Web Applikationen - dwx13
 
Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13
 
Offline-Strategien fĂźr HTML5 Web Applikationen - wmka
Offline-Strategien fĂźr HTML5 Web Applikationen - wmkaOffline-Strategien fĂźr HTML5 Web Applikationen - wmka
Offline-Strategien fĂźr HTML5 Web Applikationen - wmka
 
Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13
Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13
Offline-Strategien fĂźr HTML5 Web Applikationen - bedcon13
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
 
A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
 
Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12
Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12
Offline-Strategien fĂźr HTML5Web Applikationen - WMMRN12
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012
 
Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12
Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12
Wie Software-Generatoren die Welt verändern kÜnnen - Herbstcampus12
 

Recently uploaded

Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...Anamikakaur10
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxAndy Lambert
 
Falcon Invoice Discounting: The best investment platform in india for investors
Falcon Invoice Discounting: The best investment platform in india for investorsFalcon Invoice Discounting: The best investment platform in india for investors
Falcon Invoice Discounting: The best investment platform in india for investorsFalcon Invoice Discounting
 
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876dlhescort
 
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRLBAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRLkapoorjyoti4444
 
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...Aggregage
 
Phases of Negotiation .pptx
 Phases of Negotiation .pptx Phases of Negotiation .pptx
Phases of Negotiation .pptxnandhinijagan9867
 
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...rajveerescorts2022
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...lizamodels9
 
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesDipal Arora
 
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdfDr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdfAdmir Softic
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756dollysharma2066
 
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...allensay1
 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Neil Kimberley
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageMatteo Carbone
 
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service BangaloreCall Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangaloreamitlee9823
 
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableSeo
 
Call Girls In Panjim North Goa 9971646499 Genuine Service
Call Girls In Panjim North Goa 9971646499 Genuine ServiceCall Girls In Panjim North Goa 9971646499 Genuine Service
Call Girls In Panjim North Goa 9971646499 Genuine Serviceritikaroy0888
 

Recently uploaded (20)

Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptx
 
Falcon Invoice Discounting: The best investment platform in india for investors
Falcon Invoice Discounting: The best investment platform in india for investorsFalcon Invoice Discounting: The best investment platform in india for investors
Falcon Invoice Discounting: The best investment platform in india for investors
 
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
 
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRLBAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
 
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
 
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
 
Phases of Negotiation .pptx
 Phases of Negotiation .pptx Phases of Negotiation .pptx
Phases of Negotiation .pptx
 
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
👉Chandigarh Call Girls 👉9878799926👉Just Call👉Chandigarh Call Girl In Chandiga...
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
 
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
 
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdfDr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
 
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usage
 
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service BangaloreCall Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
 
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
 
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabiunwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
 
Call Girls In Panjim North Goa 9971646499 Genuine Service
Call Girls In Panjim North Goa 9971646499 Genuine ServiceCall Girls In Panjim North Goa 9971646499 Genuine Service
Call Girls In Panjim North Goa 9971646499 Genuine Service
 

Testing untestable code - ConFoo13

  • 1. Testing untestable code Stephan HochdĂśrfer, bitExpert AG
  • 2. Testing untestable code About me  Stephan HochdĂśrfer  Head of IT at bitExpert AG, Germany  enjoying PHP since 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • 3. Testing untestable code No excuse for writing bad code!
  • 4.
  • 5.
  • 6. Testing untestable code "Hang the rules. They're more like guidelines anyway." Elizabeth Swann, Pirates of the Caribbean
  • 7. Testing untestable code "There is no secret to writing tests, there are only secrets to write testable code!" MiĹĄko Hevery
  • 8. Testing untestable code What is „untestable code“?
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14. Testing untestable code "...our test strategy requires us to have more control [...] of the sut." Gerard Meszaros, xUnit Test Patterns: Refactoring Test Code
  • 15. Testing untestable code In a perfect world... Unittest Unittest SUT SUT
  • 16. Testing untestable code Legacy code is not perfect... Dependency Dependency Unittest Unittest SUT SUT Dependency Dependency
  • 17. Testing untestable code ... Legacy code is not perfect... Dependency Dependency Unittest Unittest SUT SUT Dependency Dependency ...
  • 18. Testing untestable code ... Legacy code is not perfect... Dependency Dependency Unittest Unittest SUT SUT Dependency Dependency ...
  • 19. Testing untestable code How to get „testable“ code?
  • 20. Testing untestable code How to get „testable“ code? Refactoring
  • 21. Testing untestable code "Before you start refactoring, check that you have a solid suite of tests." Martin Fowler, Refactoring
  • 22.
  • 23. Testing untestable code Which path to take?
  • 24. Testing untestable code Which path to take? Do not change existing code!
  • 25. Testing untestable code Examples Object Construction External resources Language issues
  • 26. Testing untestable code Object construction <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = Engine::getByType($sEngine); } }
  • 27. Testing untestable code Object construction - Autoload <?php function run_autoload($psClass) { $sFileToInclude = strtolower($psClass).'.php'; if(strtolower($psClass) == 'engine') { $sFileToInclude = '/custom/mocks/'.       $sFileToInclude; } include($sFileToInclude); } // Testcase spl_autoload_register('run_autoload'); $oCar = new Car('Diesel'); echo $oCar­>run();
  • 28. Testing untestable code Object construction <?php include('Engine.php'); class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = Engine::getByType($sEngine); } }
  • 29. Testing untestable code Object construction - include_path <?php ini_set('include_path', '/custom/mocks/'.PATH_SEPARATOR. ini_get('include_path')); // Testcase include('car.php'); $oCar = new Car('Diesel'); echo $oCar­>run();
  • 30. Testing untestable code Object construction – Stream Wrapper <?php class CustomWrapper {   private $_handler;   function stream_open($path, $mode, $options,  &$opened_path) {     stream_wrapper_restore('file');  // @TODO: modify $path before fopen     $this­>_handler = fopen($path, $mode);     stream_wrapper_unregister('file');     stream_wrapper_register('file', 'CustomWrapper');     return true;   } }
  • 31. Testing untestable code Object construction – Stream Wrapper stream_wrapper_unregister('file'); stream_wrapper_register('file', 'CustomWrapper');
  • 32. Testing untestable code Object construction – Stream Wrapper <?php class CustomWrapper { private $_handler; function stream_read($count) { $content = fread($this­>_handler, $count); $content = str_replace('Engine::getByType',        'AbstractEngine::get', $content); return $content; } }
  • 33. Testing untestable code External resources
  • 34. Testing untestable code External resources Database Webservice Filesystem Mailserver
  • 35. Testing untestable code External resources – Mock database
  • 36. Testing untestable code External resources – Mock database Provide own implementation
  • 37. Testing untestable code External resources – Mock database ZF1 example: $db = new Custom_Db_Adapter(array()); Zend_Db_Table::setDefaultAdapter($db);
  • 38. Testing untestable code External resources – Mock database PHPUnit_Extensions_Database_TestCase
  • 39. Testing untestable code External resources – Mock database require_once  "PHPUnit/Extensions/Database/TestCase.php"; class MySampleTest extends  PHPUnit_Extensions_Database_TestCase {     public function getConnection() {         $pdo = new PDO('sqlite::memory:');         return $this­>createDefaultDBConnection         $pdo, ':memory:');     }     public function getDataSet() {         return $this­>createFlatXMLDataSet(         dirname(__FILE__).'/_files/data.xml'     );     } }
  • 40. Testing untestable code External resources – Mock database Proxy for your SQL Server
  • 41. Testing untestable code External resources – Mock webservice
  • 42. Testing untestable code External resources – Mock webservice Provide own implementation
  • 43. Testing untestable code External resources – Mock webservice Host redirect via /etc/hosts
  • 44. Testing untestable code External resources – Mock filesystem
  • 45. Testing untestable code External resources – Mock filesystem <?php // set up test environmemt vfsStream::setup('exampleDir'); // create directory in test enviroment mkdir(vfsStream::url('exampleDir').'/sample/'); // check if directory was created echo vfsStreamWrapper::getRoot()­>hasChild('sample');
  • 46. Testing untestable code External resources – Mock Mailserver
  • 47. Testing untestable code External resources – Mock Mailserver Use fake mail server
  • 48. Testing untestable code External resources – Mock Mailserver $ cat /etc/php5/php.ini | grep sendmail_path sendmail_path=/usr/local/bin/logmail $ cat /usr/local/bin/logmail cat >> /tmp/logmail.log
  • 49. Testing untestable code Dealing with language issues
  • 50. Testing untestable code Dealing with language issues Testing your privates?
  • 51. Testing untestable code Dealing with language issues <?php class CustomWrapper { private $_handler; function stream_read($count) { $content = fread($this­>_handler, $count); $content = str_replace(          'private function',          'public function',           $content       ); return $content; } }
  • 52. Testing untestable code Dealing with language issues $myClass = new MyClass(); $reflectionClass  = new ReflectionClass('MyClass'); $reflectionMethod = $reflectionClass­> getMethod('mydemo'); $reflectionMethod­>setAccessible(true); $reflectionMethod­>invoke($myClass);
  • 53. Testing untestable code Dealing with language issues Overwrite internal functions?
  • 54. Testing untestable code Dealing with language issues pecl install runkit-0.9
  • 55. Testing untestable code Dealing with language issues - Runkit <?php ini_set('runkit.internal_override', '1'); runkit_function_redefine('mail','','return  true;'); ?>
  • 56. Testing untestable code Dealing with language issues pecl install funcall-0.3.0alpha
  • 57. Testing untestable code Dealing with language issues - Funcall <?php function my_func($arg1, $arg2) {     return $arg1.$arg2; } function post_cb($args,$result, $process_time) {   // return custom result based on  $args } fc_add_post('my_func','post_cb'); var_dump(my_func('php', 'c'));
  • 58. Testing untestable code Dealing with language issues funcall for methods?
  • 59. Testing untestable code Dealing with language issues git clone https://github/juliens/AOP
  • 60. Testing untestable code Dealing with language issues - AOP <?php aop_add_after('Car::drive*',  'adviceForDrive');
  • 61. Testing untestable code Dealing with language issues - AOP <?php $advice = function(AopTriggeredJoinpoint $jp) {   $returnValue =       $jp­>getReturnedValue();   // modify the return value   $returnValue = 1234;   $jp­>setReturnedValue($returnValue); }; aop_add_after('Car­>drive()', $advice);
  • 62. Testing untestable code And now? Spaghetti mess... <?php $all_tables_query  = ' SELECT table_name, MAX(version) as version FROM ...'; $all_tables_result =  PMA_query_as_controluser($all_tables_query); // If a HEAD version exists if (PMA_DBI_num_rows($all_tables_result) > 0) { ?>     <div id="tracked_tables">     <h3><?php echo __('Tracked tables');?></h3> <?php }
  • 63.
  • 64.
  • 65. Testing untestable code What else? Generative Programming
  • 66. Testing untestable code Generative Programming Configuration Configuration (DSL) (DSL) 1..n Implementation- Implementation- components Generator Generator Product components Product
  • 67. Testing untestable code Generative Programming Configuration Configuration (DSL) (DSL) Customer 22 Customer Implementation- Implementation- components Generator Generator Customer 11 components Customer
  • 68. Testing untestable code Generative Programming Configuration Configuration (DSL) (DSL) Test Test Enviroment Enviroment Implementation- Implementation- components Generator Generator Prod. Prod. components Enviroment Enviroment
  • 69. Testing untestable code Generative Programming A frame is a data structure for representing knowledge.
  • 70. Testing untestable code Frame <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = <!{Factory}!>:: getByType($sEngine); } }
  • 71. Testing untestable code ContentProvider for the Frame public class MyContentProvider extends     AbstractContentProvider {     public SlotConfiguration computeSlots(         FeatureConfiguration config) {         SlotConfiguration sl = new SlotConfiguration();         if(config.hasFeature("unittest")) {             sl.put("Factory", "FactoryMock");         } else {             sl.put("Factory", "EngineFactory");         }         return sl;     } }
  • 72. Testing untestable code Generated result – Test Enviroment <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = FactoryMock:: getByType($sEngine); } }
  • 73. Testing untestable code Generated result – Prod. Enviroment <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = EngineFactory:: getByType($sEngine); } }
  • 74. Testing untestable code Curious for more? http://replicatorframework.org
  • 77. Testing untestable code Flickr Credits http://www.flickr.com/photos/andresrueda/3452940751/ http://www.flickr.com/photos/andresrueda/3455410635/