Appetite comes with testing

     ā€œIt's a dangerous business, Frodo, going out
     your door. You step onto the road, and if you
     don't keep your feet, there's no knowing
     where you might be swept off to.ā€
                               J.R.R. Tolkien, The Lord of the Rings




Change begins with awareness
Defect Cost Increase




Change begins with awareness
Defect Cost Increase




Change begins with awareness
Stress cycle




Change begins with awareness
Testing as...




      documentation


Change begins with awareness
Testing as...



        instrument for
          cooperation

Change begins with awareness
Testing as...


        instrument for
         open source
         cooperation

Change begins with awareness
Pair programming




Change begins with awareness
All begins with...




   ...a need
Change begins with awareness
And...




 ā€œSupporting multiple user classes is not easy at all. It would
 make the bundle code far more complex as we would
 basically need to change all places interacting with the user
 to be able to handle all user classes. I don't really want to
 go this way (it will also make it more likely to introduce
 bugs).ā€

    ...a delusion
Change begins with awareness
But...


  In Symfony2, all core classes use the service container,
  so it is easy to extend, configure and use any object




   ...a hope
Change begins with awareness
Service Container
                  Dependency Injection Container


          use AcmeHelloBundleMailer;

          $mailer = new Mailer('sendmail');
          $mailer->send('info@netmeans.net', ... );




Change begins with awareness
Service Container
                  Dependency Injection Container
          class Mailer
          {
              private $mailerType;

              public function __construct($mailerType)
              {
                  $this->mailerType = $mailerType
              }

              public function send($to, ...)
              {
                  ...
              }
          }

          services:
              my_mailer:
                  class:       AcmeHelloBundleMailer
                  arguments:   [sendmail]


Change begins with awareness
Service Container
                  Dependency Injection Container


          class HelloController extends Controller
          {
              public function sendEmailAction()
              {
                  $mailer = $this->get('my_mailer');
                  $mailer->send('info@netmeans.net', ... );
              }
          }




Change begins with awareness
FOSUserBundle
             fos_user:
                 db_driver: orm
                 firewall_name: main
                 user_class: AcmeUserBundleEntityUser




Change begins with awareness
FOSUserBundle
             fos_user:
                 db_driver: orm
                 firewall_name: main
                 user_class: AcmeUserBundleEntityUser
                 service:
                     user_manager: custom_user_manager




Change begins with awareness
So ...

          We have to create our custom
          UserManager that accepts in the
          constructor an object that have the
          responsibility to discriminate user
          types




...a solution
Change begins with awareness
First of all: test

          We start writing some functional
          tests to check correct integration
          of FOSUserBundle




Change begins with awareness
Now we feel good

          We can extends FOSUser without pain
          improving changes step by step




Change begins with awareness
Custom UserManager

 Class UserManager extends FOSUserBundleEntityUserManager
 {
     protected $userDiscriminator;

     public function __construct(..., UserDiscriminator $userDiscriminator)

     public function getClass()
     {
         return $this->userDiscriminator->getClass();
     }
 }




Change begins with awareness
UserDiscriminator

              public function getClass()
              {
                 return 'Acme/UserBundle/Entity/UserOne';
              }




Change begins with awareness
From here it's all smooth

          With little iterations, we improve
          UserManager and UserDiscriminator
          with unit and functional tests,
          passing from a dirty code to a more
          elegant one




Change begins with awareness
NmnMultiUserBundle
     fos_user:
         db_driver: orm
         firewall_name: main
         user_class: AcmeUserBundleEntityUser
         service:
             user_manager: nmn_user_manager
         registration:
             form:
                 handler: nmn_user_registration_form_handler
         profile:
             form:
                 handler: nmn_user_profile_form_handler




Change begins with awareness
NmnMultiUserBundle
  parameters:
    nmn_user_discriminator_parameters:
      classes:
          user_one:
              entity: AcmeUserBundleEntityUserOne
              registration: AcmeUserBundleFormTypeRegistrationUserOneFormType
              profile: AcmeUserBundleFormTypeProfileUserOneFormType
              factory:
          user_two:
              entity: AcmeUserBundleEntityUserTwo
              registration: AcmeUserBundleFormTypeRegistrationUserTwoFormType
              profile: AcmeUserBundleFormTypeProfileUserTwoFormType
              factory:




Change begins with awareness
NmnMultiUserBundle

     Ok, it is an hack :)

     A lazy way to use for free most of the
     functionality of FOSUserBundle ...

     ... but it is ready to be improved by
     anyone.




Change begins with awareness
NmnMultiUserBundle

        github.com/netmeansnet/NmnMultiUserBundle

        github.com/netmeansnet/NmnMultiUserBundleSandbox

        travis-ci.org/#!/netmeansnet/NmnMultiUserBundle




                               @leonardo_nmn

                               @euxpom




Change begins with awareness
Some Books
                       The Clean Coder
                       A code of Conduct for Professional Programmers




                       Martin, Robert C.




I know this sounds strident and unilateral, but given the record I don't
think the surgeons should have to defend hand-washing, and I don't
think programmers should have to defend TDD

Change begins with awareness
Some Books
                       Extreme Programming Explained
                       Embrace Change




                       Beck, Kent




In software development, ā€œperfectā€ is a verb, not an adjective
In XP, testing is as important as programming
Change begins with awareness
Some Books
                       The Grumpy Programmer's Guide To Building
                       Testable Applications in PHP




                       Hartjes, Chris




