Testing untestable code - DCHH
Upcoming SlideShare
Loading in...5
×
 

Testing untestable code - DCHH

on

  • 1,342 views

 

Statistics

Views

Total Views
1,342
Views on SlideShare
1,330
Embed Views
12

Actions

Likes
0
Downloads
3
Comments
0

1 Embed 12

http://lanyrd.com 12

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Testing untestable code - DCHH Testing untestable code - DCHH Presentation Transcript

  • Testing untestable code
  • Testing untestable code Über mich  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  PHP Fanboy seit 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • Testing untestable code Keine Entschuldigung für schlechten Code!
  • Testing untestable code Nicht ausflippen!
  • Testing untestable code Kreativität zählt!
  • 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 1. Falsche Instantiierung “new” is evil! s
  • Testing untestable code 2. Starke Kopplung
  • Testing untestable code Keine Wiederverwendbarkeit
  • Testing untestable code Nicht isolierbar, nicht testbar!
  • Testing untestable code 3. Ungewissheit
  • 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 Hoffnung? ...ist nicht genug
  • Testing untestable code Wohin führt die Reise?
  • Testing untestable code Wohin führt die Reise? Vorhandenen Code nicht ändern!
  • Testing untestable code Beispiele Objekterzeugung Externe Ressourcen Sprachbarrieren
  • Testing untestable code Objekterzeugung <?php class Car { private $engine; public function __construct($engine) { $this->engine = Engine::getByType($engine); } }
  • Testing untestable code Objekterzeugung - Autoload <?php function run_autoload($class) { $fileToInclude = strtolower($class)..php; if(strtolower($class) == engine) { $fileToInclude = /custom/mocks/. $fileToInclude; } include($fileToInclude); } // Testcase spl_autoload_register(run_autoload); $car = new Car(Diesel); echo $car->run();
  • Testing untestable code Objekterzeugung <?php include(Engine.php); class Car { private $engine; public function __construct($engine) { $this->engine = Engine::getByType($engine); } }
  • Testing untestable code Objekterzeugung - include_path <?php ini_set(include_path, /custom/mocks/.PATH_SEPARATOR. ini_get(include_path)); // Testcase include(car.php); $car = new Car(Diesel); echo $car->run();
  • 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 stream_wrapper_unregister(file); stream_wrapper_register(file, CustomWrapper);
  • 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 , Abstract Engine::get , $content ); return $content ; } }
  • Testing untestable code Objekterzeugung – Namespaces <?php class Car { private $engine; public function __construct($engine) { $this->engine = CarEngine:: getByType($engine); } }
  • 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 ZF Beispiel: $db = new Custom_Db_Adapter(array()); Zend_Db_Table::setDefaultAdapter($db);
  • Testing untestable code Externe Ressourcen – Datenbank mocken PHPUnit_Extensions_Database_TestCase
  • Testing untestable code Externe Ressourcen – Datenbank mocken Proxy for 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 – Dateisystem mocken <?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 Externe Ressourcen – Mailserver mocken
  • Testing untestable code Externe Ressourcen – Mailserver mocken fake mail server verwenden
  • Testing untestable code Externe Ressourcen – Mailserver mocken $ 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 Sprachbarrieren
  • Testing untestable code Sprachbarrieren private Methoden testen?
  • 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 $myClass = new MyClass(); $reflectionClass = new ReflectionClass(MyClass); $reflectionMethod = $reflectionClass-> getMethod(mydemo); $reflectionMethod->setAccessible(true); $reflectionMethod->invoke($myClass);
  • 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 Spielraum?
  • Testing untestable code Abstrahieren du sollst!
  • Testing untestable code Was sonst? Generative Programmierung
  • Testing untestable code Generative Programmierung Generator Generator
  • Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Generator Generator
  • Software generieren statt programmieren Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Implementierungs- Implementierungs- komponenten Generator Generator komponenten
  • 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) Tests Tests Implementierungs- Implementierungs- komponenten Generator Generator Applikation komponenten Applikation
  • Testing untestable code Generative Programmierung Ein Frame ist eine Datenstruktur die Wissen repräsentiert.
  • Testing untestable code Eine Frame Instanz <?php class Car { private $engine; public function __construct($engine) { $this->engine = <!{Factory}!>:: getByType($engine); } }
  • Testing untestable code Der Frame Controller public class MyFrameController extends SimpleFrameController { public void execute(Frame frame, FeatureConfig config) { if(config.hasFeature("unittest")) { frame.setSlot("Factory", "FactoryMock"); } else { frame.setSlot("Factory", "EngineFactory"); } } }
  • Testing untestable code Nach der Generierung - Testcase <?php class Car { private $engine; public function __construct($engine) { $this->engine = FactoryMock:: getByType($engine); } }
  • Testing untestable code Nach der Generierung - Applikation <?php class Car { private $engine; public function __construct($engine) { $this->engine = EngineFactory:: getByType($engine); } }
  • 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!
  • Testing untestable code Bildquellen http://www.flickr.com/photos/andresrueda/3452940751/ http://www.flickr.com/photos/andresrueda/3455410635/