SlideShare a Scribd company logo
1 of 137
Download to read offline
PHPSpec
the only Design Tool you need
flickr.com/mobilestreetlife/4179063482/
Kacper Gunia @cakper
Software Engineer @SensioLabsUK
Symfony Certified Developer
PHPers Silesia @PHPersPL
!
‘Is my code well 

designed?’
’That’s not the way
I would have done it…’
It’s hard to

change!
We're afraid
to change it…
We cannot

reuse it!
So what
Design
is about?
‘The key in making great and
growable systems is much more to
design how its
modules communicate
rather than what their internal
properties and behaviors should be.’
Alan Kay
Design is about
Messaging
$orders	
  =	
  $orderRepository	
  
	
  	
  -­‐>getEntityManager()	
  
	
  	
  	
  -­‐>createOrderQuery($customer)	
  
	
  	
  	
  -­‐>execute();
$orders	
  =	
  $orderRepository	
  
	
  	
  -­‐>findBy($customer);	
  
!
We have
to refactor! :)
We need
two weeks
to refactor! :)
We need
two sprints
to refactor! :|
We need
two months
to refactor! :/
Refactoring
is the process of restructuring
existing code without
changing its external behavior
4 Rules of Simple Design
1. Passes its tests
2. Minimizes duplication
3. Maximizes clarity
4. Has fewer elements
…so we need
to write
Tests!
how
to write
Tests?
Tests
Driven
Development
Red
GreenRefactor
Red
GreenRefactor
But!
How to test
something that
doesn’t exist?
flickr.com/ucumari/580865728/
Test in TDD
means
specification
Specification
describes
behavior
Behavior
Driven
Development
BDD improves
Naming
Conventions
Tools
Story BDD
vs
Spec BDD
Story BDD
description of
business-targeted
application behavior
Spec BDD
specification for
low-level
implementation
http://phpspec.net/
Spec BDD
tool created by
@_md & @everzet
Bundled with
mocking library
Prophecy
composer	
  create-­‐project	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  cakper/phpspec-­‐standard	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  project-­‐name
But!
Isn’t it a tool just
like PHPUnit?
PHPUnit is a
Testing Tool
PHPSpec is the
Design Tool
class	
  CustomerRepositoryTest	
  extends	
  
PHPUnit_Framework_TestCase	
  
{	
  
	
  	
  	
  	
  function	
  testClassExists()	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  $customerRepository	
  =	
  new	
  CustomerRepository;	
  
!
	
  	
  	
  	
  	
  	
  	
  	
  $customer	
  =	
  $customerRepository-­‐>findById(5);	
  
	
  	
  	
  	
  	
  	
  	
  	
  $this-­‐>assertInstanceOf('Customer',	
  $customer);	
  
	
  	
  	
  	
  }	
  
}
class	
  CustomerRepositorySpec	
  extends	
  ObjectBehavior	
  
{	
  
	
  	
  	
  	
  function	
  it_is_initializable()	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  $this-­‐>shouldHaveType('CustomerRepository');	
  
	
  	
  	
  	
  }	
  
}
Naming
TestCase
!
Specification
Test
!
Example
Assertion
!
Expectation
OK, so how to
specify a method?
What method can do?
return a value
modify state
delegate
throw an exception
Command-Query
Separation
Command
change the state of a system
but do not return a value
Query
return a result and do not
change the state of the
system (free of side effects)
Never both!
class	
  CustomerRepositorySpec	
  extends	
  ObjectBehavior	
  
{	
  
	
  	
  	
  	
  function	
  it_loads_user_preferences()	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  $customer	
  =	
  $this-­‐>findById(5);	
  
!
	
  	
  	
  	
  	
  	
  	
  	
  $customer-­‐>shouldBeAnInstanceOf('Customer');	
  
	
  	
  	
  	
  }	
  
}
Matchers
Type
shouldBeAnInstanceOf(*)
shouldReturnAnInstanceOf(*)
shouldHaveType(*)
$customer-­‐>shouldBeAnInstanceOf('Customer');
Identity ===
shouldReturn(*)
shouldBe(*)
shouldEqual(*)
shouldBeEqualTo(*)
$this-­‐>findById(-­‐1)-­‐>shouldReturn(null);
Comparison ==
shouldBeLike(*)
$this-­‐>getAmount()-­‐>shouldBeLike(5);
Throw
throw(*)->during*()
$this-­‐>shouldThrow(‘InvalidArgumentException’)

	
  	
  	
  	
  	
  -­‐>duringFindByCustomer(null);