Building testable applications is Hard
The reason for investing in automated testing is obvious: any bugs you
catch before your application makes it into production cost less in terms
of resources (money, developer time) to fix than fixing it into production

Change begins with awareness

Appetite comes with testing

  • 1.
    Appetite comes withtesting ā€œIt's a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there's no knowing where you might be swept off to.ā€ J.R.R. Tolkien, The Lord of the Rings Change begins with awareness
  • 2.
    Defect Cost Increase Changebegins with awareness
  • 3.
    Defect Cost Increase Changebegins with awareness
  • 4.
  • 5.
    Testing as... documentation Change begins with awareness
  • 6.
    Testing as... instrument for cooperation Change begins with awareness
  • 7.
    Testing as... instrument for open source cooperation Change begins with awareness
  • 8.
  • 9.
    All begins with... ...a need Change begins with awareness
  • 10.
    And... ā€œSupporting multipleuser classes is not easy at all. It would make the bundle code far more complex as we would basically need to change all places interacting with the user to be able to handle all user classes. I don't really want to go this way (it will also make it more likely to introduce bugs).ā€ ...a delusion Change begins with awareness
  • 11.
    But... InSymfony2, all core classes use the service container, so it is easy to extend, configure and use any object ...a hope Change begins with awareness
  • 12.
    Service Container Dependency Injection Container use AcmeHelloBundleMailer; $mailer = new Mailer('sendmail'); $mailer->send('info@netmeans.net', ... ); Change begins with awareness
  • 13.
    Service Container Dependency Injection Container class Mailer { private $mailerType; public function __construct($mailerType) { $this->mailerType = $mailerType } public function send($to, ...) { ... } } services: my_mailer: class: AcmeHelloBundleMailer arguments: [sendmail] Change begins with awareness
  • 14.
    Service Container Dependency Injection Container class HelloController extends Controller { public function sendEmailAction() { $mailer = $this->get('my_mailer'); $mailer->send('info@netmeans.net', ... ); } } Change begins with awareness
  • 15.
    FOSUserBundle fos_user: db_driver: orm firewall_name: main user_class: AcmeUserBundleEntityUser Change begins with awareness
  • 16.
    FOSUserBundle fos_user: db_driver: orm firewall_name: main user_class: AcmeUserBundleEntityUser service: user_manager: custom_user_manager Change begins with awareness
  • 17.
    So ... We have to create our custom UserManager that accepts in the constructor an object that have the responsibility to discriminate user types ...a solution Change begins with awareness
  • 18.
    First of all:test We start writing some functional tests to check correct integration of FOSUserBundle Change begins with awareness
  • 19.
    Now we feelgood We can extends FOSUser without pain improving changes step by step Change begins with awareness
  • 20.
    Custom UserManager ClassUserManager extends FOSUserBundleEntityUserManager { protected $userDiscriminator; public function __construct(..., UserDiscriminator $userDiscriminator) public function getClass() { return $this->userDiscriminator->getClass(); } } Change begins with awareness
  • 21.
    UserDiscriminator public function getClass() { return 'Acme/UserBundle/Entity/UserOne'; } Change begins with awareness
  • 22.
    From here it'sall smooth With little iterations, we improve UserManager and UserDiscriminator with unit and functional tests, passing from a dirty code to a more elegant one Change begins with awareness
  • 23.
    NmnMultiUserBundle fos_user: db_driver: orm firewall_name: main user_class: AcmeUserBundleEntityUser service: user_manager: nmn_user_manager registration: form: handler: nmn_user_registration_form_handler profile: form: handler: nmn_user_profile_form_handler Change begins with awareness
  • 24.
    NmnMultiUserBundle parameters: nmn_user_discriminator_parameters: classes: user_one: entity: AcmeUserBundleEntityUserOne registration: AcmeUserBundleFormTypeRegistrationUserOneFormType profile: AcmeUserBundleFormTypeProfileUserOneFormType factory: user_two: entity: AcmeUserBundleEntityUserTwo registration: AcmeUserBundleFormTypeRegistrationUserTwoFormType profile: AcmeUserBundleFormTypeProfileUserTwoFormType factory: Change begins with awareness
  • 25.
    NmnMultiUserBundle Ok, it is an hack :) A lazy way to use for free most of the functionality of FOSUserBundle ... ... but it is ready to be improved by anyone. Change begins with awareness
  • 26.
    NmnMultiUserBundle github.com/netmeansnet/NmnMultiUserBundle github.com/netmeansnet/NmnMultiUserBundleSandbox travis-ci.org/#!/netmeansnet/NmnMultiUserBundle @leonardo_nmn @euxpom Change begins with awareness
  • 27.
    Some Books The Clean Coder A code of Conduct for Professional Programmers Martin, Robert C. I know this sounds strident and unilateral, but given the record I don't think the surgeons should have to defend hand-washing, and I don't think programmers should have to defend TDD Change begins with awareness
  • 28.
    Some Books Extreme Programming Explained Embrace Change Beck, Kent In software development, ā€œperfectā€ is a verb, not an adjective In XP, testing is as important as programming Change begins with awareness
  • 29.
    Some Books The Grumpy Programmer's Guide To Building Testable Applications in PHP Hartjes, Chris Building testable applications is Hard The reason for investing in automated testing is obvious: any bugs you catch before your application makes it into production cost less in terms of resources (money, developer time) to fix than fixing it into production Change begins with awareness