SlideShare a Scribd company logo
1 of 92
Download to read offline
Driving Development with 
PhpSpec 
with Ciaran McNulty 
PHPLondon November 2014
My experiences 
4 Unit testing since 2004 
4 Test Driven Development since 2005(ish) 
4 Behaviour Driven Development since 2012
TDD vs BDD 
(or are they the same?)
BDD is a second-generation, 
outside-in, 
pull-based, multiple-stakeholder… 
1 
Dan North
…multiple-scale, high-automation, 
agile 
methodology. 
1 
Dan North
BDD is the art of using 
examples in conversation to 
illustrate behaviour 
1 
Liz Keogh
Test Driven 
Development 
4 Before you write your code, 
write a test that validates how 
it should behave 
4 After you have written the 
code, see if it passes the test
Behaviour Driven 
Development 
4 Before you write your code, 
describe how it should behave 
using examples 
4 Then, Implement the behaviour 
you you described
SpecBDD with PhpSpec 
Describing individual classes
History 
1.0 - Inspired by RSpec 
4 Pádraic Brady and Travis 
Swicegood
History 
2.0beta - Inspired by 1.0 
4 Marcello Duarte and Konstantin Kudryashov 
(Everzet) 
4 Ground-up rewrite 
4 No BC in specs
History 
2.0 stable - The boring bits 
4 Me 
4 Christophe Coevoet 
4 Jakub Zalas 
4 Richard Miller 
4 Gildas Quéméner
Installation via Composer 
{ 
"require-dev": { 
"phpspec/phpspec": "~2.1-RC1" 
}, 
"config": { 
"bin-dir": "bin" 
}, 
"autoload": {"psr-0": {"": "src"}} 
}
A requirement: 
We need something that 
says hello to people
Describing object behaviour 
4 We describe an object using a Specification 
4 A specification is made up of Examples illustrating 
different scenarios 
Usage: 
phpspec describe [Class]
/spec/PhpLondon/HelloWorld/GreeterSpec.php 
namespace specPhpLondonHelloWorld; 
use PhpSpecObjectBehavior; 
use ProphecyArgument; 
class GreeterSpec extends ObjectBehavior 
{ 
function it_is_initializable() 
{ 
$this->shouldHaveType('PhpLondonHelloWorldGreeter'); 
} 
}
Verifying object behaviour 
4 Compare the real objects' behaviours with the 
examples 
Usage: 
phpspec run
/src/PhpLondon/HelloWorld/Greeter.php 
namespace PhpLondonHelloWorld; 
class Greeter 
{ 
}
An example for Greeter: 
When this greets, it should 
return "Hello"
/spec/PhpLondon/HelloWorld/GreeterSpec.php 
class GreeterSpec extends ObjectBehavior 
{ 
function it_greets_by_saying_hello() 
{ 
$this->greet()->shouldReturn('Hello'); 
} 
}
/src/PhpLondon/HelloWorld/Greeter.php 
class Greeter 
{ 
public function greet() 
{ 
// TODO: write logic here 
} 
}
So now I write some code?
Fake it till you make it 
4 Do the simplest thing that works 
4 Only add complexity later when more examples drive 
it 
phpspec run --fake
/src/PhpLondon/HelloWorld/Greeter.php 
class Greeter 
{ 
public function greet() 
{ 
return 'Hello'; 
} 
}
Describing values 
Matchers
Describing values - Equality 
$this->greet()->shouldReturn('Hello'); 
$this->sum(3,3)->shouldEqual(6); 
$user = $this->findById(1234); 
$user->shouldBe($expectedUser); 
$this->numberList() 
->shouldBeLike(new ArrayObject([1,2,3]));
Describing values - Type 
$this->address()->shouldHaveType('EmailAddress'); 
$this->getTime()->shouldReturnAnInstanceOf('DateTime'); 
$user = $this->findById(1234); 
$user->shouldBeAnInstanceOf('User'); 
$this->shouldImplement('Countable');
Describing values - Strings 
$this->getStory()->shouldStartWith('A long time ago'); 
$this->getStory()->shouldEndWith('happily ever after'); 
$this->getSlug()->shouldMatch('/^[0-9a-z]+$/');
Describing values - Arrays 
$this->getNames()->shouldContain('Tom'); 
$this->getNames()->shouldHaveKey(0); 
$this->getNames()->shouldHaveCount(1);
Describing values - object state 
// calls isAdmin() 
$this->getUser()->shouldBeAdmin(); 
// calls hasLoggedInUser() 
$this->shouldHaveLoggedInUser();
Describing custom values 
function it_gets_json_with_user_details() 
{ 
$this->getResponseData()->shouldHaveJsonKey('username'); 
} 
public function getMatchers() 
{ 
return [ 
'haveJsonKey' => function ($subject, $key) { 
return array_key_exists($key, json_decode($subject)); 
} 
]; 
}
Another example for Greeter: 
When this greets Bob, it 
should return "Hello, Bob"
Wait, what is Bob? 
Bob is a Person 
What is a Person?
An example for a Person: 
When you ask a person 
named "Alice" for their 
name, they return "Alice"
/spec/PhpLondon/HelloWorld/PersonSpec.php 
class PersonSpec extends ObjectBehavior 
{ 
function it_returns_the_name_it_is_created_with() 
{ 
$this->beConstructedWith('Alice'); 
$this->getName()->shouldReturn('Alice'); 
} 
}
/src/PhpLondon/HelloWorld/Person.php 
class Person 
{ 
public function __construct($argument1) 
{ 
// TODO: write logic here 
} 
public function getName() 
{ 
// TODO: write logic here 
} 
}
So now I write some code!
/src/PhpLondon/HelloWorld/Person.php 
class Person 
{ 
private $name; 
public function __construct($name) 
{ 
$this->name = $name; 
} 
public function getName() 
{ 
return $this->name; 
} 
}
Another example for a Person: 
When a person named 
"Alice" changes their name 
to "Bob", when you ask 
their name they return 
"Bob"
/spec/PhpLondon/HelloWorld/PersonSpec.php 
class PersonSpec extends ObjectBehavior 
{ 
function it_returns_the_name_it_is_created_with() 
{ 
$this->beConstructedWith('Alice'); 
$this->getName()->shouldReturn('Alice'); 
} 
}
/spec/PhpLondon/HelloWorld/PersonSpec.php 
class PersonSpec extends ObjectBehavior 
{ 
function let() 
{ 
$this->beConstructedWith('Alice'); 
} 
function it_returns_the_name_it_is_created_with() 
{ 
$this->getName()->shouldReturn('Alice'); 
} 
}
/spec/PhpLondon/HelloWorld/PersonSpec.php 
class PersonSpec extends ObjectBehavior 
{ 
function let() 
{ 
$this->beConstructedWith('Alice'); 
} 
// … 
function it_returns_its_new_name_when_the_name_has_been_changed() 
{ 
$this->changeNameTo('Bob'); 
$this->getName()->shouldReturn('Bob'); 
} 
}
/src/PhpLondon/HelloWorld/Person.php 
class Person 
{ 
private $name; 
// … 
public function changeNameTo($argument1) 
{ 
// TODO: write logic here 
} 
}
/src/PhpLondon/HelloWorld/Person.php 
class Person 
{ 
private $name; 
// … 
public function changeNameTo($name) 
{ 
$this->name = $name; 
} 
}
Another example for Greeter: 
When this greets Bob, it 
should return "Hello, Bob"
Describing collaboration - Stubs 
Stubs are used to describe how we interact with objects 
we query 
4 Maybe it is hard to get the real collaborator to 
return the value we want 
4 Maybe using the real collaborator is expensive
/spec/PhpLondon/HelloWorld/GreeterSpec.php 
class GreeterSpec extends ObjectBehavior 
{ 
//… 
function it_greets_people_by_name(Person $bob) 
{ 
$bob->getName()->willReturn('Bob'); 
$this->greet($bob)->shouldReturn('Hello, Bob'); 
} 
}
/src/PhpLondon/HelloWorld/Greeter.php 
class Greeter 
{ 
public function greet() 
{ 
return 'Hello'; 
} 
}
/src/PhpLondon/HelloWorld/Greeter.php 
class Greeter 
{ 
public function greet() 
{ 
$greeting = 'Hello'; 
return $greeting; 
} 
}
/src/PhpLondon/HelloWorld/Greeter.php 
class Greeter 
{ 
public function greet(Person $person = null) 
{ 
$greeting = 'Hello'; 
if ($person) { 
$greeting .= ', ' . $person->getName(); 
} 
return $greeting; 
} 
}
Final example for Greeter: 
When it greets Bob, the 
message "Hello Bob" should 
be logged
What's a log? 
Let's not worry yet
/src/PhpLondon/HelloWorld/Logger.php 
interface Logger 
{ 
public function log($message); 
}
Describing collaboration - Mocks and 
Spies 
Mocks or Spies are used to describe how we interact 
with objects we command 
4 Maybe the real command is has side effects 
4 Maybe using the real collaborator is expensive
/spec/PhpLondon/HelloWorld/GreeterSpec.php 
class GreeterSpec extends ObjectBehavior 
{ 
//… 
function it_greets_people_by_name(Person $bob) 
{ 
$bob->getName()->willReturn('Bob'); 
$this->greet($bob)->shouldReturn('Hello, Bob'); 
} 
}
/spec/PhpLondon/HelloWorld/GreeterSpec.php 
class GreeterSpec extends ObjectBehavior 
{ 
function let(Person $bob) 
{ 
$bob->getName()->willReturn('Bob'); 
} 
//… 
function it_greets_people_by_name(Person $bob) 
{ 
$this->greet($bob)->shouldReturn('Hello, Bob'); 
} 
}
/spec/PhpLondon/HelloWorld/GreeterSpec.php 
class GreeterSpec extends ObjectBehavior 
{ 
function let(Person $bob, Logger $logger) 
{ 
$this->beConstructedWith($logger); 
$bob->getName()->willReturn('Bob'); 
} 
//… 
function it_logs_the_greetings(Person $bob, Logger $logger) 
{ 
$this->greet($bob); 
$logger->log('Hello, Bob')->shouldHaveBeenCalled(); 
} 
}
/src/PhpLondon/HelloWorld/Greeter.php 
class Greeter 
{ 
public function __construct($argument1) 
{ 
// TODO: write logic here 
} 
public function greet(Person $person = null) 
{ 
$greeting = 'Hello'; 
if ($person) { $greeting .= ', ' . $person->getName(); } 
return $greeting; 
} 
}
/src/PhpLondon/HelloWorld/Greeter.php 
class Greeter 
{ 
private $logger; 
public function __construct(Logger $logger) 
{ 
$this->logger = $logger; 
} 
public function greet(Person $person = null) 
{ 
$greeting = 'Hello'; 
if ($person) { $greeting .= ', ' . $person->getName(); } 
$this->logger->log($greeting); 
return $greeting; 
} 
}
What have we built?
The domain model
Specs as documentation
PhpSpec 
4 Focuses on being descriptive 
4 Makes common dev activities easier or automated 
4 Drives your design
2.1 release - soon! 
4 Rerun after failure 
4 --fake option 
4 Named constructors: User::named('Bob') 
4 PSR-4 support (+ other autoloaders) 
4 + lots of small improvements
Me 
4 Senior Trainer at Inviqa / Sensio Labs UK / Session 
Digital 
4 Contributor to PhpSpec 
4 @ciaranmcnulty 
4 https://github.com/ciaranmcnulty/phplondon-phpspec- 
talk
Questions?