Object State
shouldHave*()
$car-­‐>hasEngine();	
  
!
$this-­‐>shouldHaveEngine();
Scalar
shouldBeString()
shouldBeArray()
Count
shouldHaveCount(*)
Or write your own
Inline Matcher
function	
  it_should_have_poland_as_avialable_country()	
  
{	
  
	
  	
  	
  	
  $this-­‐>getCountryCodes()-­‐>shouldHaveValue('PL');	
  
}	
  
!
public	
  function	
  getMatchers()	
  
{	
  
	
  	
  	
  	
  return	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  'haveValue'	
  =>	
  function	
  ($subject,	
  $value)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  in_array($value,	
  $subject);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  ];	
  
}
But!
Design is about
Messaging!
And (so far) there
is no messaging…
London School
Mockist TDD
only tested object is real
Test Doubles
Dummy
tested code requires
parameter but
doesn’t need to use it
function	
  let(EntityManager	
  $entityManager)	
  
{	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($entityManager);	
  
}	
  
!
function	
  it_returns_customer_by_id()	
  
{	
  
	
  	
  	
  	
  $customer	
  =	
  $this-­‐>findById(5);	
  
!
	
  	
  	
  	
  $customer-­‐>shouldBeAnInstanceOf('Customer');	
  
	
  	
  	
  	
  }	
  
}
function	
  let(EntityManager	
  $entityManager)	
  
{	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($entityManager);	
  
}	
  
!
function	
  it_returns_customer_by_id()	
  
{	
  
	
  	
  	
  	
  $customer	
  =	
  $this-­‐>findById(5);	
  
!
	
  	
  	
  	
  $customer-­‐>shouldBeAnInstanceOf('Customer');	
  
	
  	
  	
  	
  }	
  
}
Stub
provides "indirect input"
to the tested code
function	
  it_bolds_the_output(Stream	
  $stream)	
  
