SlideShare a Scribd company logo
Paying off technical debt with php 
spec 
Presented by 
Follow us on Twitter - @vivaitltd
Many thanks to Inviqua/SensioLabs 
Uk for the swag
How do we get to "good code" when 
the goal post is always evolving?
We manage our technical debt
But what is technical debt?
"As an evolving program is continually changed, 
its complexity, reflecting deteriorating 
structure, increases unless work is done to 
maintain or reduce it." 
— Meir Manny Lehman, 1980
Technical debt is essential for rapid 
and agile development
Otherwise we end up with something 
like this...
But debt gets worse the long you 
leave it 
Pay it off early, pay it off often
How do we pay it off?
What is refactoring? 
"Refactoring is the process of changing a software system in such a 
way that it does not alter the external behavior of the code yet 
improves its internal structure." 
— Martin Fowler
How do we ensure our code's 
behaviour remains consistent?
The purpose of our specs are to 
describe the behaviour of a class 
through examples.
PHPSpec is not about testing code 
you've already written
Lets write a spec for a user object
First we create a spec for our class 
Command: 
$ bin/phpspec desc Auth/User 
Response: 
> Specification for Auth 
created in spec/User.
# spec/Auth/UserSpec.php 
<?php 
namespace specAuth; 
use PhpSpecObjectBehavior; 
use ProphecyArgument; 
class UserSpec extends ObjectBehavior { 
function it_is_initializable() { 
$this->shouldHaveType('User'); 
} 
}
Not really specifying behaviour 
Lets replace it with a better one
# spec/Auth/UserSpec.php 
class UserSpec extends ObjectBehavior 
{ 
function it_generates_an_id() 
{ 
} 
}
# spec/Auth/UserSpec.php 
class UserSpec extends ObjectBehavior 
{ 
function it_generates_an_id() 
{ 
$this->getId() 
->shouldBeInteger(); 
} 
}
What's happening?
should* methods are called matchers 
They specify expected behaviour
There are lots of matchers 
shouldBe() .......... === 
shouldBeLike() ...... == 
shouldHaveType() .... instanceOf 
shouldHaveCount() ... count() 
shouldThrow() ....... try {} catch {} 
shouldBe*() ......... is*() === true 
shouldHave() ........ has*() === true 
shouldNot*() ........ !(*)
# spec/Auth/UserSpec.php 
function it_stores_a_username() 
{ 
$this->setUsername('LewisWright') 
->shouldBeAnInstance('AuthUser'); 
$this->getUsername() 
->shouldBe('LewisWright'); 
}
# spec/Auth/UserSpec.php 
function it_does_not_allow_spaces_in_usernames() 
{ 
$this 
->shouldThrow('InvalidArgumentException') 
->duringSetUsername('Lewis Wright'); 
}
# spec/Auth/UserSpec.php 
function it_lets_us_disable_a_user() 
{ 
$this->setActive(0) 
->shouldBeAnInstance('AuthUser'); 
$this->shouldNotBeActive(); 
}
Our tests start to build up a picture 
Command: 
$ bin/phpspec run
Our tests start to build up a picture 
Response: 
> specAuthUser 
✔ it generates an id 
✔ it stores a username 
✔ it does not allow spaces in usernames 
✔ it lets us disable a user 
5 examples (5 passed) 
247ms
Our spec should provide just enough examples 
to be confident we have clearly defined the 
intended behaviour. 
Only write specifications for edge cases if they 
are behaviour we want to specify.
Lets throw in collaborations 
A collaboration is the term for when our object 
interacts with another object
E.g. a User object having Roles 
objects
If our object is interacting with an 
external object (e.g. Roles), we need a 
way of specifying those interactions. 
So we create a fake object, called a double.
# spec/Auth/UserSpec.php 
function it_stores_many_roles(Role $role1, Role $role2) 
{ 
$this->addRole($role1); 
$this->addRole($role2); 
$this->getRoles() 
->shouldHaveCount(2); 
}
$role1 and $role2 may look fairly 
normal, but they're actually doubles. 
Meaning we can fake their behaviour.
# spec/Auth/UserSpec.php 
function it_provides_role_based_access(Role $role) 
{ 
$role->getPermittedAreas() 
->willReturn(['admin']); 
$this->addRole($role); 
$this->canAccess('admin') 
->shouldReturn(true); 
}
We've not actually specified that 
User should call getPermittedAreas 
Meaning we've not explicitly specified that 
collaboration.
# spec/Auth/UserSpec.php 
function it_provides_role_based_access(Role $role) 
{ 
$role->getPermittedAreas() 
->willReturn(['admin']) 
->shouldBeCalled(); 
$this->addRole($role); 
$this->canAccess('admin') 
->shouldReturn(true); 
}
PHPSpec will run the let and let_go 
before and after running each 
scenario 
Meaning we can share common 
stubbed behaviour between 
scenarios
# spec/Auth/UserSpec.php 
function let(Role $role) 
{ 
$role->checkPermittedAreas(Argument::any()) 
->will(function($args) { 
return $args; 
}); 
} 
function let_go() { 
// Do any deconstruction here 
}
PHPSpec is intended as a TDD tool 
to help you design your code through 
specifying it's behaviour. 
But that doesn't mean we can't use it to re-design 
existing code.
We've just invented TDDD! 
Technical Debt Driven Development
By specifying code behaviour, you 
create an environment where 
technical debt becomes managed. 
You, and more importantly other developers, 
can redesign and refactor with confidence.
Thanks for listening!
Symfony2 bootcamp workshop 
We're running a workshop on getting you 
started with Symfony2 on 7th June. 
Tickets are free but limited, so book your place 
ASAP. 
Link on our twitter - @vivaitld

