SlideShare uma empresa Scribd logo
1 de 73
Baixar para ler offline
Testing untestable code
 Dem Legacy Code ein Schnippchen schlagen


 Stephan Hochdörfer
               bitExpert AG
Testing untestable code

 Über mich

  Stephan Hochdörfer, bitExpert AG

  Department Manager Research Labs

  S.Hochdoerfer@bitExpert.de

  @shochdoerfer
Testing untestable code

 Keine Entschuldigung für schlechten Code!
Testing untestable code




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

 Was ist „untestbarer 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 einer perfekten Welt..




                  Unittest
                   Unittest   SUT
                               SUT
Testing untestable code

 Legacy code ist nicht perfekt...


                                    Abhängige
                                     Abhängige
                                      Klasse
                                       Klasse
       Unittest
        Unittest          SUT
                           SUT

                                    Abhängige
                                     Abhängige
                                      Klasse
                                       Klasse
Testing untestable code
                                    ...
 Legacy code ist nicht perfekt...


                                     Abhängige
                                      Abhängige
                                       Klasse
                                        Klasse
       Unittest
        Unittest          SUT
                           SUT

                                     Abhängige
                                      Abhängige
                                       Klasse
                                        Klasse




                                     ...
Testing untestable code
                                    ...
 Legacy code ist nicht perfekt...


                                     Abhängige
                                      Abhängige
                                       Klasse
                                        Klasse
       Unittest
        Unittest          SUT
                           SUT

                                     Abhängige
                                      Abhängige
                                       Klasse
                                        Klasse




                                     ...
Testing untestable code

 Wie erzeugt man „testbaren Code“?
Testing untestable code

 Wie erzeugt man „testbaren Code“?




                  Refactoring
Testing untestable code




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

 Wohin führt die Reise?
Testing untestable code

 Wohin führt die Reise?




       Wichtig: vorhandenen Code
             nicht verändern!
Testing untestable code

 Beispiele




 Objekterzeugung      Externe Ressourcen   Sprachbarrieren
Testing untestable code

 Objekterzeugung
 public class Car {
     private Engine engine;

     public Car(String engine) {
         this.engine = EngineFactory.getByType(engine);
     }
 }
Testing untestable code

 Objekterzeugung - Autoload
 public class MyLoader extends ClassLoader {
     protected Class findClass(String name)
          throws ClassNotFoundException
     {
          try {
              String path = name.replace('.', '/');
              // @TODO: change path and read file, 
              // @TODO: define package
              // @TODO: define class
          }
          catch(Exception e){
              throw new ClassNotFoundException(name);
          }
     }
 }
Testing untestable code

 Objekterzeugung – 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

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

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

 Externe Ressourcen
Testing untestable code

 Externe Ressourcen



            Datenbank     Webservice



           Dateisystem    Mailserver
Testing untestable code

 Externe Ressourcen – Datenbank mocken
Testing untestable code

 Externe Ressourcen – Datenbank mocken




      Eigene Implementierung anbieten
Testing untestable code

 Externe Ressourcen – Datenbank mocken




                     junit + dbunit
Testing untestable code

 Externe Ressourcen – Datenbank mocken




PHPUnit_Extensions_Database_TestCase
Testing untestable code

 Externe Ressourcen – Datenbank mocken




             Proxy für den SQL Server
Testing untestable code

 Externe Ressourcen – Webservice mocken
Testing untestable code

 Externe Ressourcen – Webservice mocken




      Eigene Implementierung anbieten
Testing untestable code

 Externe Ressourcen – Webservice mocken




              Host Alias via /etc/hosts
Testing untestable code

 Externe Ressourcen – Dateisytem mocken
Testing untestable code

 Externe Ressourcen – Dateisytem mocken




                     Commons-VFS
Testing untestable code

 Externe Ressourcen – Dateisytem mocken




                          vfsStream
Testing untestable code

 Externe Ressourcen – Dateisystem mocken
Testing untestable code

 Externe Ressourcen – Mailserver mocken
Testing untestable code

 Externe Ressourcen – Mailserver mocken




           fake mail server verwenden
