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

Testing untestable code - phpconpl11

on

  • 1,432 views

 

Statistics

Views

Total Views
1,432
Views on SlideShare
1,427
Embed Views
5

Actions

Likes
0
Downloads
5
Comments
2

1 Embed 5

http://lanyrd.com 5

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

12 of 2

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Thank you. Was a pleasure to attend phpconpl11.
    Are you sure you want to
    Your message goes here
    Processing…
  • Awesome speech, it was a pleasure to listen you.
    The example code that you shou us, was nice and give me many ideas, and help me in my work.
    I never heard of Runkit. Function runkit_function_redefine() is amazing! This knowledge will help me in many difficult situations.
    I hope one day I will have possibility to listen you again.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Testing untestable code - phpconpl11 Testing untestable code - phpconpl11 Presentation Transcript

    • Testing untestable code
    • Testing untestable code About me  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  enjoying PHP since 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
    • Testing untestable code No excuse for writing bad code!
    • Testing untestable code Not to freak out!
    • Testing untestable code Creativity matters!
    • 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 1. Wrong object construction “new” is evil! s
    • Testing untestable code 2. Tight coupling
    • Testing untestable code No code reuse!
    • Testing untestable code No isolation → not testable!
    • Testing untestable code 3. Uncertainty
    • 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 Hope? - Nope...
    • 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);
    • 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 , Abstract Engine::get , $content ); return $content ; } }
    • Testing untestable code Object construction – Namespaces <?php class Car { private $Engine; public function __construct($sEngine) { $this->Engine = CarEngine:: getByType($sEngine); } }
    • 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 ZF 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 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 What else?
    • Testing untestable code What else? Generative Programming
    • Testing untestable code Generative Programming Configuration Configuration 1 ... n Implementation Implementation Generator Generator Product components components Product Generator Generator application application
    • Testing untestable code Generative Programming Configuration Configuration Application Application Implementation Implementation Generator Generator components components Testcases Testcases Generator Generator application application
    • Testing untestable code Generative Programming A frame is a data structure for representing knowledge.
    • Testing untestable code A Frame instance <?php class Car { private $Engine; public function __construct($sEngine) { $this->Engine = <!{Factory}!>:: getByType($sEngine); } }
    • Testing untestable code The 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 Generated result - Testcase <?php class Car { private $Engine; public function __construct($sEngine) { $this->Engine = FactoryMock:: getByType($sEngine); } }
    • Testing untestable code Generated result - Application <?php class Car { private $Engine; public function __construct($sEngine) { $this->Engine = EngineFactory:: getByType($sEngine); } }
    • Testing untestable code What is possible?
    • Testing untestable code What is possible? Show / hide parts of the code
    • Testing untestable code What is possible? Change content of global vars!
    • Testing untestable code What is possible? Define pre- or postfixes!
    • Testing untestable code Is it worth it?
    • Testing untestable code Conclusions Change your mindset to write testable code!
    • Testing untestable code Conclusions PHP is a swiss-army knife. Use it that way!
    • http://joind.in/3922
    • Testing untestable code Bildquellen http://www.flickr.com/photos/andresrueda/3452940751/ http://www.flickr.com/photos/andresrueda/3455410635/