More Related Content

What's hot

Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Vysakh Sreenivasan
 
Automated testing with RSpec
Automated testing with RSpecAutomated testing with RSpec
Automated testing with RSpecNascenia IT
 
Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API DocumentationSmartLogic
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2Javier Eguiluz
 
The basics of Ember Objects
The basics of Ember ObjectsThe basics of Ember Objects
The basics of Ember ObjectsJason Schmidt
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Storiesrahoulb
 
Angular Directives from Scratch
Angular Directives from ScratchAngular Directives from Scratch
Angular Directives from ScratchChristian Lilley
 
Frank Rodenbaugh Portfolio
Frank Rodenbaugh PortfolioFrank Rodenbaugh Portfolio
Frank Rodenbaugh PortfolioFrankRodenbaugh
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4Javier Eguiluz
 
Programming Primer Encapsulation CS
Programming Primer Encapsulation CSProgramming Primer Encapsulation CS
Programming Primer Encapsulation CSsunmitraeducation
 
Angular custom directives
Angular custom directivesAngular custom directives
Angular custom directivesAlexe Bogdan
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Railsbenlcollins
 
Dutch php a short tale about state machine
Dutch php   a short tale about state machineDutch php   a short tale about state machine
Dutch php a short tale about state machineŁukasz Chruściel
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в MagentoMagecom Ukraine
 
Intro to Angular.JS Directives
Intro to Angular.JS DirectivesIntro to Angular.JS Directives
Intro to Angular.JS DirectivesChristian Lilley
 
Laravel 5.2 Gates, AuthServiceProvider and Policies
Laravel 5.2 Gates, AuthServiceProvider and PoliciesLaravel 5.2 Gates, AuthServiceProvider and Policies
Laravel 5.2 Gates, AuthServiceProvider and PoliciesAlison Gianotto
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form componentSamuel ROZE
 

What's hot (20)

Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)
 
Barely Enough Design
Barely Enough DesignBarely Enough Design
Barely Enough Design
 
Automated testing with RSpec
Automated testing with RSpecAutomated testing with RSpec
Automated testing with RSpec
 
Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API Documentation
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2
 
