Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
2 
Your 
code 
are 
my 
tests 
How 
to 
test 
legacy 
code
ADVISORY 
IN ORDER TO EXPLAIN CERTAIN SITUATIONS YOU MIGHT FACE IN YOUR 
DEVELOPMENT CAREER, WE WILL BE DISCUSSING THE USA...
3 
Michelangelo van Dam! 
! 
PHP Consultant 
Community Leader 
President of PHPBenelux 
Contributor
Why 
bother 
with 
tes3ng? 
4 
https://www.flickr.com/photos/vialbost/5533266530
Reasons 
why 
not 
to 
test 
• No 
0me 
• No 
budget 
• We 
deliver 
tests 
a8er 
delivery 
( 
this 
means 
never 
) 
• We...
No 
excuses!!! 
6 
Crea0ve 
Commons 
-­‐ 
hBp://www.flickr.com/photos/akrabat/8421560178
Responsibility 
issue 
• As 
a 
developer, 
it’s 
your 
job 
to 
• write 
code 
& 
fixing 
bugs 
• add 
documenta0on 
• wr...
Pizza 
principle 
8 
Topping: 
your 
tests 
Box: 
your 
documenta0on 
Dough: 
your 
code
Benefits 
of 
tes3ng 
• Direct 
feedback 
(test 
fails) 
• Once 
a 
test 
is 
made, 
it 
will 
always 
be 
tested 
• Easy ...
Rule 
of 
thumb 
“Whenever 
you 
are 
tempted 
to 
type 
something 
into 
a 
print 
statement 
or 
a 
debugger 
expression...
Warming 
up 
11 
https://www.flickr.com/photos/bobjagendorf/8535316836
PHPUnit 
• PHPUnit 
is 
a 
port 
of 
xUnit 
tes0ng 
framework 
• Created 
by 
“Sebas0an 
Bergmann” 
• Uses 
“asser0ons” 
t...
Approach 
for 
tes3ng 
• Instan0ate 
a 
“unit-­‐of-­‐code” 
• Assert 
expected 
result 
against 
actual 
result 
• Provide...
Available 
asser3ons 
• assertArrayHasKey() 
• assertClassHasABribute() 
• assertClassHasSta0cABribute() 
• assertContains...
To 
protect 
and 
to 
serve 
15
Data 
is 
tainted, 
ALWAYS 
Hackers 
BAD DATA 
Web Services 
16 
Stupid users
17
18
OWASP 
top 
10 
exploits 
https://www.owasp.org/index.php/Top_10_2013-Top_10 
19
Filtering 
& 
Valida3on 
20
Smallest 
unit 
of 
code 
21 
https://www.flickr.com/photos/toolstop/4546017269
Example 
class 
<?php ! 
/** ! 
* Example class ! 
*/ ! 
class MyClass ! 
{ ! 
/** ... */ ! 
public function doSomething($...
Tes3ng 
for 
good 
/** ... */! 
public function testClassAcceptsValidRequiredArgument() ! 
{ ! 
$expected = $argument = 'T...
Tes3ng 
for 
bad 
/** ! 
* @expectedException InvalidArgumentException ! 
*/ ! 
public function testExceptionIsThrownForIn...
Example: 
tes3ng 
payments 
<?php 
namespace 
MyappCommonPayment; 
class 
ProcessTest 
extends 
PHPUnit_Framework_TestCase...
We 
don’t 
live 
in 
a 
fairy 
tale! 
26 
https://www.flickr.com/photos/bertknot/8175214909
Real 
code, 
real 
apps 
27
github.com/Telaxus/EPESI 
28
Running 
the 
project 
29
Where 
are 
the 
TESTS? 
30
Where 
are 
the 
TESTS? 
31
Oh 
noes, 
no 
tests! 
32 
https://www.flickr.com/photos/mjhagen/2973212926
Let’s 
get 
started 
33 
https://www.flickr.com/photos/npobre/2601582256
How 
to 
get 
about 
it? 
34
Se]ng 
up 
for 
tes3ng 
<phpunit colors="true" stopOnError="true" stopOnFailure="true">! 
<testsuites>! 
<testsuite name="...
ModuleManager 
• not_loaded_modules 
• loaded_modules 
• modules 
• modules_install 
• modules_common 
• root 
• processin...
ModuleManager::module_install 
/** ! 
* Includes file with module installation class. ! 
* ! 
* Do not use directly. ! 
* ...
Tes3ng 
first 
condi3on 
<?php ! 
! 
require_once 'include.php'; ! 
! 
class ModuleManagerTest extends PHPUnit_Framework_T...
Run 
test 
39
Check 
coverage 
40
Test 
for 
second 
condi3on 
public function testLoadingNonExistingModuleIsNotExecuted() ! 
{ ! 
$module = 'Foo_Bar'; ! 
$...
Run 
tests 
42
Check 
coverage 
43
Test 
for 
third 
condi3on 
public function testNoInstallationOfModuleWithoutInstallationClass() ! 
{ ! 
$module = 'EssCli...
Run 
tests 
45
Check 
code 
coverage 
46
Non-­‐executable 
code 
47 
https://www.flickr.com/photos/dazjohnson/7720806824
Test 
for 
success 
public function testIncludeClassFileForLoadingModule() ! 
{ ! 
$module = 'Base_About'; ! 
$result = Mo...
Run 
tests 
49
Check 
code 
coverage 
50
Look 
at 
the 
global 
coverage 
51
Bridging 
gaps 
52 
https://www.flickr.com/photos/hugo90/6980712643
Privates 
exposed 
53 
http://www.slashgear.com/former-tsa-agent-admits-we-knew-full-body-scanners-didnt-work-31315288/
Dependency 
• __construct 
• get_module_name 
• get_version_min 
• get_version_max 
• is_sa0sfied_by 
• requires 
• requir...
A 
private 
constructor! 
<?php ! 
! 
defined("_VALID_ACCESS") || die('Direct access forbidden'); ! 
! 
/** ! 
* This clas...
Don’t 
touch 
my 
junk! 
56 
https://www.flickr.com/photos/caseymultimedia/5412293730
House 
of 
Reflec3on 
57 
https://www.flickr.com/photos/tabor-roeder/8250770115
Let’s 
do 
this… 
<?php ! 
require_once 'include.php'; ! 
! 
class DependencyTest extends PHPUnit_Framework_TestCase ! 
{ ...
Let’s 
use 
the 
sta3c 
$params = array ( ! 
'moduleName' => 'Foo_Bar', ! 
'minVersion' => 0, ! 
'maxVersion' => 1, ! 
'ma...
Use 
the 
reflec3on 
to 
assert 
// Let's retrieve the private properties ! 
$moduleName = $reflectionClass->getProperty('...
Run 
tests 
61
Code 
Coverage 
62
Yes, 
paradise 
exists 
63 
https://www.flickr.com/photos/rnugraha/2003147365
Unit 
tes3ng 
is 
not 
difficult! 
64
You 
just 
need 
to 
get 
started 
65
PHP 
has 
all 
the 
tools 
66
And 
there 
are 
more 
roads 
to 
Rome 
67
Recommended 
reading 
68
joind.in/12558! 
! 
Slides are on joindin 
While you're there give some feedback 
! 
If you liked my talk, thanks. 
If not...
Ques3ons? 
70 
https://www.flickr.com/photos/mdpettitt/8671901426
Need 
help? 
71 
Michelangelo van Dam 
! 
michelangelo@in2it.be 
@DragonBe 
www.in2it.be
Upcoming SlideShare
Loading in …5
×

of

Your code are my tests - ZendUncon 2014 Slide 1 Your code are my tests - ZendUncon 2014 Slide 2 Your code are my tests - ZendUncon 2014 Slide 3 Your code are my tests - ZendUncon 2014 Slide 4 Your code are my tests - ZendUncon 2014 Slide 5 Your code are my tests - ZendUncon 2014 Slide 6 Your code are my tests - ZendUncon 2014 Slide 7 Your code are my tests - ZendUncon 2014 Slide 8 Your code are my tests - ZendUncon 2014 Slide 9 Your code are my tests - ZendUncon 2014 Slide 10 Your code are my tests - ZendUncon 2014 Slide 11 Your code are my tests - ZendUncon 2014 Slide 12 Your code are my tests - ZendUncon 2014 Slide 13 Your code are my tests - ZendUncon 2014 Slide 14 Your code are my tests - ZendUncon 2014 Slide 15 Your code are my tests - ZendUncon 2014 Slide 16 Your code are my tests - ZendUncon 2014 Slide 17 Your code are my tests - ZendUncon 2014 Slide 18 Your code are my tests - ZendUncon 2014 Slide 19 Your code are my tests - ZendUncon 2014 Slide 20 Your code are my tests - ZendUncon 2014 Slide 21 Your code are my tests - ZendUncon 2014 Slide 22 Your code are my tests - ZendUncon 2014 Slide 23 Your code are my tests - ZendUncon 2014 Slide 24 Your code are my tests - ZendUncon 2014 Slide 25 Your code are my tests - ZendUncon 2014 Slide 26 Your code are my tests - ZendUncon 2014 Slide 27 Your code are my tests - ZendUncon 2014 Slide 28 Your code are my tests - ZendUncon 2014 Slide 29 Your code are my tests - ZendUncon 2014 Slide 30 Your code are my tests - ZendUncon 2014 Slide 31 Your code are my tests - ZendUncon 2014 Slide 32 Your code are my tests - ZendUncon 2014 Slide 33 Your code are my tests - ZendUncon 2014 Slide 34 Your code are my tests - ZendUncon 2014 Slide 35 Your code are my tests - ZendUncon 2014 Slide 36 Your code are my tests - ZendUncon 2014 Slide 37 Your code are my tests - ZendUncon 2014 Slide 38 Your code are my tests - ZendUncon 2014 Slide 39 Your code are my tests - ZendUncon 2014 Slide 40 Your code are my tests - ZendUncon 2014 Slide 41 Your code are my tests - ZendUncon 2014 Slide 42 Your code are my tests - ZendUncon 2014 Slide 43 Your code are my tests - ZendUncon 2014 Slide 44 Your code are my tests - ZendUncon 2014 Slide 45 Your code are my tests - ZendUncon 2014 Slide 46 Your code are my tests - ZendUncon 2014 Slide 47 Your code are my tests - ZendUncon 2014 Slide 48 Your code are my tests - ZendUncon 2014 Slide 49 Your code are my tests - ZendUncon 2014 Slide 50 Your code are my tests - ZendUncon 2014 Slide 51 Your code are my tests - ZendUncon 2014 Slide 52 Your code are my tests - ZendUncon 2014 Slide 53 Your code are my tests - ZendUncon 2014 Slide 54 Your code are my tests - ZendUncon 2014 Slide 55 Your code are my tests - ZendUncon 2014 Slide 56 Your code are my tests - ZendUncon 2014 Slide 57 Your code are my tests - ZendUncon 2014 Slide 58 Your code are my tests - ZendUncon 2014 Slide 59 Your code are my tests - ZendUncon 2014 Slide 60 Your code are my tests - ZendUncon 2014 Slide 61 Your code are my tests - ZendUncon 2014 Slide 62 Your code are my tests - ZendUncon 2014 Slide 63 Your code are my tests - ZendUncon 2014 Slide 64 Your code are my tests - ZendUncon 2014 Slide 65 Your code are my tests - ZendUncon 2014 Slide 66 Your code are my tests - ZendUncon 2014 Slide 67 Your code are my tests - ZendUncon 2014 Slide 68 Your code are my tests - ZendUncon 2014 Slide 69 Your code are my tests - ZendUncon 2014 Slide 70 Your code are my tests - ZendUncon 2014 Slide 71
Upcoming SlideShare
Navidad
Next
Download to read offline and view in fullscreen.

2 Likes

Share

Download to read offline

Your code are my tests - ZendUncon 2014

Download to read offline

After years of promoting PHPUnit I still hear it's hard to get started with unit testing. So instead of showing nice step-by-step examples on how to use PHPUnit, we're going to take examples straight from github and start writing tests for them where I explain the issue, how we test it and how we finally got things tested. So I take on the challenge to start writing tests for PHP projects that already have unit tests in place (like major frameworks) and projects that not even started with unit testing.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Your code are my tests - ZendUncon 2014

  1. 1. 2 Your code are my tests How to test legacy code
  2. 2. ADVISORY IN ORDER TO EXPLAIN CERTAIN SITUATIONS YOU MIGHT FACE IN YOUR DEVELOPMENT CAREER, WE WILL BE DISCUSSING THE USAGE OF PRIVATES AND PUBLIC EXPOSURE. IF THESE TOPICS OFFEND OR UPSET YOU, WE WOULD LIKE TO ASK YOU TO LEAVE THIS ROOM NOW. ! THE SPEAKER NOR THE ORGANISATION CANNOT BE HELD ACCOUNTABLE FOR MENTAL DISTRESS OR ANY FORMS OF DAMAGE YOU MIGHT ENDURE DURING OR AFTER THIS PRESENTATION. FOR COMPLAINTS PLEASE INFORM ORGANISATION AT INFO@ZEND.COM. 2
  3. 3. 3 Michelangelo van Dam! ! PHP Consultant Community Leader President of PHPBenelux Contributor
  4. 4. Why bother with tes3ng? 4 https://www.flickr.com/photos/vialbost/5533266530
  5. 5. Reasons why not to test • No 0me • No budget • We deliver tests a8er delivery ( this means never ) • We don’t know how… 5
  6. 6. No excuses!!! 6 Crea0ve Commons -­‐ hBp://www.flickr.com/photos/akrabat/8421560178
  7. 7. Responsibility issue • As a developer, it’s your job to • write code & fixing bugs • add documenta0on • write & update unit tests 7
  8. 8. Pizza principle 8 Topping: your tests Box: your documenta0on Dough: your code
  9. 9. Benefits of tes3ng • Direct feedback (test fails) • Once a test is made, it will always be tested • Easy to refactor exis0ng code (protec0on) • Easy to debug: write a test to see if a bug is genuine • Higher confidence and less uncertainty 9
  10. 10. Rule of thumb “Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead.” ! — Source: Mar?n Fowler 10
  11. 11. Warming up 11 https://www.flickr.com/photos/bobjagendorf/8535316836
  12. 12. PHPUnit • PHPUnit is a port of xUnit tes0ng framework • Created by “Sebas0an Bergmann” • Uses “asser0ons” to verify behaviour of “unit of code” • Open source and hosted on GitHub • See hBps://github.com/sebas0anbergmann/phpunit • Can be installed using: • PEAR • PHAR • Composer 12
  13. 13. Approach for tes3ng • Instan0ate a “unit-­‐of-­‐code” • Assert expected result against actual result • Provide a custom error message 13
  14. 14. Available asser3ons • assertArrayHasKey() • assertClassHasABribute() • assertClassHasSta0cABribute() • assertContains() • assertContainsOnly() • assertContainsOnlyInstancesOf() • assertCount() • assertEmpty() • assertEqualXMLStructure() • assertEquals() • assertFalse() • assertFileEquals() • assertFileExists() • assertGreaterThan() • assertGreaterThanOrEqual() • assertInstanceOf() • assertInternalType() • assertJsonFileEqualsJsonFile() • assertJsonStringEqualsJsonFile() • assertJsonStringEqualsJsonString() • assertLessThan() • assertLessThanOrEqual() • assertNull() • assertObjectHasABribute() • assertRegExp() • assertStringMatchesFormat() • assertStringMatchesFormatFile() • assertSame() • assertSelectCount() • assertSelectEquals() • assertSelectRegExp() • assertStringEndsWith() • assertStringEqualsFile() • assertStringStartsWith() • assertTag() • assertThat() • assertTrue() • assertXmlFileEqualsXmlFile() • assertXmlStringEqualsXmlFile() • assertXmlStringEqualsXmlString() 14
  15. 15. To protect and to serve 15
  16. 16. Data is tainted, ALWAYS Hackers BAD DATA Web Services 16 Stupid users
  17. 17. 17
  18. 18. 18
  19. 19. OWASP top 10 exploits https://www.owasp.org/index.php/Top_10_2013-Top_10 19
  20. 20. Filtering & Valida3on 20
  21. 21. Smallest unit of code 21 https://www.flickr.com/photos/toolstop/4546017269
  22. 22. Example class <?php ! /** ! * Example class ! */ ! class MyClass ! { ! /** ... */ ! public function doSomething($requiredParam, $optionalParam = null) ! { ! if (!filter_var( ! $requiredParam, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH ! )) { ! throw new InvalidArgumentException('Invalid argument provided'); ! } ! if (null !== $optionalParam) { ! if (!filter_var( ! $optionalParam, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH ! )) { ! throw new InvalidArgumentException('Invalid argument provided'); ! } ! $requiredParam .= ' - ' . $optionalParam; ! } ! return $requiredParam; ! } ! } 22
  23. 23. Tes3ng for good /** ... */! public function testClassAcceptsValidRequiredArgument() ! { ! $expected = $argument = 'Testing PHP Class'; ! $myClass = new MyClass; ! $result = $myClass->doSomething($argument); ! $this->assertSame($expected, $result, ! 'Expected result differs from actual result'); ! } ! ! /** ... */ ! public function testClassAcceptsValidOptionalArgument() ! { ! $requiredArgument = 'Testing PHP Class'; ! $optionalArgument = 'Is this not fun?!?'; ! $expected = $requiredArgument . ' - ' . $optionalArgument; ! $myClass = new MyClass; ! $result = $myClass->doSomething($requiredArgument, $optionalArgument); ! $this->assertSame($expected, $result, ! 'Expected result differs from actual result'); ! } 23
  24. 24. Tes3ng for bad /** ! * @expectedException InvalidArgumentException ! */ ! public function testExceptionIsThrownForInvalidRequiredArgument() ! { ! $expected = $argument = new StdClass; ! $myClass = new MyClass; ! $result = $myClass->doSomething($argument); ! $this->assertSame($expected, $result, ! 'Expected result differs from actual result'); ! } ! ! /** ! * @expectedException InvalidArgumentException ! */ ! public function testExceptionIsThrownForInvalidOptionalArgument() ! { ! $requiredArgument = 'Testing PHP Class'; ! $optionalArgument = new StdClass; ! $myClass = new MyClass; ! $result = $myClass->doSomething($requiredArgument, $optionalArgument); ! $this->assertSame($expected, $result, ! 'Expected result differs from actual result'); ! } 24
  25. 25. Example: tes3ng payments <?php namespace MyappCommonPayment; class ProcessTest extends PHPUnit_Framework_TestCase { public function testPaymentIsProcessedCorrectly() { $customer = new Customer(/* data for customer */); $transaction = new Transaction(/* data for transaction */); $process = new Process('sale', $customer, $transaction); $process-­‐>pay(); $this-­‐>assertTrue($process-­‐>paymentApproved()); $this-­‐>assertEquals('PAY-­‐17S8410768582940NKEE66EQ', $process-­‐>getPaymentId()); } } 25
  26. 26. We don’t live in a fairy tale! 26 https://www.flickr.com/photos/bertknot/8175214909
  27. 27. Real code, real apps 27
  28. 28. github.com/Telaxus/EPESI 28
  29. 29. Running the project 29
  30. 30. Where are the TESTS? 30
  31. 31. Where are the TESTS? 31
  32. 32. Oh noes, no tests! 32 https://www.flickr.com/photos/mjhagen/2973212926
  33. 33. Let’s get started 33 https://www.flickr.com/photos/npobre/2601582256
  34. 34. How to get about it? 34
  35. 35. Se]ng up for tes3ng <phpunit colors="true" stopOnError="true" stopOnFailure="true">! <testsuites>! <testsuite name="EPESI admin tests">! <directory phpVersion="5.3.0">tests/admin</directory>! </testsuite>! <testsuite name="EPESI include tests">! <directory phpVersion="5.3.0">tests/include</directory>! </testsuite>! <testsuite name="EPESI modules testsuite">! <directory phpVersion="5.3.0">tests/modules</directory>! </testsuite>! </testsuites>! <php>! <const name="DEBUG_AUTOLOADS" value="1"/>! <const name="CID" value="1234567890123456789"/>! </php>! <logging>! <log type="coverage-html" target="build/coverage" charset="UTF-8"/>! <log type="coverage-clover" target="build/logs/clover.xml"/>! <log type="junit" target="build/logs/junit.xml"/>! </logging>! </phpunit> 35
  36. 36. ModuleManager • not_loaded_modules • loaded_modules • modules • modules_install • modules_common • root • processing • processed_modules • include_install • include_common • include_main • create_load_priority_array • check_dependencies • sa0sfy_dependencies • get_module_dir_path • get_module_file_name • list_modules • exists • register • unregister • is_installed • upgrade • downgrade • get_module_class_name • install • uninstall • get_processed_modules • get_load_priority_array • new_instance • get_instance • create_data_dir • remove_data_dir • get_data_dir • load_modules • create_common_cache • create_root • check_access • call_common_methods • check_common_methods • required_modules • reset_cron 36
  37. 37. ModuleManager::module_install /** ! * Includes file with module installation class. ! * ! * Do not use directly. ! * ! * @param string $module_class_name module class name - underscore separated ! */ ! public static final function include_install($module_class_name) { ! if(isset(self::$modules_install[$module_class_name])) return true; ! $path = self::get_module_dir_path($module_class_name); ! $file = self::get_module_file_name($module_class_name); ! $full_path = 'modules/' . $path . '/' . $file . 'Install.php'; ! if (!file_exists($full_path)) return false; ! ob_start(); ! $ret = require_once($full_path); ! ob_end_clean(); ! $x = $module_class_name.'Install'; ! if(!(class_exists($x, false)) || ! !array_key_exists('ModuleInstall',class_parents($x))) ! trigger_error('Module '.$path.': Invalid install file',E_USER_ERROR); ! self::$modules_install[$module_class_name] = new $x($module_class_name); ! return true; ! } 37
  38. 38. Tes3ng first condi3on <?php ! ! require_once 'include.php'; ! ! class ModuleManagerTest extends PHPUnit_Framework_TestCase ! { ! protected function tearDown() ! { ! ModuleManager::$modules_install = array (); ! } ! ! public function testReturnImmediatelyWhenModuleAlreadyLoaded() ! { ! $module = 'Foo_Bar'; ! ModuleManager::$modules_install[$module] = 1; ! $result = ModuleManager::include_install($module); ! $this->assertTrue($result, ! 'Expecting that an already installed module returns true'); ! $this->assertCount(1, ModuleManager::$modules_install, ! 'Expecting to find 1 module ready for installation'); ! } ! } 38
  39. 39. Run test 39
  40. 40. Check coverage 40
  41. 41. Test for second condi3on public function testLoadingNonExistingModuleIsNotExecuted() ! { ! $module = 'Foo_Bar'; ! $result = ModuleManager::include_install($module); ! $this->assertFalse($result, 'Expecting failure for loading Foo_Bar'); ! $this->assertEmpty(ModuleManager::$modules_install, ! 'Expecting to find no modules ready for installation'); ! } 41
  42. 42. Run tests 42
  43. 43. Check coverage 43
  44. 44. Test for third condi3on public function testNoInstallationOfModuleWithoutInstallationClass() ! { ! $module = 'EssClient_IClient'; ! $result = ModuleManager::include_install($module); ! $this->assertFalse($result, 'Expecting failure for loading Foo_Bar'); ! $this->assertEmpty(ModuleManager::$modules_install, ! 'Expecting to find no modules ready for installation'); ! } 44
  45. 45. Run tests 45
  46. 46. Check code coverage 46
  47. 47. Non-­‐executable code 47 https://www.flickr.com/photos/dazjohnson/7720806824
  48. 48. Test for success public function testIncludeClassFileForLoadingModule() ! { ! $module = 'Base_About'; ! $result = ModuleManager::include_install($module); ! $this->assertTrue($result, 'Expected module to be loaded'); ! $this->assertCount(1, ModuleManager::$modules_install, ! 'Expecting to find 1 module ready for installation'); ! } 48
  49. 49. Run tests 49
  50. 50. Check code coverage 50
  51. 51. Look at the global coverage 51
  52. 52. Bridging gaps 52 https://www.flickr.com/photos/hugo90/6980712643
  53. 53. Privates exposed 53 http://www.slashgear.com/former-tsa-agent-admits-we-knew-full-body-scanners-didnt-work-31315288/
  54. 54. Dependency • __construct • get_module_name • get_version_min • get_version_max • is_sa0sfied_by • requires • requires_exact • requires_at_least • requires_range 54
  55. 55. A private constructor! <?php ! ! defined("_VALID_ACCESS") || die('Direct access forbidden'); ! ! /** ! * This class provides dependency requirements ! * @package epesi-base ! * @subpackage module ! */ ! class Dependency { ! ! private $module_name; ! private $version_min; ! private $version_max; ! private $compare_max; ! ! private function __construct(! $module_name, $version_min, $version_max, $version_max_is_ok = true) { ! $this->module_name = $module_name; ! $this->version_min = $version_min; ! $this->version_max = $version_max; ! $this->compare_max = $version_max_is_ok ? '<=' : '<'; ! } ! ! /** ... */ ! } 55
  56. 56. Don’t touch my junk! 56 https://www.flickr.com/photos/caseymultimedia/5412293730
  57. 57. House of Reflec3on 57 https://www.flickr.com/photos/tabor-roeder/8250770115
  58. 58. Let’s do this… <?php ! require_once 'include.php'; ! ! class DependencyTest extends PHPUnit_Framework_TestCase ! { ! public function testConstructorSetsProperSettings() ! { ! require_once 'include/module_dependency.php'; ! ! // We have a problem, the constructor is private!! } ! } 58
  59. 59. Let’s use the sta3c $params = array ( ! 'moduleName' => 'Foo_Bar', ! 'minVersion' => 0, ! 'maxVersion' => 1, ! 'maxOk' => true, ! ); ! // We use a static method for this test ! $dependency = Dependency::requires_range( ! $params['moduleName'], ! $params['minVersion'], ! $params['maxVersion'], ! $params['maxOk'] ! ); ! ! // We use reflection to see if properties are set correctly ! $reflectionClass = new ReflectionClass('Dependency'); 59
  60. 60. Use the reflec3on to assert // Let's retrieve the private properties ! $moduleName = $reflectionClass->getProperty('module_name'); ! $moduleName->setAccessible(true); ! $minVersion = $reflectionClass->getProperty('version_min'); ! $minVersion->setAccessible(true); ! $maxVersion = $reflectionClass->getProperty('version_max'); ! $maxVersion->setAccessible(true); ! $maxOk = $reflectionClass->getProperty('compare_max'); ! $maxOk->setAccessible(true); ! ! // Let's assert ! $this->assertEquals($params['moduleName'], $moduleName->getValue($dependency), ! 'Expected value does not match the value set’);! ! $this->assertEquals($params['minVersion'], $minVersion->getValue($dependency), ! 'Expected value does not match the value set’);! ! $this->assertEquals($params['maxVersion'], $maxVersion->getValue($dependency), ! 'Expected value does not match the value set’);! ! $this->assertEquals('<=', $maxOk->getValue($dependency), ! 'Expected value does not match the value set'); 60
  61. 61. Run tests 61
  62. 62. Code Coverage 62
  63. 63. Yes, paradise exists 63 https://www.flickr.com/photos/rnugraha/2003147365
  64. 64. Unit tes3ng is not difficult! 64
  65. 65. You just need to get started 65
  66. 66. PHP has all the tools 66
  67. 67. And there are more roads to Rome 67
  68. 68. Recommended reading 68
  69. 69. joind.in/12558! ! Slides are on joindin While you're there give some feedback ! If you liked my talk, thanks. If not, let me know how to improve it 69
  70. 70. Ques3ons? 70 https://www.flickr.com/photos/mdpettitt/8671901426
  71. 71. Need help? 71 Michelangelo van Dam ! michelangelo@in2it.be @DragonBe www.in2it.be
  • beejhuff

    May. 12, 2015
  • diovanemonteiro

    Oct. 29, 2014

After years of promoting PHPUnit I still hear it's hard to get started with unit testing. So instead of showing nice step-by-step examples on how to use PHPUnit, we're going to take examples straight from github and start writing tests for them where I explain the issue, how we test it and how we finally got things tested. So I take on the challenge to start writing tests for PHP projects that already have unit tests in place (like major frameworks) and projects that not even started with unit testing.

Views

Total views

919

On Slideshare

0

From embeds

0

Number of embeds

3

Actions

Downloads

7

Shares

0

Comments

0

Likes

2

×