Testing untestable code

 Externe Ressourcen – Mailserver mocken
 public class SimpleSmtpServerTest extends TestCase {
   public void testSend() {
     SimpleSmtpServer server = SimpleSmtpServer.start();

     // send your message here....

     server.stop();

     assertTrue(server.getReceivedEmailSize() == 1);
     Iterator emailIter = server.getReceivedEmail();
     SmtpMessage email = (SmtpMessage)emailIter.next();
     assertTrue(email.getBody().equals("Test Body"));
   }
 }




 Dumbster – Fake SMTP server
Testing untestable code

 Externe Ressourcen – Mailserver mocken




       Wem Dumbster zu blöd ist
            nutzt wiser ;)
Testing untestable code

 Externe Ressourcen – Mailserver mocken
 wiser.setPort(2500);
 wiser.start();

 for (WiserMessage message : wiser.getMessages())
 {
         String envelopeSender = 
          message.getEnvelopeSender();
         String envelopeReceiver = 
          message.getEnvelopeReceiver();

         MimeMessage mess = message.getMimeMessage();

         // process the message...
 }




 Wiser - The Wiser framework for unit testing mail
Testing untestable code

 Sprachbarrieren
Testing untestable code

 Sprachbarrieren




          private Methoden testen?
Testing untestable code

 Sprachbarrieren
 final Method methods[] = 
 o.getClass().getDeclaredMethods();
 for (int i = 0; i < methods.length; ++i) {
     if (methodName.equals(methods[i].getName())) {
          try {
              methods[i].setAccessible(true);
              return methods[i].invoke(o, params);
          } 
          catch (IllegalAccessException ex) {
          }
          catch (InvocationTargetException ite) {
          }
     }
     return null;  
 }
Testing untestable code

 Sprachbarrieren
 <?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

 Sprachbarrieren




                Interne Funktionen
                  überschreiben?
Testing untestable code

 Sprachbarrieren - Runkit




              pecl install runkit-0.9
Testing untestable code

 Sprachbarrieren - Runkit
 <?php

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

 runkit_function_redefine('mail','','return true;');
Testing untestable code

 Was nun? Was tun?
 <?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

 Was sonst?




        Generative Programmierung
Testing untestable code

 Generative Programmierung

                          Konfiguration
                           Konfiguration
                             (DSL)
                              (DSL)



                                           1..n
  Implementierungs-
   Implementierungs-
    komponenten
                          Generator
                          Generator          Produkt
     komponenten                              Produkt
Testing untestable code

 Generative Programmierung

                          Konfiguration
                           Konfiguration
                             (DSL)
                              (DSL)
                                           Kunde 22
                                            Kunde



  Implementierungs-
   Implementierungs-
    komponenten
                          Generator
                          Generator        Kunde 11
     komponenten                            Kunde
Testing untestable code

 Generative Programmierung

                          Konfiguration
                           Konfiguration
                             (DSL)
                              (DSL)
                                             Test
                                              Test
                                           Umgebung
                                            Umgebung



  Implementierungs-
   Implementierungs-
    komponenten
                          Generator
                          Generator          Prod.
                                              Prod.
     komponenten                           Umgebung
                                            Umgebung
Testing untestable code

 Generative Programmierung




    Ein Frame ist eine Datenstruktur
        die Wissen repräsentiert.
Testing untestable code

 Frame
 <?php
 class Car {
     private $Engine;

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

 }
Testing untestable code

 Der ContentProvider für den 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

 Ergebnis der Generierung: Test Umgebung
 <?php
 class Car {
     private $Engine;

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

 }
Testing untestable code

 Ergebnis der Generierung: Prod. Umgebung
 <?php
 class Car {
     private $Engine;

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

 }
Testing untestable code

 Lust auf mehr?




                     http://replicatorframework.org
Testing untestable code

 Was ist möglich?
Testing untestable code

 Was ist möglich?




            Extraktion von Codezeilen
Testing untestable code

 Was ist möglich?




            Globale Inhalte verändern
Testing untestable code

 Was ist möglich?




       Pre- oder Postfixes für Methoden
Testing untestable code

 Wie weit sollte man gehen?
Vielen Dank!

Mais conteúdo relacionado

Destaque

Testing untestable code - phpconpl11
Testing untestable code - phpconpl11Testing untestable code - phpconpl11
Testing untestable code - phpconpl11Stephan Hochdörfer
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmStephan Hochdörfer
 
Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11Stephan 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
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8Stephan Hochdörfer
 
Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Stephan Hochdörfer
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Innomatic Platform
 
