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

10,606

Published on

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

Published in: Technology
1 Comment
12 Likes
Statistics
Notes
No Downloads
Views
Total Views
10,606
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
271
Comments
1
Likes
12
Embeds 0
No embeds

No notes for slide

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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×