SlideShare ist ein Scribd-Unternehmen logo
1 von 137
Downloaden Sie, um offline zu lesen
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
PHPSpec - the only Design Tool you need - 4Developers
class	
  CustomerRepositoryTest	
  extends	
  
PHPUnit_Framework_TestCase	
  
{	
  
	
  	
  	
  	
  function	
  testClassExists()	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  $customerRepository	
  =	
  new	
  CustomerRepository;	
  
!
	
  	
  	
  	
  	
  	
  	
  	
  $customer	
  =	
  $customerRepository-­‐>findById(5);	
  
	
  	
  	
  	
  	
  	
  	
  	
  $this-­‐>assertInstanceOf('Customer',	
  $customer);	
  
	
  	
  	
  	
  }	
  
}
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
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!
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
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
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
Isn’t it overhead?
PHPSpec - the only Design Tool you need - 4Developers
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
PHPSpec - the only Design Tool you need - 4Developers
So it helps ;)
Kacper Gunia
Software Engineer
Symfony Certified Developer
PHPers Silesia
Thanks!

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 

Andere mochten auch

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
 

Andere mochten auch (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
 

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

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

Mehr von 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
 

Mehr von 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
 

Kürzlich hochgeladen

Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfinfogdgmi
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfJamie (Taka) Wang
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 

Kürzlich hochgeladen (20)

Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdf
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 

PHPSpec - the only Design Tool you need - 4Developers