your code are my tests - phpcon poland 2014
DESCRIPTION
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.TRANSCRIPT
![Page 1: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/1.jpg)
2
Your code are my tests
![Page 2: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/2.jpg)
2
ADVISORYIN 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 [email protected].
![Page 3: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/3.jpg)
3
Michelangelo van Dam!!
PHP Consultant Community Leader
President of PHPBenelux Contributor
![Page 4: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/4.jpg)
Why bother with tes3ng?
4
http
s://w
ww.
flick
r.com
/pho
tos/
vial
bost
/553
3266
530
![Page 5: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/5.jpg)
Reasons why not to test
• No %me • No budget • We deliver tests a4er delivery ( this means never ) • We don’t know how…
5
![Page 6: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/6.jpg)
No excuses!!!
6
Crea%ve Co
mmon
s -‐ h@p://www.flickr.com
/pho
tos/akrabat/8421560178
![Page 7: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/7.jpg)
Responsibility issue
• As a developer, it’s your job to • write code & fixing bugs • add documenta%on • write & update unit tests
7
![Page 8: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/8.jpg)
Pizza principle
8
Topping: your tests
Box: your documenta%on
Dough: your code
![Page 9: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/9.jpg)
Benefits of tes3ng
• Direct feedback (test fails) • Once a test is made, it will always be tested • Easy to refactor exis%ng code (protec%on) • Easy to debug: write a test to see if a bug is genuine • Higher confidence and less uncertainty
9
![Page 10: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/10.jpg)
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
![Page 11: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/11.jpg)
Warming up
11
http
s://w
ww.
flick
r.com
/pho
tos/
bobj
agen
dorf/
8535
3168
36
![Page 12: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/12.jpg)
PHPUnit
• PHPUnit is a port of xUnit tes%ng framework • Created by “Sebas%an Bergmann” • Uses “asser%ons” to verify behaviour of “unit of code” • Open source and hosted on GitHub
• See h@ps://github.com/sebas%anbergmann/phpunit • Can be installed using:
• PEAR • PHAR • Composer
12
![Page 13: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/13.jpg)
Approach for tes3ng
• Instan%ate a “unit-‐of-‐code” • Assert expected result against actual result • Provide a custom error message
13
![Page 14: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/14.jpg)
Available asser3ons• assertArrayHasKey() • assertClassHasA@ribute() • assertClassHasSta%cA@ribute() • assertContains() • assertContainsOnly() • assertContainsOnlyInstancesOf() • assertCount() • assertEmpty() • assertEqualXMLStructure() • assertEquals() • assertFalse() • assertFileEquals() • assertFileExists() • assertGreaterThan() • assertGreaterThanOrEqual() • assertInstanceOf() • assertInternalType() • assertJsonFileEqualsJsonFile() • assertJsonStringEqualsJsonFile() • assertJsonStringEqualsJsonString()
• assertLessThan() • assertLessThanOrEqual() • assertNull() • assertObjectHasA@ribute() • assertRegExp() • assertStringMatchesFormat() • assertStringMatchesFormatFile() • assertSame() • assertSelectCount() • assertSelectEquals() • assertSelectRegExp() • assertStringEndsWith() • assertStringEqualsFile() • assertStringStartsWith() • assertTag() • assertThat() • assertTrue() • assertXmlFileEqualsXmlFile() • assertXmlStringEqualsXmlFile() • assertXmlStringEqualsXmlString()
14
![Page 15: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/15.jpg)
To protect and to serve
15
![Page 16: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/16.jpg)
Data is tainted, ALWAYS
16
Hackers BAD DATA
Web S
ervicesStupid users
![Page 19: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/19.jpg)
OWASP top 10 exploits
19https://www.owasp.org/index.php/Top_10_2013-Top_10
![Page 21: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/21.jpg)
Smallest unit of code
21
http
s://w
ww.
flick
r.com
/pho
tos/
tool
stop
/454
6017
269
![Page 22: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/22.jpg)
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
![Page 23: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/23.jpg)
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
![Page 24: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/24.jpg)
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
![Page 25: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/25.jpg)
Example: tes3ng payments<?php namespace Myapp\Common\Payment; 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
![Page 26: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/26.jpg)
We don’t live in a fairy tale!
26
http
s://w
ww.
flick
r.com
/pho
tos/
bertk
not/8
1752
1490
9
![Page 27: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/27.jpg)
Real code, real apps
27
![Page 28: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/28.jpg)
github.com/Telaxus/EPESI
28
![Page 29: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/29.jpg)
Running the project
29
![Page 30: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/30.jpg)
Where are the TESTS?
30
![Page 31: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/31.jpg)
Where are the TESTS?
31
![Page 32: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/32.jpg)
Oh noes, no tests!
32
http
s://w
ww.
flick
r.com
/pho
tos/
mjh
agen
/297
3212
926
![Page 33: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/33.jpg)
Let’s get started
33
http
s://w
ww.
flick
r.com
/pho
tos/
npob
re/2
6015
8225
6
![Page 34: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/34.jpg)
How to get about it?
34
![Page 35: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/35.jpg)
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
![Page 36: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/36.jpg)
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 • sa%sfy_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
![Page 37: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/37.jpg)
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
![Page 38: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/38.jpg)
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
![Page 39: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/39.jpg)
Run test
39
![Page 40: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/40.jpg)
Check coverage
40
![Page 41: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/41.jpg)
Test for second condi3onpublic 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
![Page 42: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/42.jpg)
Run tests
42
![Page 43: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/43.jpg)
Check coverage
43
![Page 44: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/44.jpg)
Test for third condi3onpublic 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
![Page 45: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/45.jpg)
Run tests
45
![Page 46: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/46.jpg)
Check code coverage
46
![Page 47: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/47.jpg)
Non-‐executable code
47
http
s://w
ww.
flick
r.com
/pho
tos/
dazj
ohns
on/7
7208
0682
4
![Page 48: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/48.jpg)
Test for successpublic 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
![Page 49: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/49.jpg)
Run tests
49
![Page 50: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/50.jpg)
Check code coverage
50
![Page 51: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/51.jpg)
Look at the global coverage
51
![Page 52: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/52.jpg)
Bridging gaps
52
http
s://w
ww.
flick
r.com
/pho
tos/
hugo
90/6
9807
1264
3
![Page 53: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/53.jpg)
Privates exposed
53 http
://w
ww.
slas
hgea
r.com
/form
er-ts
a-ag
ent-a
dmits
-we-
knew
-full-
body
-sca
nner
s-di
dnt-w
ork-
3131
5288
/
![Page 54: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/54.jpg)
Dependency• __construct • get_module_name • get_version_min • get_version_max • is_sa%sfied_by • requires • requires_exact • requires_at_least • requires_range
54
![Page 55: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/55.jpg)
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
![Page 56: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/56.jpg)
Don’t touch my junk!
56
http
s://w
ww.
flick
r.com
/pho
tos/
case
ymul
timed
ia/5
4122
9373
0
![Page 57: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/57.jpg)
House of Reflec3on
57
http
s://w
ww.
flick
r.com
/pho
tos/
tabo
r-roe
der/8
2507
7011
5
![Page 58: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/58.jpg)
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
![Page 59: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/59.jpg)
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
![Page 60: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/60.jpg)
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
![Page 61: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/61.jpg)
Run tests
61
![Page 62: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/62.jpg)
Code Coverage
62
![Page 63: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/63.jpg)
Yes, paradise exists
63
http
s://w
ww.
flick
r.com
/pho
tos/
rnug
raha
/200
3147
365
![Page 64: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/64.jpg)
Unit tes3ng is not difficult!
64
![Page 65: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/65.jpg)
You just need to get started
65
![Page 66: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/66.jpg)
PHP has all the tools
66
![Page 67: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/67.jpg)
And there are more roads to Rome
67
![Page 68: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/68.jpg)
Recommended reading
68
![Page 70: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/70.jpg)
Ques3ons?
70
http
s://w
ww.
flick
r.com
/pho
tos/
mdp
ettit
t/867
1901
426
![Page 71: Your code are my tests - PHPCon Poland 2014](https://reader034.vdocument.in/reader034/viewer/2022051816/5476de5fb4af9fd6028b47d3/html5/thumbnails/71.jpg)
71
joind.in/11840!!
If you liked my talk, thanks. If not, let me know how to improve it