More Related Content

What's hot

C# conventions & good practices
C# conventions & good practicesC# conventions & good practices
C# conventions & good practicesTan Tran
 
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)James Titcumb
 
PHP 5.4 New Features
PHP 5.4 New FeaturesPHP 5.4 New Features
PHP 5.4 New FeaturesHaim Michael
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Wen-Tien Chang
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)James Titcumb
 
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)James Titcumb
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHPDavid Stockton
 
Coding Best Practices
Coding Best PracticesCoding Best Practices
Coding Best Practicesmh_azad
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScriptT11 Sessions
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the BasicsMichael Koby
 
Fundamental JavaScript [In Control 2009]
Fundamental JavaScript [In Control 2009]Fundamental JavaScript [In Control 2009]
Fundamental JavaScript [In Control 2009]Aaron Gustafson
 
Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)James Titcumb
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)James Titcumb
 
Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)James Titcumb
 
Beginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScriptBeginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScriptStoyan Stefanov
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplicationolegmmiller
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHPDavid Stockton
 

What's hot (20)

C# conventions & good practices
C# conventions & good practicesC# conventions & good practices
C# conventions & good practices
 
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
 
PHP 5.4 New Features
PHP 5.4 New FeaturesPHP 5.4 New Features
PHP 5.4 New Features
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
Coding Best Practices
Coding Best PracticesCoding Best Practices
Coding Best Practices
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScript
 
