SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

Frank Rodenbaugh Portfolio
Frank Rodenbaugh PortfolioFrank Rodenbaugh Portfolio
Frank Rodenbaugh Portfolio
FrankRodenbaugh
 
Angular custom directives
Angular custom directivesAngular custom directives
Angular custom directives
Alexe Bogdan
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
Magecom Ukraine
 

Was ist angesagt? (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
 

Ähnlich wie Paying off technical debt with PHPSpec

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
Michelangelo van Dam
 

Ähnlich wie 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
 

Kürzlich hochgeladen

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Kürzlich hochgeladen (20)

Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

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