Testing untestable code
Testing untestable code Über mich  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  PHP Fanboy seit ...
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               test...
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 ...
Testing untestable code In einer perfekten Welt..                  Unittest                   Unittest   SUT              ...
Testing untestable code Legacy code ist nicht perfekt...                                    Abhängige                     ...
Testing untestable code                                    ... Legacy code ist nicht perfekt...                           ...
Testing untestable code                                    ... Legacy code ist nicht perfekt...                           ...
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."               ...
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) {  ...
Testing untestable code Objekterzeugung - Autoload <?php function run_autoload($class) {    $fileToInclude = strtolower($c...
Testing untestable code Objekterzeugung <?php include(Engine.php); class Car {    private $engine;     public function __c...
Testing untestable code Objekterzeugung - include_path <?php ini_set(include_path,    /custom/mocks/.PATH_SEPARATOR.    in...
Testing untestable code Objekterzeugung – Stream Wrapper <?php class CustomWrapper {   private $_handler;   function strea...
Testing untestable code Objekterzeugung – Stream Wrapper stream_wrapper_unregister(file); stream_wrapper_register(file, Cu...
Testing untestable code Objekterzeugung – Stream Wrapper <?php class CustomWrapper {    private $_handler ;     function s...
Testing untestable code Objekterzeugung – Namespaces <?php class Car {    private $engine;     public function __construct...
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 Cus...
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(exampleD...
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=...
Testing untestable code Sprachbarrieren
Testing untestable code Sprachbarrieren          private Methoden testen?
Testing untestable code Sprachbarrieren <?php class CustomWrapper {    private $_handler;     function stream_read($count)...
Testing untestable code Sprachbarrieren $myClass = new MyClass(); $reflectionClass = new ReflectionClass(MyClass); $reflec...
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...
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                           Konfigu...
Software generieren statt programmieren Generative Programmierung                                          Konfiguration  ...
Testing untestable code Generative Programmierung                          Konfiguration                           Konfigu...
Testing untestable code Generative Programmierung                          Konfiguration                           Konfigu...
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) ...
Testing untestable code Der Frame Controller public class MyFrameController extends SimpleFrameController {    public void...
Testing untestable code Nach der Generierung - Testcase <?php class Car {    private $engine;     public function __constr...
Testing untestable code Nach der Generierung - Applikation <?php class Car {    private $engine;     public function __con...
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/andr...
Upcoming SlideShare
Loading in...5
×

Testing untestable code - DCHH

1,074

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,074
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Testing untestable code - DCHH

  1. 1. Testing untestable code
  2. 2. Testing untestable code Über mich  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  PHP Fanboy seit 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  3. 3. Testing untestable code Keine Entschuldigung für schlechten Code!
  4. 4. Testing untestable code Nicht ausflippen!
  5. 5. Testing untestable code Kreativität zählt!
  6. 6. Testing untestable code "There is no secret to writing tests, there are only secrets to write testable code!" Miško Hevery
  7. 7. Testing untestable code Was ist „untestbarer Code“?
  8. 8. Testing untestable code 1. Falsche Instantiierung “new” is evil! s
  9. 9. Testing untestable code 2. Starke Kopplung
  10. 10. Testing untestable code Keine Wiederverwendbarkeit
  11. 11. Testing untestable code Nicht isolierbar, nicht testbar!
  12. 12. Testing untestable code 3. Ungewissheit
  13. 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. 14. Testing untestable code In einer perfekten Welt.. Unittest Unittest SUT SUT
  15. 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. 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. 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. 18. Testing untestable code Wie erzeugt man „testbaren Code“?
  19. 19. Testing untestable code Wie erzeugt man „testbaren Code“? Refactoring
  20. 20. Testing untestable code "Before you start refactoring, check that you have a solid suite of tests." Martin Fowler, Refactoring
  21. 21. Testing untestable code Hoffnung? ...ist nicht genug
  22. 22. Testing untestable code Wohin führt die Reise?
  23. 23. Testing untestable code Wohin führt die Reise? Vorhandenen Code nicht ändern!
  24. 24. Testing untestable code Beispiele Objekterzeugung Externe Ressourcen Sprachbarrieren
  25. 25. Testing untestable code Objekterzeugung <?php class Car { private $engine; public function __construct($engine) { $this->engine = Engine::getByType($engine); } }
  26. 26. 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();
  27. 27. Testing untestable code Objekterzeugung <?php include(Engine.php); class Car { private $engine; public function __construct($engine) { $this->engine = Engine::getByType($engine); } }
  28. 28. 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();
  29. 29. 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; } }
  30. 30. Testing untestable code Objekterzeugung – Stream Wrapper stream_wrapper_unregister(file); stream_wrapper_register(file, CustomWrapper);
  31. 31. 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 ; } }
  32. 32. Testing untestable code Objekterzeugung – Namespaces <?php class Car { private $engine; public function __construct($engine) { $this->engine = CarEngine:: getByType($engine); } }
  33. 33. Testing untestable code Externe Ressourcen
  34. 34. Testing untestable code Externe Ressourcen Datenbank Webservice Dateisystem Mailserver
  35. 35. Testing untestable code Externe Ressourcen – Datenbank mocken
  36. 36. Testing untestable code Externe Ressourcen – Datenbank mocken Eigene Implementierung anbieten
  37. 37. Testing untestable code Externe Ressourcen – Datenbank mocken ZF Beispiel: $db = new Custom_Db_Adapter(array()); Zend_Db_Table::setDefaultAdapter($db);
  38. 38. Testing untestable code Externe Ressourcen – Datenbank mocken PHPUnit_Extensions_Database_TestCase
  39. 39. Testing untestable code Externe Ressourcen – Datenbank mocken Proxy for den SQL Server
  40. 40. Testing untestable code Externe Ressourcen – Webservice mocken
  41. 41. Testing untestable code Externe Ressourcen – Webservice mocken Eigene Implementierung anbieten
  42. 42. Testing untestable code Externe Ressourcen – Webservice mocken Host Alias via /etc/hosts
  43. 43. Testing untestable code Externe Ressourcen – Dateisytem mocken
  44. 44. 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);
  45. 45. Testing untestable code Externe Ressourcen – Mailserver mocken
  46. 46. Testing untestable code Externe Ressourcen – Mailserver mocken fake mail server verwenden
  47. 47. 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
  48. 48. Testing untestable code Sprachbarrieren
  49. 49. Testing untestable code Sprachbarrieren private Methoden testen?
  50. 50. 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; }
  51. 51. Testing untestable code Sprachbarrieren $myClass = new MyClass(); $reflectionClass = new ReflectionClass(MyClass); $reflectionMethod = $reflectionClass-> getMethod(mydemo); $reflectionMethod->setAccessible(true); $reflectionMethod->invoke($myClass);
  52. 52. Testing untestable code Sprachbarrieren Interne Funktionen überschreiben?
  53. 53. Testing untestable code Sprachbarrieren - Runkit pecl install runkit-0.9
  54. 54. Testing untestable code Sprachbarrieren - Runkit <?php ini_set(runkit.internal_override, 1); runkit_function_redefine(mail,,return true;); ?>
  55. 55. Testing untestable code Spielraum?
  56. 56. Testing untestable code Abstrahieren du sollst!
  57. 57. Testing untestable code Was sonst? Generative Programmierung
  58. 58. Testing untestable code Generative Programmierung Generator Generator
  59. 59. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Generator Generator
  60. 60. Software generieren statt programmieren Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Implementierungs- Implementierungs- komponenten Generator Generator komponenten
  61. 61. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) 1..n Implementierungs- Implementierungs- komponenten Generator Generator Produkt komponenten Produkt
  62. 62. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Tests Tests Implementierungs- Implementierungs- komponenten Generator Generator Applikation komponenten Applikation
  63. 63. Testing untestable code Generative Programmierung Ein Frame ist eine Datenstruktur die Wissen repräsentiert.
  64. 64. Testing untestable code Eine Frame Instanz <?php class Car { private $engine; public function __construct($engine) { $this->engine = <!{Factory}!>:: getByType($engine); } }
  65. 65. 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"); } } }
  66. 66. Testing untestable code Nach der Generierung - Testcase <?php class Car { private $engine; public function __construct($engine) { $this->engine = FactoryMock:: getByType($engine); } }
  67. 67. Testing untestable code Nach der Generierung - Applikation <?php class Car { private $engine; public function __construct($engine) { $this->engine = EngineFactory:: getByType($engine); } }
  68. 68. Testing untestable code Was ist möglich?
  69. 69. Testing untestable code Was ist möglich? Extraktion von Codezeilen
  70. 70. Testing untestable code Was ist möglich? Globale Inhalte verändern
  71. 71. Testing untestable code Was ist möglich? Pre- oder Postfixes für Methoden
  72. 72. Testing untestable code Wie weit sollte man gehen?
  73. 73. Vielen Dank!
  74. 74. Testing untestable code Bildquellen http://www.flickr.com/photos/andresrueda/3452940751/ http://www.flickr.com/photos/andresrueda/3455410635/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×