Clean Code
Clean CodeClean Code
Clean Code
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
 
Fundamental JavaScript [In Control 2009]
Fundamental JavaScript [In Control 2009]Fundamental JavaScript [In Control 2009]
Fundamental JavaScript [In Control 2009]
 
Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Java script
Java scriptJava script
Java script
 
Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)
 
Beginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScriptBeginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScript
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
Let's Play Dart
Let's Play DartLet's Play Dart
Let's Play Dart
 

Viewers also liked

PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodeSWIFTotter Solutions
 
Software Testing & PHPSpec
Software Testing & PHPSpecSoftware Testing & PHPSpec
Software Testing & PHPSpecDarren Craig
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerPaul Jones
 
Emergent design with phpspec
Emergent design with phpspecEmergent design with phpspec
Emergent design with phpspecMarcello Duarte
 
JWT - To authentication and beyond!
JWT - To authentication and beyond!JWT - To authentication and beyond!
JWT - To authentication and beyond!Luís Cobucci
 
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
 
Minimal Containers for PHP
Minimal Containers for PHPMinimal Containers for PHP
Minimal Containers for PHPWeaveworks
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesMarcello Duarte
 

Viewers also liked (10)

PHP's FIG and PSRs
PHP's FIG and PSRsPHP's FIG and PSRs
PHP's FIG and PSRs
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
Software Testing & PHPSpec
Software Testing & PHPSpecSoftware Testing & PHPSpec
Software Testing & PHPSpec
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
 
