Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PHPUnit and Zend Test
ZendCon 2009, San Jose, CA
Who am I ?
Michelangelo van Dam

Independent Enterprise PHP consultant
Co-founder PHPBelgium

Mail me at dragonbe [at] gma...
Unit testing ?

•   test smallest piece of code (unit)
•   to verify its behavior is as expected
•   exceptions are thrown...
Everyone should test !
•   rule #1: you should test
•   rule #2: see rule #1 (no excuses!!!)

•   Why?
    - tests are aut...
Why PHPUnit ?

•   part of xUnit family
•   ported by Sebastian Bergmann
•   PEAR package
    - pear channel-discover pear...
PHPUnit !== Atlassian Jira


        Just making sure ;-)




                6
<?php
                  My first class
class SayHello
{
  public $name;

    public function __construct($name = 'nobody')
...
<?php
                           Run it
require_once 'sayhello.php';

$hello = new SayHello();
echo $hello->speak();

// o...
<?php
                       Test it !
require_once 'sayhello.php';

class SayHelloTest extends PHPUnit_Framework_TestCase...
We’re good
$ phpunit SayHelloTest
PHPUnit 3.3.15 by Sebastian Bergmann.

..

Time: 0 seconds

OK (2 tests, 2 assertions)

...
It’s that simple !




