test driven development - zombie proof your code
DESCRIPTION
Changing Legacy code can cause it to come back to life and bite you in the APP! Learn the symptoms and techniques to write testable codeTRANSCRIPT
![Page 1: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/1.jpg)
Test Driven DevelopmentZombie proof your code
![Page 2: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/2.jpg)
Pascal Larocque
● TrustCharge Team● Behat guy● Testing guy● SOLID guy● Pattern guy● Father of 3● Star Wars Geek @pascallarocque
![Page 3: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/3.jpg)
Why do we write code?
● Add New Features● Maintaining old features
![Page 4: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/4.jpg)
What are the challenges?● I can’t understand what the code does● Only the original programmer understands what it does… He’s not
with us anymore● Fixing a Bug creates a NEW BUG● There is no documentation● It’s Only working on my local● We can’t upgrade because all are code is dependent on this
version● The only way to test is with the real data on production● I have to test this manually
![Page 5: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/5.jpg)
What are we really saying?
“I’m Scared...When I change something, some other feature might stop working”
![Page 6: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/6.jpg)
YOU’VE CREATED ZOMBIE CODE
![Page 7: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/7.jpg)
How to survive the Zombie apocalypse
1. Write TESTS!2. Write TESTABLE CODE
![Page 8: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/8.jpg)
The Power of Testable code● Forces Simplification of the code● Simplifies Design● Documentation of the code● Less time debugging● New code doesn’t break old code● Refactoring becomes easier● Interfaces are better designed● Easier to do code reviews● Fearless programming ● Faster than writing code without
tests
![Page 9: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/9.jpg)
How to write testable codePHPUnitDatabase TestingLegacy code testingPHPspec
![Page 10: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/10.jpg)
Why aren’t we testing?● Testing main flow is enough● The code is legacy, impossible to test● Don’t have time to test● Fix bug first then write a test● To be on the safe side manual testing is mandatory● No one else is writing tests● Testing and maintaining tests will cost more time● After changing code, I have to change a bunch of test
![Page 11: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/11.jpg)
Sorry to say this but...
![Page 12: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/12.jpg)
DON’T BLAME TESTING!MISSING PROFESSIONALISM
WRONG DESIGN
LOSING DISCIPLINE NO-TEST DEVELOPMENT
INEXPERIENCED DEVELOPERS
UNREVIEWED CODE
![Page 13: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/13.jpg)
“THE SECRET TO TESTING IS WRITING TESTABLE CODE”
![Page 14: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/14.jpg)
“If the answer is not obvious, or if the tests looks like the tests would be ugly or had to write, then take that as a warning signal.
Your design probably needs to modified; change things around until the code is easy to test, and your design will end up being better for the effort”
HOW TO GET STARTED?
![Page 15: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/15.jpg)
How can you tell if your code isn’t going to come back from the SVN and BYTE you in the APP?
Look for the following SYMPTOMS.
![Page 16: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/16.jpg)
SYMPTOMS - CONSTRUCTOR DOES TOO MUCH
● Using the NEW keyword in the constructor● STATIC METHOD calls● Anything more than field assignment● Object not fully initialized after constructor● CONTROL FLOW (conditions or loops) in constructor● Constructor build complex Collections instead of using
FACTORY or BUILDER● There is an INITIALIZE block● Not asking for Objects, looking for Objects
(DEPENDENCIES in constructor)
![Page 17: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/17.jpg)
SYMPTOMS - Digging into dependencies
● Object passed are used to access other objects● LAW OF DEMETER VIOLATION: Method call chain
with more than one ->● SUSPICIOUS NAMES: Manager, Context, Registry,
Container● Creating mocks that return MOCKS● Deceitful API (Real Dependencies are unclear)● Too many “Middle Men” objects● Needle in a haystack (due to breaking demeter law)
![Page 18: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/18.jpg)
SYMPTOMS - Singletons & Global state (the dark side)
● Using SINGLETONS● Accessing GLOBAL STATE STATICALLY● Using STATIC FIELDS or STATIC METHODS● Using a STATIC INITIALIZATION block● Using a REGISTRIES● NOT (or MIS-) using DEPENDENCY INJECTION● Hard Coded Dependencies● You have to read EVERY LINE OF CODE to
understand the potential side effects
![Page 19: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/19.jpg)
CURE
USE DEPENDENCY INJECTION
Replace your static methodWrap static method from third party libraries
If you can’t wrap them, write adapters
![Page 20: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/20.jpg)
SYMPTOMS - Object does too much
● When you have to use the word “AND” to describe what the Object does
● Object is hard to read for team members● Object have fields that are only used in some methods● Object has static methods that only operate on
parameters● MANY collaborators that you need to reach into for
more collaborators● HIDDEN INTERACTIONS behind public methods
![Page 21: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/21.jpg)
CURESOLID
Single ResponsibilityOpen/Close Principle
Liskov Substitution PrincipleInterface Segregation
Dependency Inversion
![Page 22: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/22.jpg)
● Run Without○ Network connection○ Production Data○ External API
● Run Fast○ ~milliseconds
Tests should...
● Must○ be Easy to maintain○ run before every
commit
![Page 23: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/23.jpg)
Rules for TDD
1. Devise possible tests2. Implement 1 FAILING
test3. Implement just enough
code to PASS the test4. Refactor code and clean
up design5. Repeat until ALL tests
are passed
THINK DIFFERENTLY
IMPLEMENTDESIGN
TEST
TEST
![Page 24: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/24.jpg)
How to write testable codePHPUnitDatabase TestingLegacy code testingPHPspec
![Page 25: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/25.jpg)
PHPUnit - Installation
● Pear● Phar● Ubuntu package● Composer
Optional Packages● Selenium● DbUnit● SkeletonGenerator
![Page 26: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/26.jpg)
PHPUnit - Bootstrap
● Common Initialization of testing Environment
$baseDir = realpath(__DIR__.'/..');
require_once $baseDir. '/tc_platform/Include/minimalBootstrap.php';
require_once $baseDir . '/TrustChargeLibrairies/vendor/autoload.php';
require_once $baseDir . '/PHPLibs/vendor/autoload.php';
![Page 27: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/27.jpg)
PHPUnit - Writing Test● Use the skeleton generator (should be in Eclipse)
phpunit-skelgen --bootstrap bootstrap.php --test -- Class_Something Lib/Class/Something.php Class_SomethingTest Tests/Lib/Class/SomethingTest.php
● Write it yourselfclass Class_SomethingTest extends PHPUnit_Framework_TestCase
![Page 28: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/28.jpg)
PHPUnit - Setup● setUpBeforeClass() - Executed before class is instantiated
○ Setup DB○ Setup Files
● setUp() - Executed before every test○ Reset DB○ Load Extra fixtures
● tearDown() - Executed after Test○ Clean up DB○ Remove Files
![Page 29: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/29.jpg)
Depends@depends - For tests that depend on output from other tests
![Page 30: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/30.jpg)
DataProvider@dataProvider - To test the same function with multiple values
![Page 31: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/31.jpg)
Stubs and MocksStubs - Test double that allows you to control the flow of data
Mock - Test double that allows you to control the flow of data and that assert that the object was called in a specific way
![Page 32: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/32.jpg)
Test DoublesDoubles - When you cannot replace a static dependency you can preload a test doubles instead
![Page 33: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/33.jpg)
Test DoublesDoubles - When you cannot replace a static dependency you can preload a test doubles instead
Preload Test Doubles
Run in own process
![Page 34: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/34.jpg)
How to write testable codePHPUnitDatabase TestingLegacy code testingPHPspec
![Page 35: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/35.jpg)
Database testing
● Must be fast● Need to control the data in the database● Must be ran in TESTING environment● Clean up after yourself
![Page 36: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/36.jpg)
1. Setup - DBConnection
Make sure you’re using TEST DB
Use MYISAM to bypass foreign key issues
Create the tables
![Page 37: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/37.jpg)
2. Setup - FixturesLoad Data
Export Data
![Page 38: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/38.jpg)
3. Tests
![Page 39: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/39.jpg)
![Page 40: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/40.jpg)
Hard coded dependencies
Hard coded DB name will cause you to truncate production DB instead of TEST DB
![Page 41: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/41.jpg)
CURECreate new test double interface
![Page 42: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/42.jpg)
How to write testable codePHPUnitDatabase TestingLegacy code testingPHPspec
![Page 43: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/43.jpg)
![Page 44: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/44.jpg)
"Behavior is the most important thing about software. It is what users depends on. Users like it when we add behavior, but if we change or remove behavior they depend on, they stop trusting us."
![Page 45: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/45.jpg)
Legacy Code Change Algorithm
1. Identify the change points2. Find test points3. Break Dependencies4. Write Tests5. Makes changes and refactor
![Page 46: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/46.jpg)
Identify test point
Find the code you need to change
Find test points
![Page 47: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/47.jpg)
Bridge Class● Class that bridges the gap between legacy code and
new architecture● Allows you to test in isolation● Helps refactor out dependencies
![Page 48: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/48.jpg)
Extract Method
Extract 535 Lines of code
![Page 49: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/49.jpg)
Bridge
![Page 50: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/50.jpg)
How to write testable codePHPUnitDatabase TestingLegacy code testingPHPspec
![Page 51: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/51.jpg)
PHPSpec● http://www.phpspec.net
While PHPUnit focuses on testing the functions and methods of the classes used to develop features, specBDD focuses on testing the behaviors of these classes.
“ describing the code before you actually write it is a fear management technique. You don’t have to write all the code, just the spec of the next thing you want to work on. ” -- Kent Beck
![Page 52: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/52.jpg)
Demo
![Page 53: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/53.jpg)
It’s not worth writing test unless you have CONTINUOUS INTEGRATION
I ZOMBIES
![Page 54: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/54.jpg)
Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. Take some action to prevent further damage and to show that you're on top of the situation.
We've seen clean, functional systems deteriorate pretty quickly once builds start breaking. There are other factors that can contribute to software rot, but neglect accelerates the rot faster than any other factor.
The broken window Theory
![Page 55: Test driven development - Zombie proof your code](https://reader035.vdocuments.site/reader035/viewer/2022081400/554f6511b4c905c8088b4cd7/html5/thumbnails/55.jpg)