Emergent design with phpspec
Emergent design with phpspecEmergent design with phpspec
Emergent design with phpspec
 
JWT - To authentication and beyond!
JWT - To authentication and beyond!JWT - To authentication and beyond!
JWT - To authentication and beyond!
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
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
 
Minimal Containers for PHP
Minimal Containers for PHPMinimal Containers for PHP
Minimal Containers for PHP
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examples
 

Similar to Driving Design with PhpSpec

SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5Jason Austin
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)Oleg Zinchenko
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developersStoyan Stefanov
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibilitymachuga
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overviewjsmith92
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Introducing ruby on rails
Introducing ruby on railsIntroducing ruby on rails
Introducing ruby on railsPriceen
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHPBradley Holt
 
Phpspec tips&tricks
Phpspec tips&tricksPhpspec tips&tricks
Phpspec tips&tricksFilip Golonka
 

Similar to Driving Design with PhpSpec (20)

SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Oops in php
Oops in phpOops in php
Oops in php
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
OOP
OOPOOP
OOP
 
php AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdfphp AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdf
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibility
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
ElePHPant7 - Introduction to PHP7
ElePHPant7 - Introduction to PHP7ElePHPant7 - Introduction to PHP7
ElePHPant7 - Introduction to PHP7
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Fatc
FatcFatc
Fatc
 
Introducing ruby on rails
Introducing ruby on railsIntroducing ruby on rails
Introducing ruby on rails
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
Phpspec tips&tricks
Phpspec tips&tricksPhpspec tips&tricks
Phpspec tips&tricks
 
PHP pod mikroskopom
PHP pod mikroskopomPHP pod mikroskopom
PHP pod mikroskopom
 

More from CiaranMcNulty

Greener web development at PHP London
Greener web development at PHP LondonGreener web development at PHP London
Greener web development at PHP LondonCiaranMcNulty
 
Doodle Driven Development
Doodle Driven DevelopmentDoodle Driven Development
Doodle Driven DevelopmentCiaranMcNulty
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with SymfonyCiaranMcNulty
 
Behat Best Practices
Behat Best PracticesBehat Best Practices
Behat Best PracticesCiaranMcNulty
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with SymfonyCiaranMcNulty
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through ExamplesCiaranMcNulty
 
Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016CiaranMcNulty
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through ExamplesCiaranMcNulty
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobCiaranMcNulty
 
Fly In Style (without splashing out)
Fly In Style (without splashing out)Fly In Style (without splashing out)
Fly In Style (without splashing out)CiaranMcNulty
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015CiaranMcNulty
 
Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015CiaranMcNulty
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through ExamplesCiaranMcNulty
 
Why Your Test Suite Sucks
Why Your Test Suite SucksWhy Your Test Suite Sucks
Why Your Test Suite SucksCiaranMcNulty
 
Using HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationUsing HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationCiaranMcNulty
 

More from CiaranMcNulty (17)

Greener web development at PHP London
Greener web development at PHP LondonGreener web development at PHP London
Greener web development at PHP London
 
Doodle Driven Development
Doodle Driven DevelopmentDoodle Driven Development
Doodle Driven Development
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with Symfony
 
Behat Best Practices
Behat Best PracticesBehat Best Practices
Behat Best Practices
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with Symfony
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016
 
Conscious Coupling
Conscious CouplingConscious Coupling
Conscious Coupling
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the Job
 
Fly In Style (without splashing out)
Fly In Style (without splashing out)Fly In Style (without splashing out)
Fly In Style (without splashing out)
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015
 
Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Why Your Test Suite Sucks
Why Your Test Suite SucksWhy Your Test Suite Sucks
Why Your Test Suite Sucks
 
Using HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationUsing HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless Integration
 

Recently uploaded

Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Fact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMsFact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMsZilliz
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dashnarutouzumaki53779
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Fact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMsFact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMs
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dash
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 

Driving Design with PhpSpec