How to build customizable multitenant web applications - IPC11 Spring Edition
How to build customizable multitenant web applications - IPC11 Spring EditionHow to build customizable multitenant web applications - IPC11 Spring Edition
How to build customizable multitenant web applications - IPC11 Spring EditionStephan Hochdörfer
 

Destaque (9)

Testing untestable code - phpconpl11
Testing untestable code - phpconpl11Testing untestable code - phpconpl11
Testing untestable code - phpconpl11
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffm
 
Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11
 
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
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
 
Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010
 
Testing untestable code - DPC10
Testing untestable code - DPC10Testing untestable code - DPC10
Testing untestable code - DPC10
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
 
How to build customizable multitenant web applications - IPC11 Spring Edition
How to build customizable multitenant web applications - IPC11 Spring EditionHow to build customizable multitenant web applications - IPC11 Spring Edition
How to build customizable multitenant web applications - IPC11 Spring Edition
 

Semelhante a Testing untestable code - Herbstcampus12

Funktionstests in SAP
Funktionstests in SAPFunktionstests in SAP
Funktionstests in SAPCadaxo GmbH
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTddjlink
 
Agiles Testing
Agiles TestingAgiles Testing
Agiles TestingNEOMO GmbH
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklungjlink
 
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsjavaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsgedoplan
 
Feige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-UmfeldFeige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-Umfeldgedoplan
 
Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!gedoplan
 
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017Torsten Kleiber
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir seincodepitbull
 
Advanced Refactoring Patterns
Advanced Refactoring PatternsAdvanced Refactoring Patterns
Advanced Refactoring PatternsHendrik Lösch
 
Advanced Refactoring Patterns - Dev Day 2018
Advanced Refactoring Patterns - Dev Day 2018Advanced Refactoring Patterns - Dev Day 2018
Advanced Refactoring Patterns - Dev Day 2018Hendrik Lösch
 
Besseren Java Code mit Type Annotations
Besseren Java Code mit Type AnnotationsBesseren Java Code mit Type Annotations
Besseren Java Code mit Type Annotationsdzuvic
 
Die nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDie nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDaniel Lehner
 
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10Ralf Sigmund
 
Softwarequalität mit Visual Studio 2010
Softwarequalität mit Visual Studio 2010Softwarequalität mit Visual Studio 2010
Softwarequalität mit Visual Studio 2010mspgermany
 
Softwarequalitätssicherung mit Continuous Integration Tools
Softwarequalitätssicherung mit Continuous Integration ToolsSoftwarequalitätssicherung mit Continuous Integration Tools
Softwarequalitätssicherung mit Continuous Integration ToolsGFU Cyrus AG
 
JavaScript für Java-Entwickler W-JAX 2013
JavaScript für Java-Entwickler W-JAX 2013JavaScript für Java-Entwickler W-JAX 2013
JavaScript für Java-Entwickler W-JAX 2013Oliver Zeigermann
 
Feige sein
Feige seinFeige sein
Feige seingedoplan
 
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)Florian Wolters
 

Semelhante a Testing untestable code - Herbstcampus12 (20)

Funktionstests in SAP
Funktionstests in SAPFunktionstests in SAP
Funktionstests in SAP
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
 
Agiles Testing
Agiles TestingAgiles Testing
Agiles Testing
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklung
 
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsjavaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
 
Property Based Testing
Property Based TestingProperty Based Testing
Property Based Testing
 
Feige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-UmfeldFeige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-Umfeld
 
Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!
 
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir sein
 
Advanced Refactoring Patterns
Advanced Refactoring PatternsAdvanced Refactoring Patterns
Advanced Refactoring Patterns
 
Advanced Refactoring Patterns - Dev Day 2018
Advanced Refactoring Patterns - Dev Day 2018Advanced Refactoring Patterns - Dev Day 2018
Advanced Refactoring Patterns - Dev Day 2018
 
Besseren Java Code mit Type Annotations
Besseren Java Code mit Type AnnotationsBesseren Java Code mit Type Annotations
Besseren Java Code mit Type Annotations
 
Die nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDie nächste Generation des Unit Testing
Die nächste Generation des Unit Testing
 
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
 
Softwarequalität mit Visual Studio 2010
Softwarequalität mit Visual Studio 2010Softwarequalität mit Visual Studio 2010
Softwarequalität mit Visual Studio 2010
 