The basics of Ember Objects
The basics of Ember ObjectsThe basics of Ember Objects
The basics of Ember Objects
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Stories
 
Angular Directives from Scratch
Angular Directives from ScratchAngular Directives from Scratch
Angular Directives from Scratch
 
RSpec 2 Best practices
RSpec 2 Best practicesRSpec 2 Best practices
RSpec 2 Best practices
 
Frank Rodenbaugh Portfolio
Frank Rodenbaugh PortfolioFrank Rodenbaugh Portfolio
Frank Rodenbaugh Portfolio
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4
 
Programming Primer Encapsulation CS
Programming Primer Encapsulation CSProgramming Primer Encapsulation CS
Programming Primer Encapsulation CS
 
Angular custom directives
Angular custom directivesAngular custom directives
Angular custom directives
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Rails
 
Dutch php a short tale about state machine
Dutch php   a short tale about state machineDutch php   a short tale about state machine
Dutch php a short tale about state machine
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
 
Intro to Angular.JS Directives
Intro to Angular.JS DirectivesIntro to Angular.JS Directives
Intro to Angular.JS Directives
 
Laravel 5.2 Gates, AuthServiceProvider and Policies
Laravel 5.2 Gates, AuthServiceProvider and PoliciesLaravel 5.2 Gates, AuthServiceProvider and Policies
Laravel 5.2 Gates, AuthServiceProvider and Policies
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 

Similar to Paying off technical debt with PHPSpec

PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersKacper Gunia
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Konstantin Kudryashov
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionKent Huang
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Michelangelo van Dam
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4Naga Muruga
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastMichelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 

Similar to Paying off technical debt with PHPSpec (20)

PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Rhino Mocks
Rhino MocksRhino Mocks
Rhino Mocks
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 

Recently uploaded

Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILNatan Silnitsky
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfMeon Technology
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1KnowledgeSeed
 
Studiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting softwareStudiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting softwareinfo611746
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownloadvrstrong314
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...Alluxio, Inc.
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfmbmh111980
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockSkilrock Technologies
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...rajkumar669520
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfOrtus Solutions, Corp
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowPeter Caitens
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandIES VE
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEJelle | Nordend
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesKrzysztofKkol1
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion Clinic
 

Recently uploaded (20)

Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdf
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
Studiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting softwareStudiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting software
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 