{	
  
	
  	
  	
  	
  $stream-­‐>getOutput()	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>willReturn('4	
  Developers');	
  
!
	
  	
  	
  	
  $this-­‐>bold($stream)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldReturn('<b>4	
  Developers</b>’);	
  
}
function	
  it_bolds_the_output(Stream	
  $stream)	
  
{	
  
	
  	
  	
  	
  $stream-­‐>getOutput()	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>willReturn('4	
  Developers');	
  
!
	
  	
  	
  	
  $this-­‐>bold($stream)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldReturn('<b>4	
  Developers</b>’);	
  
}
Mocks
verifies "indirect output”
of the tested code
function	
  let(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($logger);	
  
}	
  
!
function	
  it_returns_customer_by_id(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $logger-­‐>debug('DB	
  queried')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>findById(5);	
  
}
function	
  let(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($logger);	
  
}	
  
!
function	
  it_returns_customer_by_id(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $logger-­‐>debug('DB	
  queried')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>findById(5);	
  
}
Spy
verifies "indirect output”
by asserting the expectations
afterwards
function	
  let(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($logger);	
  
}	
  
!
function	
  it_returns_customer_by_id(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $this-­‐>findById(5);	
  
!
	
  	
  	
  	
  $logger-­‐>debug('DB	
  queried')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldHaveBeenCalled();	
  
}
function	
  let(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($logger);	
  
}	
  
!
function	
  it_returns_customer_by_id(Logger	
  $logger)	
  
{	
  
	
  	
  	
  	
  $this-­‐>findById(5);	
  
!
	
  	
  	
  	
  $logger-­‐>debug('DB	
  queried')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldHaveBeenCalled();	
  
}
(a bit more)
complex example
function	
  let(SecurityContext	
  $securityContext)	
  {	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($securityContext);	
  	
  
}	
  
!
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type('Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  	
  
}
function	
  let(SecurityContext	
  $securityContext)	
  {	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($securityContext);	
  	
  
}	
  
!
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type('Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  	
  
}
function	
  let(SecurityContext	
  $securityContext)	
  {	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($securityContext);	
  	
  
}	
  
!
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type('Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  	
  
}
function	
  let(SecurityContext	
  $securityContext)	
  {	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($securityContext);	
  	
  
}	
  
!
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type('Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  	
  
}
function	
  let(SecurityContext	
  $securityContext)	
  {	
  
	
  	
  	
  	
  $this-­‐>beConstructedWith($securityContext);	
  	
  
}	
  
!
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type('Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  	
  
}
But mocking
becomes painful…
And it smells…
Law of Demeter
unit should only
talk to its friends;
don't talk to strangers
It’s time to
refactor! :)
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  	
  
	
  	
  	
  	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type('Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  	
  
}
function	
  it_returns_user_from_token(	
  
	
  	
  	
  	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $this-­‐>getUser()-­‐>shouldRetun($user);	
  
}	
  
!
public	
  function	
  __construct(SecurityContext	
  $securityContext){	
  
	
  	
  	
  	
  $this-­‐>securityContext	
  =	
  $securityContext;	
  
}	
  
!
public	
  function	
  getUser()	
  
{	
  
	
  	
  	
  	
  $token	
  =	
  $this-­‐>securityContext-­‐>getToken();	
  
	
  	
  	
  	
  if	
  ($token	
  instanceof	
  TokenInterface)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  $token-­‐>getUser();	
  
	
  	
  	
  	
  }	
  
!
	
  	
  	
  	
  return	
  null;	
  
}
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  	
  
	
  	
  	
  	
  SecurityContext	
  $securityContext,	
  	
  
	
  	
  	
  	
  TokenInterface	
  $token,	
  User	
  $user)	
  	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getToken()-­‐>willReturn($token);	
  
	
  	
  	
  	
  $token-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type('Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  	
  
}
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  DomainSecurityContext	
  $securityContext,	
  

	
  	
  	
  	
  User	
  $user)	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type(‘Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  
}	
  
Composition over Inheritance
separation of concerns
small, well focused objects
composition is simpler to test
public	
  function	
  __construct(SecurityContext	
  $securityContext){	
  
	
  	
  	
  	
  $this-­‐>securityContext	
  =	
  $securityContext;	
  
}	
  
!
public	
  function	
  getUser()	
  
{	
  
	
  	
  	
  	
  $token	
  =	
  $this-­‐>securityContext-­‐>getToken();	
  
	
  	
  	
  	
  if	
  ($token	
  instanceof	
  TokenInterface)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  $token-­‐>getUser();	
  
	
  	
  	
  	
  }	
  
!
	
  	
  	
  	
  return	
  null;	
  
}
We can still
improve
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  DomainSecurityContext	
  $securityContext,	
  

	
  	
  	
  	
  User	
  $user)	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type(‘Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  
}	
  
function	
  it_loads_user_preferences(	
  
	
  	
  	
  	
  GetResponseEvent	
  $event,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  DomainSecurityContextInterface	
  $securityContext,	
  

	
  	
  	
  	
  User	
  $user)	
  
{	
  
	
  	
  	
  	
  $securityContext-­‐>getUser()-­‐>willReturn($user);	
  
!
	
  	
  	
  	
  $user-­‐>setPreferences(Argument::type(‘Preferences'))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>shouldBeCalled();	
  
!
	
  	
  	
  	
  $this-­‐>handle($event);	
  
}	
  
Dependency
Inversion Principle
high-level modules should
not depend on low-level
modules; both should depend
on abstractions
DIP states:
DIP states:
abstractions should not
depend upon details; details
should depend upon
abstractions
Isn’t it overhead?
What are benefits of
using PHPSpec?
TDD-cycle
oriented tool
ease Mocking
focused on
Messaging
encourage
injecting right
Collaborators
and following
Demeter Low
enables
Refactoring
and gives you
Regression Safety
and it’s trendy ;)
Is PHPSpec
the only design tool
we need?
s
So it helps ;)
Kacper Gunia
Software Engineer
Symfony Certified Developer
PHPers Silesia
Thanks!

More Related Content

What's hot

Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationKirill Chebunin
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
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
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
Dependency Injection in PHP
Dependency Injection in PHPDependency Injection in PHP
Dependency Injection in PHPKacper Gunia
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13Rafael Dohms
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix itRafael Dohms
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonfRafael Dohms
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介Jace Ju
 

What's hot (20)

Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
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
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
Dependency Injection in PHP
Dependency Injection in PHPDependency Injection in PHP
Dependency Injection in PHP
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
 
New in php 7
New in php 7New in php 7
New in php 7
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 

