TDD, DDD & Teamwork

TDD, DDD & Teamwork

B84af63b07f297643ab1fd943c9ac59c?s=128

pelshoff

April 12, 2019
Tweet

Transcript

  1. None
  2. TDD, DDD & Teamwork @jlammerts @pelshoff

  3. Part I: TDD

  4. What is a test?

  5. Something shouldn’t happen • Expect exception • Do the thing

  6. final class PresentationTest extends TestCase { /** * @test */

    public function presentationsShouldHaveTitles(): void { $this->expectException(InvalidPresentation::class); new Presentation('', '', ''); } }
  7. Something should happen • Do the thing • Expect result

  8. final class PresentationTest extends TestCase { /** * @test */

    public function presentationsShouldAllowNewSubtitles(): void { $actual = new Presentation('With', 'a', 'title'); $expectation = new Presentation('With', 'another', 'title'); $actual->changeSubtitleTo('another'); $this->assertEquals($expectation, $actual); } }
  9. What is a good test?

  10. A good test... • Arrange • Act • Assert

  11. A good test... • Setup • Expect • Execute •

    Verify
  12. A good test... • Setup • Expect • Perform •

    Assert
  13. A good test... • Given • When • Then

  14. What is TDD?

  15. “Test-Driven Development (TDD) is a technique for building software that

    guides software development by writing tests.” - Martin Fowler
  16. Three steps of TDD • Red • Green • Refactor

  17. What is the difference between test-first & TDD?

  18. Recap • Given, When, Then • Red, Green, Refactor •

    Client-first
  19. Good luck and have fun!

  20. Part II: Teamwork

  21. The Attitude Model

  22. Divergent

  23. Convergent

  24. Divergent Tend to be… • Open • Optimistic and curious

    • Quick, sloppy and careless
  25. Convergent Tend to be... • Closed • Pessimistic and inquisitive

    • Paced, diligent and careful
  26. The Double Design Diamond

  27. None
  28. Good luck and have fun!

  29. Part III: DDD

  30. Value objects

  31. final class Name { private $lastName; private $firstName; private $insertion;

    public function __construct(string $lastName, string $firstName, string $insertion) { $this->lastName = $lastName; $this->firstName = $firstName; $this->insertion = $insertion; $this->nameMustHaveLastName(); } private function nameMustHaveLastName(): void { if (!$this->lastName) { throw InvalidName::becauseLastNameIsMissing(); } } public function getLastName(): string { /**/ } public function getFirstName(): string { /**/ } public function getInsertion(): string { /**/ } }
  32. final class EmailAddress { private $emailAddress; public function __construct(string $emailAddress)

    { $this->emailAddress = $emailAddress; $this->emailAddressMustBeAnActualEmailAddress(); } private function emailAddressMustBeAnActualEmailAddress(): void { if (!filter_var($this->emailAddress, FILTER_VALIDATE_EMAIL)) { throw InvalidEmailAddress::becauseThisIsNotAnEmailAddress(); } } public function asString(): string { return $this->emailAddress; } }
  33. Value objects • Express a value • Define allowed values

    • Are immutable • Are easy to test
  34. Entities

  35. final class Attendee { private $id; private $name; private $emailAddress;

    public function __construct(Uuid $id, Name $name, EmailAddress $emailAddress) { $this->id = $id; $this->name = $name; $this->emailAddress = $emailAddress; } public function getId(): Uuid { /**/ } public function getName(): Name { /**/ } public function setName(Name $name): Attendee { /**/ } public function getEmailAddress(): EmailAddress { /**/ } public function setEmailAddress(EmailAddress $emailAddress): Attendee { $this->emailAddress = $emailAddress; return $this; } }
  36. Entities • Have identity • Are more than their attributes

    • Evolve over time • Are slightly harder to test
  37. Services

  38. final class Registration { private $repository; public function __construct(AttendeeRepository $repository)

    { $this->repository = $repository; } public function registerNew(Attendee $attendee): void { $this->emailAddressMustBeUnique($attendee->getEmailAddress()); $this->repository->add($attendee); } private function emailAddressMustBeUnique(EmailAddress $emailAddress): void { try { $this->repository->findByEmailAddress($emailAddress); } catch (AttendeeNotFound $e) { return; } throw RegistrationFailed::becauseEmailAddressIsNotUnique(); } }
  39. Services • Have no identity or attributes (Are not a

    “thing”) • Tackle cross-concern operations • Are harder to test
  40. Context Technische bouwblokken Quiz Case study I Case study II

  41. class Address

  42. class BicycleService

  43. class StreetAddress

  44. class Investment

  45. Good luck and have fun!

  46. The end! @jlammerts @pelshoff https://joind.in/event/php-yorkshire-2019/tdd-ddd--teamwork