Testing untestable code - Herbstcampus12

  • 307 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
307
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
1
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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. Testing untestable code "There is no secret to writing tests, there are only secrets to write testable code!" Miško Hevery
  • 5. Testing untestable code Was ist „untestbarer Code“?
  • 6. Testing untestable code "...our test strategy requires us to have more control [...] of the sut." Gerard Meszaros, xUnit Test Patterns: Refactoring Test Code
  • 7. Testing untestable code In einer perfekten Welt.. Unittest Unittest SUT SUT
  • 8. Testing untestable code Legacy code ist nicht perfekt... Abhängige Abhängige Klasse Klasse Unittest Unittest SUT SUT Abhängige Abhängige Klasse Klasse
  • 9. Testing untestable code ... Legacy code ist nicht perfekt... Abhängige Abhängige Klasse Klasse Unittest Unittest SUT SUT Abhängige Abhängige Klasse Klasse ...
  • 10. Testing untestable code ... Legacy code ist nicht perfekt... Abhängige Abhängige Klasse Klasse Unittest Unittest SUT SUT Abhängige Abhängige Klasse Klasse ...
  • 11. Testing untestable code Wie erzeugt man „testbaren Code“?
  • 12. Testing untestable code Wie erzeugt man „testbaren Code“? Refactoring
  • 13. Testing untestable code "Before you start refactoring, check that you have a solid suite of tests." Martin Fowler, Refactoring
  • 14. Testing untestable code Wohin führt die Reise?
  • 15. Testing untestable code Wohin führt die Reise? Wichtig: vorhandenen Code nicht verändern!
  • 16. Testing untestable code Beispiele Objekterzeugung Externe Ressourcen Sprachbarrieren
  • 17. Testing untestable code Objekterzeugung public class Car { private Engine engine; public Car(String engine) { this.engine = EngineFactory.getByType(engine); } }
  • 18. 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); } } }
  • 19. 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; } }
  • 20. 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; } }
  • 21. Testing untestable code Externe Ressourcen
  • 22. Testing untestable code Externe Ressourcen Datenbank Webservice Dateisystem Mailserver
  • 23. Testing untestable code Externe Ressourcen – Datenbank mocken
  • 24. Testing untestable code Externe Ressourcen – Datenbank mocken Eigene Implementierung anbieten
  • 25. Testing untestable code Externe Ressourcen – Datenbank mocken junit + dbunit
  • 26. Testing untestable code Externe Ressourcen – Datenbank mockenPHPUnit_Extensions_Database_TestCase
  • 27. Testing untestable code Externe Ressourcen – Datenbank mocken Proxy für den SQL Server
  • 28. Testing untestable code Externe Ressourcen – Webservice mocken
  • 29. Testing untestable code Externe Ressourcen – Webservice mocken Eigene Implementierung anbieten
  • 30. Testing untestable code Externe Ressourcen – Webservice mocken Host Alias via /etc/hosts
  • 31. Testing untestable code Externe Ressourcen – Dateisytem mocken
  • 32. Testing untestable code Externe Ressourcen – Dateisytem mocken Commons-VFS
  • 33. Testing untestable code Externe Ressourcen – Dateisytem mocken vfsStream
  • 34. Testing untestable code Externe Ressourcen – Dateisystem mocken
  • 35. Testing untestable code Externe Ressourcen – Mailserver mocken
  • 36. Testing untestable code Externe Ressourcen – Mailserver mocken fake mail server verwenden
  • 37. 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
  • 38. Testing untestable code Externe Ressourcen – Mailserver mocken Wem Dumbster zu blöd ist nutzt wiser ;)
  • 39. 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
  • 40. Testing untestable code Sprachbarrieren
  • 41. Testing untestable code Sprachbarrieren private Methoden testen?
  • 42. 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;   }
  • 43. 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; } }
  • 44. Testing untestable code Sprachbarrieren Interne Funktionen überschreiben?
  • 45. Testing untestable code Sprachbarrieren - Runkit pecl install runkit-0.9
  • 46. Testing untestable code Sprachbarrieren - Runkit <?php ini_set(runkit.internal_override, 1); runkit_function_redefine(mail,,return true;);
  • 47. 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 }
  • 48. Testing untestable code Was sonst? Generative Programmierung
  • 49. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) 1..n Implementierungs- Implementierungs- komponenten Generator Generator Produkt komponenten Produkt
  • 50. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Kunde 22 Kunde Implementierungs- Implementierungs- komponenten Generator Generator Kunde 11 komponenten Kunde
  • 51. Testing untestable code Generative Programmierung Konfiguration Konfiguration (DSL) (DSL) Test Test Umgebung Umgebung Implementierungs- Implementierungs- komponenten Generator Generator Prod. Prod. komponenten Umgebung Umgebung
  • 52. Testing untestable code Generative Programmierung Ein Frame ist eine Datenstruktur die Wissen repräsentiert.
  • 53. Testing untestable code Frame <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = <!{Factory}!>:: getByType($sEngine); } }
  • 54. 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;     } }
  • 55. Testing untestable code Ergebnis der Generierung: Test Umgebung <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = FactoryMock:: getByType($sEngine); } }
  • 56. Testing untestable code Ergebnis der Generierung: Prod. Umgebung <?php class Car { private $Engine; public function __construct($sEngine) { $this­>Engine = EngineFactory:: getByType($sEngine); } }
  • 57. Testing untestable code Lust auf mehr? http://replicatorframework.org
  • 58. Testing untestable code Was ist möglich?
  • 59. Testing untestable code Was ist möglich? Extraktion von Codezeilen
  • 60. Testing untestable code Was ist möglich? Globale Inhalte verändern
  • 61. Testing untestable code Was ist möglich? Pre- oder Postfixes für Methoden
  • 62. Testing untestable code Wie weit sollte man gehen?
  • 63. Vielen Dank!