Viewers also liked

TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017Matthias Noback
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages webJean-Pierre Vincent
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsDavey Shafik
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phingRajat Pandit
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)Matthias Noback
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performanceafup Paris
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Marcello Duarte
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!tlrx
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLGabriele Bartolini
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Bruno Boucard
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)Arnauld Loyer
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apacheafup Paris
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsRyan Weaver
 
Password (in)security
Password (in)securityPassword (in)security
Password (in)securityEnrico Zimuel
 

Viewers also liked (20)

TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
 
Diving deep into twig
Diving deep into twigDiving deep into twig
Diving deep into twig
 
Elastic Searching With PHP
Elastic Searching With PHPElastic Searching With PHP
Elastic Searching With PHP
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQL
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)
 
Behat 3.0 meetup (March)
Behat 3.0 meetup (March)Behat 3.0 meetup (March)
Behat 3.0 meetup (March)
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apache
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
 
Password (in)security
Password (in)securityPassword (in)security
Password (in)security
 

Similar to PHPSpec - the only Design Tool you need - 4Developers

Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsClinton Dreisbach
 
Paying off technical debt with PHPSpec
Paying off technical debt with PHPSpecPaying off technical debt with PHPSpec
Paying off technical debt with PHPSpecLewis Wright
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your CodeAbbas Ali
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learnedMoving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learnedBaldur Rensch
 
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
 
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
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011Alessandro Nadalin
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormMichelangelo van Dam
 

Similar to PHPSpec - the only Design Tool you need - 4Developers (20)

Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
Paying off technical debt with PHPSpec
Paying off technical debt with PHPSpecPaying off technical debt with PHPSpec
Paying off technical debt with PHPSpec
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learnedMoving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
 
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
 
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
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStorm
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 

More from Kacper Gunia

How a large corporation used Domain-Driven Design to replace a loyalty system
How a large corporation used Domain-Driven Design to replace a loyalty systemHow a large corporation used Domain-Driven Design to replace a loyalty system
How a large corporation used Domain-Driven Design to replace a loyalty systemKacper Gunia
 
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learned
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learnedRebuilding Legacy Apps with Domain-Driven Design - Lessons learned
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learnedKacper Gunia
 
The top 10 things that any pro PHP developer should be doing
The top 10 things that any pro PHP developer should be doingThe top 10 things that any pro PHP developer should be doing
The top 10 things that any pro PHP developer should be doingKacper Gunia
 
Embrace Events and let CRUD die
Embrace Events and let CRUD dieEmbrace Events and let CRUD die
Embrace Events and let CRUD dieKacper Gunia
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Kacper Gunia
 
OmniFocus - the #1 ‘Getting Things Done’ tool
OmniFocus - the #1 ‘Getting Things Done’ toolOmniFocus - the #1 ‘Getting Things Done’ tool
OmniFocus - the #1 ‘Getting Things Done’ toolKacper Gunia
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupKacper Gunia
 

More from Kacper Gunia (9)

How a large corporation used Domain-Driven Design to replace a loyalty system
How a large corporation used Domain-Driven Design to replace a loyalty systemHow a large corporation used Domain-Driven Design to replace a loyalty system
How a large corporation used Domain-Driven Design to replace a loyalty system
 
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learned
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learnedRebuilding Legacy Apps with Domain-Driven Design - Lessons learned
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learned
 
The top 10 things that any pro PHP developer should be doing
The top 10 things that any pro PHP developer should be doingThe top 10 things that any pro PHP developer should be doing
The top 10 things that any pro PHP developer should be doing
 
Embrace Events and let CRUD die
Embrace Events and let CRUD dieEmbrace Events and let CRUD die
Embrace Events and let CRUD die
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
 
OmniFocus - the #1 ‘Getting Things Done’ tool
OmniFocus - the #1 ‘Getting Things Done’ toolOmniFocus - the #1 ‘Getting Things Done’ tool
OmniFocus - the #1 ‘Getting Things Done’ tool
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
 
Code Dojo
Code DojoCode Dojo
Code Dojo
 
SpecBDD in PHP
SpecBDD in PHPSpecBDD in PHP
SpecBDD in PHP
 

Recently uploaded

Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
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
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
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
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
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
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
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
 

Recently uploaded (20)

Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
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
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
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
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
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
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
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
 

PHPSpec - the only Design Tool you need - 4Developers