Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introducing Unit tests with CakePHP

Introducing Unit tests with CakePHP

What are Unit Tests and how do they look like in CakePHP?

Johannes Nagl

December 04, 2013
Tweet

More Decks by Johannes Nagl

Other Decks in Programming

Transcript

  1. Current state:
    Changes create pure angst and suspense!
    http://www.flickr.com/photos/wolfgangfoto/2355166933/

    View Slide

  2. We have no ideas about the following:
    … does newly created code really work?
    … does newly created code break old code (“Regression Error”)
    … how does adequate test data look like?
    … do we have all adequate test data in our database for manually testing?
    … do/can we really test all cases manually or do we miss (the most important)
    ones?

    View Slide

  3. One of many solutions:
    Automatic testing.
    In this case:
    Testing with CakePHP/PHPUnit.

    View Slide

  4. Welcome to the bride side of life!
    Insert Music & wordplays about sunrise avenue here.

    View Slide

  5. Unit Testing
    “In computer programming, unit testing is a method by
    which individual units of source code, sets of one or more
    computer program modules together with associated control
    data, usage procedures, and operating procedures are tested
    to determine if they are fit for use.
    Intuitively, one can view a unit as the smallest testable part
    of an application.”
    http://en.wikipedia.org/wiki/Unit_testing

    View Slide

  6. CakePHP Unit Testing
    … out of the box there is support for:
    Models, Controllers, Helpers
    … MVC: Views?
    -> Selenium
    … JS?
    -> Nope!

    View Slide

  7. Requirements (as in: dev-requirements)
    0. CakePHP
    1. PHP Unit (available via composer)
    2. Own testing database
    Optional:
    3. XDebug (for code coverage)

    View Slide

  8. Where to start?
    https://dev.domain.tld/test.php

    View Slide

  9. Where to put your tests?
    /app/Test/…
    All test cases belong to this area
    All test suites (run multiple test files at once)
    belong to this area

    View Slide

  10. How to test?
    You write stupid code. Very stupid. Very very stupid. And it’
    s very repetitive.
    so, you test your app code with simple assertions:
    $result = $this->Team->isAbleTo(‘test’);
    $expected = array(‘read’, ‘create’, ‘edit’, ‘delete’);
    $this->assertsEqual($expected, $result);

    View Slide

  11. Assertions:
    (http://book.cakephp.org/2.0/en/development/testing.html)
    ● assertEquals: ===
    ● assertContains: does $result contain a specific string?
    ● assertTrue
    ● assertFalse
    ● and more!

    View Slide

  12. How do tests look like in real life?
    Helper Test: https://gist.github.com/johannesnagl/7785824
    Component Test: https://gist.github.com/johannesnagl/7785842
    Model Test: …

    View Slide

  13. Whoop, before we test models…
    We need some data to test!

    View Slide

  14. View Slide

  15. No, … Fixtures!
    We don’t want to test our app with real life data. So we need something else.
    Test datasets are called “fixtures”. And they get “magically” imported when
    running our test cases.
    class GroupFixture extends CakeTestFixture {
    public $import = 'Group';
    public $records = array(
    array('id' => 1, 'name' => 'Group with users'),
    array('id' => 2, 'name' => 'Group with one user'),
    array('id' => 3, 'name' => 'Group without any user')
    );
    }

    View Slide

  16. How does tests look like in real life?
    /2
    Model Test: https://gist.github.com/johannesnagl/7785994
    Controller Test: …

    View Slide

  17. Wow, it’s getting hard!
    Controllers have many dependencies and
    maybe quite risky operations (think of sending
    e-mails, …)
    That’s why we need mock-ing!

    View Slide

  18. Alois Mock!?
    former austrian politician
    http://oevp-galerie.hico-nms.at/var/albums/Allgemein/Alois%20und%20Edith%20Mock.jpg?m=1329683884

    View Slide

  19. Mocking methods/objects
    Example: We don’t want any mails to be sent in the testing
    environment.
    So we “mock” the Email-Object and replace the method
    “send” with a “result true;”.
    public function testSendingEmails() {
    $model = $this->getMockForModel('EmailVerification', array('send'));
    $model->expects($this->once())
    ->method('send')
    ->will($this->returnValue(true));
    $model->verifyEmail('[email protected]');
    }

    View Slide

  20. Required code changes
    $this->redirect([‘controller’ => ‘foo’, ‘action’ => ‘bar’]);
    return $this->redirect([‘controller’ => ‘foo’, ‘action’ => ‘bar’]);

    View Slide

  21. Lessons learned so far
    ● Thinking about useful test cases let you think
    better about methods
    ● Decouple all the things!
    ● Always return values in your methods!
    ○ $this->setUser(1);
    $this->user = $this->setUser(1);
    ● Fix the Fixtures! (Instead of trying to do
    voodoo-magic with your fixtures, write own
    “namespaced”-fixtures for every test case)
    ○ Testcase 1: Use User-Fixture 100, 101, 102
    ○ Testcase 2: Use User-Fixture 200, 201, 202

    View Slide

  22. In the end …
    If everything’s green, everything’s awesome!

    View Slide