Softwarequalitätssicherung mit Continuous Integration Tools
Softwarequalitätssicherung mit Continuous Integration ToolsSoftwarequalitätssicherung mit Continuous Integration Tools
Softwarequalitätssicherung mit Continuous Integration Tools
 
JavaScript für Java-Entwickler W-JAX 2013
JavaScript für Java-Entwickler W-JAX 2013JavaScript für Java-Entwickler W-JAX 2013
JavaScript für Java-Entwickler W-JAX 2013
 
Feige sein
Feige seinFeige sein
Feige sein
 
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
 

Mais de 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
 
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-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
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Stephan 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
 

Mais de 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...
 
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-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
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13
 
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
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
 
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
 

Testing untestable code - Herbstcampus12

  • 1. Testing untestable code Dem Legacy Code ein Schnippchen schlagen Stephan Hochdörfer bitExpert AG
  • 2. Testing untestable code Über mich  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • 3. Testing untestable code Keine Entschuldigung für schlechten Code!
  • 4.
  • 5.
  • 6. Testing untestable code "There is no secret to writing tests, there are only secrets to write testable code!" Miško Hevery
  • 7. Testing untestable code Was ist „untestbarer Code“?
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13. Testing untestable code "...our test strategy requires us to have more control [...] of the sut." Gerard Meszaros, xUnit Test Patterns: Refactoring Test Code
  • 14. Testing untestable code In einer perfekten Welt.. Unittest Unittest SUT SUT
  • 15. Testing untestable code Legacy code ist nicht perfekt... Abhängige Abhängige Klasse Klasse Unittest Unittest SUT SUT Abhängige Abhängige Klasse Klasse
  • 16. Testing untestable code ... Legacy code ist nicht perfekt... Abhängige Abhängige Klasse Klasse Unittest Unittest SUT SUT Abhängige Abhängige Klasse Klasse ...
  • 17. Testing untestable code ... Legacy code ist nicht perfekt... Abhängige Abhängige Klasse Klasse Unittest Unittest SUT SUT Abhängige Abhängige Klasse Klasse ...
  • 18. Testing untestable code Wie erzeugt man „testbaren Code“?
  • 19. Testing untestable code Wie erzeugt man „testbaren Code“? Refactoring
  • 20. Testing untestable code "Before you start refactoring, check that you have a solid suite of tests." Martin Fowler, Refactoring
  • 21.
  • 22. Testing untestable code Wohin führt die Reise?
  • 23. Testing untestable code Wohin führt die Reise? Wichtig: vorhandenen Code nicht verändern!
  • 24. Testing untestable code Beispiele Objekterzeugung Externe Ressourcen Sprachbarrieren
  • 25. Testing untestable code Objekterzeugung public class Car { private Engine engine; public Car(String engine) { this.engine = EngineFactory.getByType(engine); } }
  • 26. Testing untestable code Objekterzeugung - Autoload public class MyLoader extends ClassLoader { protected Class findClass(String name) throws ClassNotFoundException { try { String path = name.replace('.', '/'); // @TODO: change path and read file,  // @TODO: define package // @TODO: define class } catch(Exception e){ throw new ClassNotFoundException(name); } } }
  • 27. Testing untestable code Objekterzeugung – 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; } }
  • 28. Testing untestable code Objekterzeugung – Stream Wrapper <?php class CustomWrapper { private $_handler; function stream_read($count) { $content = fread($this­>_handler, $count); $content = str_replace('Engine::getByType',        ' Engine2::getByType', $content); return $content; } }
  • 29. Testing untestable code Externe Ressourcen
  • 30. Testing untestable code Externe Ressourcen Datenbank Webservice Dateisystem Mailserver
  • 31. Testing untestable code Externe Ressourcen – Datenbank mocken
  • 32. Testing untestable code Externe Ressourcen – Datenbank mocken Eigene Implementierung anbieten
  • 33. Testing untestable code Externe Ressourcen – Datenbank mocken junit + dbunit
  • 34. Testing untestable code Externe Ressourcen – Datenbank mocken PHPUnit_Extensions_Database_TestCase
  • 35. Testing untestable code Externe Ressourcen – Datenbank mocken Proxy für den SQL Server
  • 36. Testing untestable code Externe Ressourcen – Webservice mocken
  • 37. Testing untestable code Externe Ressourcen – Webservice mocken Eigene Implementierung anbieten
  • 38. Testing untestable code Externe Ressourcen – Webservice mocken Host Alias via /etc/hosts
  • 39. Testing untestable code Externe Ressourcen – Dateisytem mocken
  • 40. Testing untestable code Externe Ressourcen – Dateisytem mocken Commons-VFS
  • 41. Testing untestable code Externe Ressourcen – Dateisytem mocken vfsStream
  • 42. Testing untestable code Externe Ressourcen – Dateisystem mocken
  • 43. Testing untestable code Externe Ressourcen – Mailserver mocken
  • 44. Testing untestable code Externe Ressourcen – Mailserver mocken fake mail server verwenden
  • 45. Testing untestable code Externe Ressourcen – Mailserver mocken public class SimpleSmtpServerTest extends TestCase {   public void testSend() {     SimpleSmtpServer server = SimpleSmtpServer.start();     // send your message here....     server.stop();     assertTrue(server.getReceivedEmailSize() == 1);     Iterator emailIter = server.getReceivedEmail();     SmtpMessage email = (SmtpMessage)emailIter.next();     assertTrue(email.getBody().equals("Test Body"));   } } Dumbster – Fake SMTP server
  • 46. Testing untestable code Externe Ressourcen – Mailserver mocken Wem Dumbster zu blöd ist nutzt wiser ;)
  • 47. Testing untestable code Externe Ressourcen – Mailserver mocken wiser.setPort(2500); wiser.start(); for (WiserMessage message : wiser.getMessages()) {         String envelopeSender =  message.getEnvelopeSender();         String envelopeReceiver =  message.getEnvelopeReceiver();         MimeMessage mess = message.getMimeMessage();         // process the message... } Wiser - The Wiser framework for unit testing mail
  • 48. Testing untestable code Sprachbarrieren
  • 49. Testing untestable code Sprachbarrieren private Methoden testen?
  • 50. Testing untestable code Sprachbarrieren final Method methods[] =  o.getClass().getDeclaredMethods(); for (int i = 0; i < methods.length; ++i) { if (methodName.equals(methods[i].getName())) { try {    methods[i].setAccessible(true); return methods[i].invoke(o, params); }  catch (IllegalAccessException ex) { } catch (InvocationTargetException ite) { } } return null;   }
  • 51. Testing untestable code Sprachbarrieren <?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 Sprachbarrieren Interne Funktionen überschreiben?
  • 53. Testing untestable code Sprachbarrieren - Runkit pecl install runkit-0.9
  • 54. Testing untestable code Sprachbarrieren - Runkit <?php ini_set('runkit.internal_override', '1'); runkit_function_redefine('mail','','return true;');
  • 55. Testing untestable code Was nun? Was tun? <?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 }
  • 56.
  • 57.
  • 58. Testing untestable code Was sonst? Generative Programmierung
  • 59. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) 1..n Implementierungs- Implementierungs- komponenten Generator Generator Produkt komponenten Produkt
  • 60. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Kunde 22 Kunde Implementierungs- Implementierungs- komponenten Generator Generator Kunde 11 komponenten Kunde
  • 61. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Test Test Umgebung Umgebung Implementierungs- Implementierungs- komponenten Generator Generator Prod. Prod. komponenten Umgebung Umgebung
  • 62. Testing untestable code Generative Programmierung Ein Frame ist eine Datenstruktur die Wissen repräsentiert.
  • 63. Testing untestable code Frame <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = <!{Factory}!>:: getByType($sEngine); } }
  • 64. Testing untestable code Der ContentProvider für den 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;     } }
  • 65. Testing untestable code Ergebnis der Generierung: Test Umgebung <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = FactoryMock:: getByType($sEngine); } }
  • 66. Testing untestable code Ergebnis der Generierung: Prod. Umgebung <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = EngineFactory:: getByType($sEngine); } }
  • 67. Testing untestable code Lust auf mehr? http://replicatorframework.org
  • 68. Testing untestable code Was ist möglich?
  • 69. Testing untestable code Was ist möglich? Extraktion von Codezeilen
  • 70. Testing untestable code Was ist möglich? Globale Inhalte verändern
  • 71. Testing untestable code Was ist möglich? Pre- oder Postfixes für Methoden
  • 72. Testing untestable code Wie weit sollte man gehen?