Paying off technical debt with PHPSpec

  • 1. Paying off technical debt with php spec Presented by Follow us on Twitter - @vivaitltd
  • 2. Many thanks to Inviqua/SensioLabs Uk for the swag
  • 3.
  • 4. How do we get to "good code" when the goal post is always evolving?
  • 5. We manage our technical debt
  • 6. But what is technical debt?
  • 7. "As an evolving program is continually changed, its complexity, reflecting deteriorating structure, increases unless work is done to maintain or reduce it." — Meir Manny Lehman, 1980
  • 8. Technical debt is essential for rapid and agile development
  • 9. Otherwise we end up with something like this...
  • 10.
  • 11. But debt gets worse the long you leave it Pay it off early, pay it off often
  • 12. How do we pay it off?
  • 13.
  • 14. What is refactoring? "Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure." — Martin Fowler
  • 15. How do we ensure our code's behaviour remains consistent?
  • 16.
  • 17. The purpose of our specs are to describe the behaviour of a class through examples.
  • 18. PHPSpec is not about testing code you've already written
  • 19. Lets write a spec for a user object
  • 20. First we create a spec for our class Command: $ bin/phpspec desc Auth/User Response: > Specification for Auth created in spec/User.
  • 21. # spec/Auth/UserSpec.php <?php namespace specAuth; use PhpSpecObjectBehavior; use ProphecyArgument; class UserSpec extends ObjectBehavior { function it_is_initializable() { $this->shouldHaveType('User'); } }
  • 22. Not really specifying behaviour Lets replace it with a better one
  • 23. # spec/Auth/UserSpec.php class UserSpec extends ObjectBehavior { function it_generates_an_id() { } }
  • 24. # spec/Auth/UserSpec.php class UserSpec extends ObjectBehavior { function it_generates_an_id() { $this->getId() ->shouldBeInteger(); } }
  • 26. should* methods are called matchers They specify expected behaviour
  • 27. There are lots of matchers shouldBe() .......... === shouldBeLike() ...... == shouldHaveType() .... instanceOf shouldHaveCount() ... count() shouldThrow() ....... try {} catch {} shouldBe*() ......... is*() === true shouldHave() ........ has*() === true shouldNot*() ........ !(*)
  • 28. # spec/Auth/UserSpec.php function it_stores_a_username() { $this->setUsername('LewisWright') ->shouldBeAnInstance('AuthUser'); $this->getUsername() ->shouldBe('LewisWright'); }
  • 29. # spec/Auth/UserSpec.php function it_does_not_allow_spaces_in_usernames() { $this ->shouldThrow('InvalidArgumentException') ->duringSetUsername('Lewis Wright'); }
  • 30. # spec/Auth/UserSpec.php function it_lets_us_disable_a_user() { $this->setActive(0) ->shouldBeAnInstance('AuthUser'); $this->shouldNotBeActive(); }
  • 31. Our tests start to build up a picture Command: $ bin/phpspec run
  • 32. Our tests start to build up a picture Response: > specAuthUser ✔ it generates an id ✔ it stores a username ✔ it does not allow spaces in usernames ✔ it lets us disable a user 5 examples (5 passed) 247ms
  • 33. Our spec should provide just enough examples to be confident we have clearly defined the intended behaviour. Only write specifications for edge cases if they are behaviour we want to specify.
  • 34. Lets throw in collaborations A collaboration is the term for when our object interacts with another object
  • 35. E.g. a User object having Roles objects
  • 36. If our object is interacting with an external object (e.g. Roles), we need a way of specifying those interactions. So we create a fake object, called a double.
  • 37. # spec/Auth/UserSpec.php function it_stores_many_roles(Role $role1, Role $role2) { $this->addRole($role1); $this->addRole($role2); $this->getRoles() ->shouldHaveCount(2); }
  • 38. $role1 and $role2 may look fairly normal, but they're actually doubles. Meaning we can fake their behaviour.
  • 39. # spec/Auth/UserSpec.php function it_provides_role_based_access(Role $role) { $role->getPermittedAreas() ->willReturn(['admin']); $this->addRole($role); $this->canAccess('admin') ->shouldReturn(true); }
  • 40. We've not actually specified that User should call getPermittedAreas Meaning we've not explicitly specified that collaboration.
  • 41. # spec/Auth/UserSpec.php function it_provides_role_based_access(Role $role) { $role->getPermittedAreas() ->willReturn(['admin']) ->shouldBeCalled(); $this->addRole($role); $this->canAccess('admin') ->shouldReturn(true); }
  • 42. PHPSpec will run the let and let_go before and after running each scenario Meaning we can share common stubbed behaviour between scenarios
  • 43. # spec/Auth/UserSpec.php function let(Role $role) { $role->checkPermittedAreas(Argument::any()) ->will(function($args) { return $args; }); } function let_go() { // Do any deconstruction here }
  • 44. PHPSpec is intended as a TDD tool to help you design your code through specifying it's behaviour. But that doesn't mean we can't use it to re-design existing code.
  • 45. We've just invented TDDD! Technical Debt Driven Development
  • 46. By specifying code behaviour, you create an environment where technical debt becomes managed. You, and more importantly other developers, can redesign and refactor with confidence.
  • 48. Symfony2 bootcamp workshop We're running a workshop on getting you started with Symfony2 on 7th June. Tickets are free but limited, so book your place ASAP. Link on our twitter - @vivaitld