        11
Test Driven Development

•   think about functionality
•   think about testable functionality
•   write functional tests
•...
More testing

•   data providers (@dataProvider)
•   exception (@expectedException)
•   fixtures (setUp() and tearDown())
•...
Data Provider

•   provides arbitrary arguments
    -   array
    -   object (that implements Iterator)
•   annotated by @...
<?php
                 CombineTest
class CombineTest extends PHPUnit_Framework_TestCase
{
    /**
      * @dataProvider pr...
Testing CombineTest
# phpunit CombineTest CombineTest.php
PHPUnit 3.3.2 by Sebastian Bergmann.

..F

Time: 0 seconds

Ther...
Expected Exception

•   testing exceptions
    -   that they are thrown
    -   are properly catched




                 ...
OopsTest
<?php
class OopsTest extends PHPUnit_Framework_TestCase
{
    public function testOops()
    {
        try {
    ...
Testing OopsTest

# phpunit OopsTest OopsTest.php
PHPUnit 3.3.2 by Sebastian Bergmann.

.

Time: 0 seconds

OK (1 test, 0 ...
Fixtures

•   is a “known state” of an application
    -   needs to be ‘set up’ at start of test
    -   needs to be ‘torn...
<?php
                     FixmeTest
class FixmeTest extends PHPUnit_Framework_TestCase
{
    protected $fixme;

    publi...
Testing FixmeTest

# phpunit FixmeTest FixmeTest.php
PHPUnit 3.3.2 by Sebastian Bergmann.

..

Time: 0 seconds

OK (2 test...
Doubles


•   stub objects
•   mock objects




                   23
Stubs

•   isolates tests from external influences
    -   slow connections
    -   expensive and complex resources
•   rep...
StubTest
<?php
// example taken from phpunit.de
class StubTest extends PHPUnit_Framework_TestCase
{
    public function te...
Testing StubTest

# phpunit StubTest StubTest.php
PHPUnit 3.3.2 by Sebastian Bergmann.

.

Time: 0 seconds

OK (1 test, 1 ...
Mocks

•   simulated objects
•   mimics API or behaviour
•   in a controlled way
•   to test a real object




           ...
<?php
                ObserverTest
// example taken from Sebastian Bergmann’s slides on
// slideshare.net/sebastian_bergma...
Database Testing
•   ported by Mike Lively from DBUnit
•   PHPUnit_Extensions_Database_TestCase
•   for database-driven pr...
BankAccount Example
                         BankAccount example by Mike Lively
           http://www.ds-o.com/archives/63...
Database Testing Example
<?php
require_once 'PHPUnit/Extensions/Database/Tescase.php';
require_once 'PHPUnit/Extensions/Da...
Testing data store/retrieve
...

public function testNewAccountCreation()
{
  $bank_account = new BankAccount('12345678912...
Testing BankAccount

$ phpunit BankAccountDBTestPHPUnit 3.3.15 by Sebastian Bergmann.

.....

Time: 0 seconds

OK (5 tests...
BankAccount Dataset

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <bank_account account_number="15934903649620486"...
Testing ZF App

•   using ZF bootstrap
•   uses ZF autoloading
•   tests MVC controllers and views




                   ...
<?php
             Testing Controllers
require_once 'Zend/Test/PHPUnit/TestCase.php';

class IndexControllerTest extends Z...
Zend_Test_PHPUnit

•   Dispatching: $this->dispatch(‘/’);
•   Testing Controller:
    $this->assertController(‘index’);
• ...
More on Zend_Test
http://framework.zend.com/manual/en/zend.test.html

              Jon Lebensold’s ZendCast sessions
    ...
Interesting Readings

•   PHPUnit by Sebastian Bergmann
    http://phpunit.de


•   Art of Unit Testing by Roy Osherove
  ...
Credits
                     Thumbs up monkey
  http://www.flickr.com/photos/amberandclint/3266859324/

                   ...
NOTICE


No elePHPants were harmed
while performing these tests




            41
License
This presentation is released under the Creative Commons
Attribution-Share Alike 3.0 Unported License
You are free...
Questions ?

             Thank you

This presentation will be available on
  http://slideshare.com/DragonBe

           V...
Upcoming SlideShare
Loading in …5
×

Php Unit With Zend Framework Zendcon09

11,771 views

Published on

An introduction to Unit Testing and coupling it in with Zend Framework

Published in: Technology

Php Unit With Zend Framework Zendcon09

  1. 1. PHPUnit and Zend Test ZendCon 2009, San Jose, CA
  2. 2. Who am I ? Michelangelo van Dam Independent Enterprise PHP consultant Co-founder PHPBelgium Mail me at dragonbe [at] gmail [dot] com Follow me on http://twitter.com/DragonBe Read my articles on http://dragonbe.com See my profile on http://linkedin.com/in/michelangelovandam 2
  3. 3. Unit testing ? • test smallest piece of code (unit) • to verify its behavior is as expected • exceptions are thrown • code remains backwards compatible 3
  4. 4. Everyone should test ! • rule #1: you should test • rule #2: see rule #1 (no excuses!!!) • Why? - tests are automated - run over and over again - detect flaws, errors, mistakes, screw ups - progress indication of the project 4
  5. 5. Why PHPUnit ? • part of xUnit family • ported by Sebastian Bergmann • PEAR package - pear channel-discover pear.phpunit.de - pear install phpunit/PHPUnit 5
  6. 6. PHPUnit !== Atlassian Jira Just making sure ;-) 6
  7. 7. <?php My first class class SayHello { public $name; public function __construct($name = 'nobody') { $this->name = $name; } public function speak() { return "Hello {$this->name}!"; } } 7
  8. 8. <?php Run it require_once 'sayhello.php'; $hello = new SayHello(); echo $hello->speak(); // outputs Hello nobody! 8
  9. 9. <?php Test it ! require_once 'sayhello.php'; class SayHelloTest extends PHPUnit_Framework_TestCase { public function testSpeakWithoutParams () { $hello = new SayHello(); $this->assertEquals("Hello nobody!", $hello->speak()); } public function testSpeakWithParams () { $hello = new SayHello('Marco'); $this->assertEquals("Hello Marco!", $hello->speak()); } } 9
  10. 10. We’re good $ phpunit SayHelloTest PHPUnit 3.3.15 by Sebastian Bergmann. .. Time: 0 seconds OK (2 tests, 2 assertions) 10
  11. 11. It’s that simple ! 11
  12. 12. Test Driven Development • think about functionality • think about testable functionality • write functional tests • write functionality 12
  13. 13. More testing • data providers (@dataProvider) • exception (@expectedException) • fixtures (setUp() and tearDown()) • doubles (mocks and stubs) • database testing 13
  14. 14. Data Provider • provides arbitrary arguments - array - object (that implements Iterator) • annotated by @dataProvider provider • multiple arguments 14
  15. 15. <?php CombineTest class CombineTest extends PHPUnit_Framework_TestCase { /** * @dataProvider provider */ public function testCombine($a, $b, $c) { $this->assertEquals($c, $a . ' ' . $b); } public function provider() { return array ( array ('Hello','World','Hello World'), array ('Go','PHP','Go PHP'), array ('This','Fails','This succeeds') ); } } 15
  16. 16. Testing CombineTest # phpunit CombineTest CombineTest.php PHPUnit 3.3.2 by Sebastian Bergmann. ..F Time: 0 seconds There was 1 failure: 1) testCombine(CombineTest) with data set #2 ('This', 'Fails', 'This succeeds') Failed asserting that two strings are equal. expected string <This succeeds> difference < xxxxx???> got string <This Fails> /root/dev/phpunittutorial/CombineTest.php:9 FAILURES! Tests: 3, Assertions: 3, Failures: 1. 16
  17. 17. Expected Exception • testing exceptions - that they are thrown - are properly catched 17
  18. 18. OopsTest <?php class OopsTest extends PHPUnit_Framework_TestCase { public function testOops() { try { throw new Exception('I just made a booboo'); } catch (Exception $expected) { return; } $this->fail('An expected Exception was not thrown'); } } 18
  19. 19. Testing OopsTest # phpunit OopsTest OopsTest.php PHPUnit 3.3.2 by Sebastian Bergmann. . Time: 0 seconds OK (1 test, 0 assertions) 19
  20. 20. Fixtures • is a “known state” of an application - needs to be ‘set up’ at start of test - needs to be ‘torn down’ at end of test - shares “states” over test methods 20
  21. 21. <?php FixmeTest class FixmeTest extends PHPUnit_Framework_TestCase { protected $fixme; public function setUp() { $this->fixme = array (); } public function testFixmeEmpty() { $this->assertEquals(0, sizeof($this->fixme)); } public function testFixmeHasOne() { array_push($this->fixme, 'element'); $this->assertEquals(1, sizeof($this->fixme)); } } 21
  22. 22. Testing FixmeTest # phpunit FixmeTest FixmeTest.php PHPUnit 3.3.2 by Sebastian Bergmann. .. Time: 0 seconds OK (2 tests, 2 assertions) 22
  23. 23. Doubles • stub objects • mock objects 23
  24. 24. Stubs • isolates tests from external influences - slow connections - expensive and complex resources • replaces a “system under test” (SUT) - for the purpose of testing 24
  25. 25. StubTest <?php // example taken from phpunit.de class StubTest extends PHPUnit_Framework_TestCase { public function testStub() { $stub = $this->getMock('SomeClass'); $stub->expects($this->any()) ->method('doSometing') ->will($this->returnValue('foo')); } // Calling $stub->doSomething() will now return 'foo' } 25
  26. 26. Testing StubTest # phpunit StubTest StubTest.php PHPUnit 3.3.2 by Sebastian Bergmann. . Time: 0 seconds OK (1 test, 1 assertion) 26
  27. 27. Mocks • simulated objects • mimics API or behaviour • in a controlled way • to test a real object 27
  28. 28. <?php ObserverTest // example taken from Sebastian Bergmann’s slides on // slideshare.net/sebastian_bergmann/advanced-phpunit-topics class ObserverTest extends PHPUnit_Framework_TestCase { public function testUpdateIsCalledOnce() { $observer = $this->getMock('Observer', array('update')); $observer->expects($this->once()) ->method('update') ->with($this->equalTo('something')); $subject = new Subject; $subject->attach($observer) ->doSomething(); } } 28
  29. 29. Database Testing • ported by Mike Lively from DBUnit • PHPUnit_Extensions_Database_TestCase • for database-driven projects • puts DB in know state between tests • imports and exports DB data from/to XML • easily added to existing tests 29
  30. 30. BankAccount Example BankAccount example by Mike Lively http://www.ds-o.com/archives/63-PHPUnit-Database-Extension-DBUnit-Port.html http://www.ds-o.com/archives/64-Adding-Database-Tests-to-Existing-PHPUnit-Test-Cases.html BankAccount Classs by Sebastian Bergmann http://www.slideshare.net/sebastian_bergmann/testing-phpweb-applications-with-phpunit-and-selenium The full BankAccount class http://www.phpunit.de/browser/phpunit/branches/release/3.3/PHPUnit/Samples/BankAccountDB/ BankAccount.php 30
  31. 31. Database Testing Example <?php require_once 'PHPUnit/Extensions/Database/Tescase.php'; require_once 'PHPUnit/Extensions/Database/Dataset/FlatXmlDataSet.php'; require_once 'BankAccount.php'; class BankAccountDBTest extends PHPUnit_Extensions_Database_Testcase { public function getConnection() { $pdo = new PDO('sqlite::memory:'); return $this->createDefaultDBConnection($pdo, 'testdb'); } public function getDataSet() { return $this->createFlatFileXMLDataSet( dirname(__FILE__) . '/_files/dataset.xml'); } ... 31
  32. 32. Testing data store/retrieve ... public function testNewAccountCreation() { $bank_account = new BankAccount('12345678912345678', $this->pdo); $xml_dataset = $this->createFlatXMLDataSet( dirname(__FILE__).'/_files/ba-new-account.xml'); $this->assertDataSetsEquals($xml_dataset, $this->getConnection()->createDataSet()); } ... 32
  33. 33. Testing BankAccount $ phpunit BankAccountDBTestPHPUnit 3.3.15 by Sebastian Bergmann. ..... Time: 0 seconds OK (5 tests, 10 assertions) 33
  34. 34. BankAccount Dataset <?xml version="1.0" encoding="UTF-8"?> <dataset> <bank_account account_number="15934903649620486" balance="100.00" /> <bank_account account_number="15936487230215067" balance="1216.00" /> <bank_account account_number="12348612357236185" balance="89.00" /> </dataset> 34
  35. 35. Testing ZF App • using ZF bootstrap • uses ZF autoloading • tests MVC controllers and views 35
  36. 36. <?php Testing Controllers require_once 'Zend/Test/PHPUnit/TestCase.php'; class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { public function setUp() { $this->bootstrap = array ($this, 'bootstrap'); parent::setUp(); } public function tearDown() { parent::tearDown(); $this->bootstrap = null; } public function bootstrap() { $this->frontController->registerPlugin(new Initializer('test')); } // tests goes here } 36
  37. 37. Zend_Test_PHPUnit • Dispatching: $this->dispatch(‘/’); • Testing Controller: $this->assertController(‘index’); • Testing Action: $this->assertAction(‘index’); 37
  38. 38. More on Zend_Test http://framework.zend.com/manual/en/zend.test.html Jon Lebensold’s ZendCast sessions http://www.zendcast.com ZendCast on Zend Framework Unit Testing http://www.zendcasts.com/unit-testing-with-the-zend-framework-with-zend_test-and-phpunit/2009/06/ 38
  39. 39. Interesting Readings • PHPUnit by Sebastian Bergmann http://phpunit.de • Art of Unit Testing by Roy Osherove http://artofunittesting.com • Mike Lively’s blog http://www.ds-o.com/archives/63-PHPUnit-Database-Extension-DBUnit-Port.html 39
  40. 40. Credits Thumbs up monkey http://www.flickr.com/photos/amberandclint/3266859324/ Lomo elePHPant http://www.flickr.com/photos/jakobwesthoff/3231273333/ Sebastian Bergmann http://www.flickr.com/photos/sebastian_bergmann/2293021853 40
  41. 41. NOTICE No elePHPants were harmed while performing these tests 41
  42. 42. License This presentation is released under the Creative Commons Attribution-Share Alike 3.0 Unported License You are free: - to share : to copy, distribute and transmit the work - to remix : to adapt the work Under the following conditions: - attribution :You must attribute the work in the manner specified by the author or licensor - share alike : If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license See: http://creativecommons.org/licenses/by-sa/3.0/ 42
  43. 43. Questions ? Thank you This presentation will be available on http://slideshare.com/DragonBe Vote this talk http://joind.in/638 43

×