SlideShare a Scribd company logo
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] 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
Unit testing ?

•   test smallest piece of code (unit)
•   to verify its behavior is as expected
•   exceptions are thrown
•   code remains backwards compatible




                             3
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
Why PHPUnit ?

•   part of xUnit family
•   ported by Sebastian Bergmann
•   PEAR package
    - pear channel-discover pear.phpunit.de
    - pear install phpunit/PHPUnit


                             5
PHPUnit !== Atlassian Jira


        Just making sure ;-)




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

    public function __construct($name = 'nobody')
    {
      $this->name = $name;
    }

    public function speak()
    {
      return "Hello {$this->name}!";
    }
}




                                 7
<?php
                           Run it
require_once 'sayhello.php';

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

// outputs Hello nobody!




                               8
<?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
We’re good
$ phpunit SayHelloTest
PHPUnit 3.3.15 by Sebastian Bergmann.

..

Time: 0 seconds

OK (2 tests, 2 assertions)




                               10
It’s that simple !




        11
Test Driven Development

•   think about functionality
•   think about testable functionality
•   write functional tests
•   write functionality




                              12
More testing

•   data providers (@dataProvider)
•   exception (@expectedException)
•   fixtures (setUp() and tearDown())
•   doubles (mocks and stubs)
•   database testing



                       13
Data Provider

•   provides arbitrary arguments
    -   array
    -   object (that implements Iterator)
•   annotated by @dataProvider provider
•   multiple arguments



                         14
<?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
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
Expected Exception

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




                         17
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
Testing OopsTest

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

.

Time: 0 seconds

OK (1 test, 0 assertions)




                                19
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
<?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
Testing FixmeTest

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

..

Time: 0 seconds

OK (2 tests, 2 assertions)




                                22
Doubles


•   stub objects
•   mock objects




                   23
Stubs

•   isolates tests from external influences
    -   slow connections
    -   expensive and complex resources
•   replaces a “system under test” (SUT)
    -   for the purpose of testing



                         24
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
Testing StubTest

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

.

Time: 0 seconds

OK (1 test, 1 assertion)




                                26
Mocks

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




                          27
<?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
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
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
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
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
Testing BankAccount

$ phpunit BankAccountDBTestPHPUnit 3.3.15 by Sebastian Bergmann.

.....

Time: 0 seconds

OK (5 tests, 10 assertions)




                                33
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
Testing ZF App

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




                         35
<?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
Zend_Test_PHPUnit

•   Dispatching: $this->dispatch(‘/’);
•   Testing Controller:
    $this->assertController(‘index’);
•   Testing Action:
    $this->assertAction(‘index’);



                        37
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
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
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
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:
- 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
Questions ?

             Thank you

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

           Vote this talk
         http://joind.in/638



                 43
Ad

Recommended

Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
Continuous Quality Assurance
Continuous Quality Assurance
Michelangelo van Dam
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & Application
Jace Ju
 
深入淺出 MVC
深入淺出 MVC
Jace Ju
 
Kyiv.py #17 Flask talk
Kyiv.py #17 Flask talk
Alexey Popravka
 
Getting Started-with-Laravel
Getting Started-with-Laravel
Mindfire Solutions
 
Silex Cheat Sheet
Silex Cheat Sheet
Andréia Bohner
 
CodeIgniter 3.0
CodeIgniter 3.0
Phil Sturgeon
 
New in php 7
New in php 7
Vic Metcalfe
 
What's new with PHP7
What's new with PHP7
SWIFTotter Solutions
 
Filling the flask
Filling the flask
Jason Myers
 
Flask patterns
Flask patterns
it-people
 
Apigility reloaded
Apigility reloaded
Ralf Eggert
 
Flask SQLAlchemy
Flask SQLAlchemy
Eueung Mulyana
 
You must know about CodeIgniter Popular Library
You must know about CodeIgniter Popular Library
Bo-Yi Wu
 
Flask – Python
Flask – Python
Max Claus Nunes
 
Laravel Design Patterns
Laravel Design Patterns
Bobby Bouwmann
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
Michelangelo van Dam
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephp
SynapseindiaComplaints
 
Zero to SOLID
Zero to SOLID
Vic Metcalfe
 
Complex Sites with Silex
Complex Sites with Silex
Chris Tankersley
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
SWIFTotter Solutions
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
Lar21
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
wpnepal
 
ACL in CodeIgniter
ACL in CodeIgniter
mirahman
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
Alessandro Cucci
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
Michelangelo van Dam
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
Michelangelo van Dam
 

More Related Content

What's hot (20)

New in php 7
New in php 7
Vic Metcalfe
 
What's new with PHP7
What's new with PHP7
SWIFTotter Solutions
 
Filling the flask
Filling the flask
Jason Myers
 
Flask patterns
Flask patterns
it-people
 
Apigility reloaded
Apigility reloaded
Ralf Eggert
 
Flask SQLAlchemy
Flask SQLAlchemy
Eueung Mulyana
 
You must know about CodeIgniter Popular Library
You must know about CodeIgniter Popular Library
Bo-Yi Wu
 
Flask – Python
Flask – Python
Max Claus Nunes
 
Laravel Design Patterns
Laravel Design Patterns
Bobby Bouwmann
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
Michelangelo van Dam
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephp
SynapseindiaComplaints
 
Zero to SOLID
Zero to SOLID
Vic Metcalfe
 
Complex Sites with Silex
Complex Sites with Silex
Chris Tankersley
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
SWIFTotter Solutions
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
Lar21
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
wpnepal
 
ACL in CodeIgniter
ACL in CodeIgniter
mirahman
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
Alessandro Cucci
 
Filling the flask
Filling the flask
Jason Myers
 
Flask patterns
Flask patterns
it-people
 
Apigility reloaded
Apigility reloaded
Ralf Eggert
 
You must know about CodeIgniter Popular Library
You must know about CodeIgniter Popular Library
Bo-Yi Wu
 
Laravel Design Patterns
Laravel Design Patterns
Bobby Bouwmann
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
Michelangelo van Dam
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephp
SynapseindiaComplaints
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
SWIFTotter Solutions
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
Lar21
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
wpnepal
 
ACL in CodeIgniter
ACL in CodeIgniter
mirahman
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
Alessandro Cucci
 

Similar to Php Unit With Zend Framework Zendcon09 (20)

Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
Michelangelo van Dam
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
Michelangelo van Dam
 
Test in action week 2
Test in action week 2
Yi-Huan Chan
 
Fighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnit
James Fuller
 
Developer testing 101: Become a Testing Fanatic
Developer testing 101: Become a Testing Fanatic
LB Denker
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnit
Mindfire Solutions
 
Unit Testing using PHPUnit
Unit Testing using PHPUnit
varuntaliyan
 
PHPUnit: from zero to hero
PHPUnit: from zero to hero
Jeremy Cook
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
dpc
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards
Denis Ristic
 
Unit testing
Unit testing
davidahaskins
 
Test
Test
Eddie Kao
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
PHPunit and you
PHPunit and you
markstory
 
Php unit (eng)
Php unit (eng)
Anatoliy Okhotnikov
 
Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022
Mark Niebergall
 
Unit testing php-unit - phing - selenium_v2
Unit testing php-unit - phing - selenium_v2
Tricode (part of Dept)
 
Getting started-php unit
Getting started-php unit
mfrost503
 
Phpunit testing
Phpunit testing
Nikunj Bhatnagar
 
Variety of automated tests
Variety of automated tests
Артём Курапов
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
Michelangelo van Dam
 
Test in action week 2
Test in action week 2
Yi-Huan Chan
 
Fighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnit
James Fuller
 
Developer testing 101: Become a Testing Fanatic
Developer testing 101: Become a Testing Fanatic
LB Denker
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnit
Mindfire Solutions
 
Unit Testing using PHPUnit
Unit Testing using PHPUnit
varuntaliyan
 
PHPUnit: from zero to hero
PHPUnit: from zero to hero
Jeremy Cook
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
dpc
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards
Denis Ristic
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
PHPunit and you
PHPunit and you
markstory
 
Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022
Mark Niebergall
 
Unit testing php-unit - phing - selenium_v2
Unit testing php-unit - phing - selenium_v2
Tricode (part of Dept)
 
Getting started-php unit
Getting started-php unit
mfrost503
 
Ad

More from Michelangelo van Dam (20)

GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and default
Michelangelo van Dam
 
Moving from app services to azure functions
Moving from app services to azure functions
Michelangelo van Dam
 
Privacy by design
Privacy by design
Michelangelo van Dam
 
DevOps or DevSecOps
DevOps or DevSecOps
Michelangelo van Dam
 
Privacy by design
Privacy by design
Michelangelo van Dam
 
Continuous deployment 2.0
Continuous deployment 2.0
Michelangelo van Dam
 
Let your tests drive your code
Let your tests drive your code
Michelangelo van Dam
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's story
Michelangelo van Dam
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantage
Michelangelo van Dam
 
The road to php 7.1
The road to php 7.1
Michelangelo van Dam
 
Open source for a successful business
Open source for a successful business
Michelangelo van Dam
 
Decouple your framework now, thank me later
Decouple your framework now, thank me later
Michelangelo van Dam
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutes
Michelangelo van Dam
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heaven
Michelangelo van Dam
 
Getting hands dirty with php7
Getting hands dirty with php7
Michelangelo van Dam
 
Zf2 how arrays will save your project
Zf2 how arrays will save your project
Michelangelo van Dam
 
Create, test, secure, repeat
Create, test, secure, repeat
Michelangelo van Dam
 
The Continuous PHP Pipeline
The Continuous PHP Pipeline
Michelangelo van Dam
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
Michelangelo van Dam
 
Easily extend your existing php app with an api
Easily extend your existing php app with an api
Michelangelo van Dam
 
GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and default
Michelangelo van Dam
 
Moving from app services to azure functions
Moving from app services to azure functions
Michelangelo van Dam
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's story
Michelangelo van Dam
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantage
Michelangelo van Dam
 
Open source for a successful business
Open source for a successful business
Michelangelo van Dam
 
Decouple your framework now, thank me later
Decouple your framework now, thank me later
Michelangelo van Dam
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutes
Michelangelo van Dam
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heaven
Michelangelo van Dam
 
Zf2 how arrays will save your project
Zf2 how arrays will save your project
Michelangelo van Dam
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
Michelangelo van Dam
 
Easily extend your existing php app with an api
Easily extend your existing php app with an api
Michelangelo van Dam
 
Ad

Recently uploaded (20)

War_And_Cyber_3_Years_Of_Struggle_And_Lessons_For_Global_Security.pdf
War_And_Cyber_3_Years_Of_Struggle_And_Lessons_For_Global_Security.pdf
biswajitbanerjee38
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Alliance
 
June Patch Tuesday
June Patch Tuesday
Ivanti
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
Safe Software
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
Edge-banding-machines-edgeteq-s-200-en-.pdf
Edge-banding-machines-edgeteq-s-200-en-.pdf
AmirStern2
 
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Alliance
 
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Alliance
 
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Safe Software
 
High Availability On-Premises FME Flow.pdf
High Availability On-Premises FME Flow.pdf
Safe Software
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
War_And_Cyber_3_Years_Of_Struggle_And_Lessons_For_Global_Security.pdf
War_And_Cyber_3_Years_Of_Struggle_And_Lessons_For_Global_Security.pdf
biswajitbanerjee38
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Alliance
 
June Patch Tuesday
June Patch Tuesday
Ivanti
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
Safe Software
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
Edge-banding-machines-edgeteq-s-200-en-.pdf
Edge-banding-machines-edgeteq-s-200-en-.pdf
AmirStern2
 
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Alliance
 
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Alliance
 
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Safe Software
 
High Availability On-Premises FME Flow.pdf
High Availability On-Premises FME Flow.pdf
Safe Software
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 

Php Unit With Zend Framework Zendcon09

  • 1. PHPUnit and Zend Test ZendCon 2009, San Jose, CA
  • 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. Unit testing ? • test smallest piece of code (unit) • to verify its behavior is as expected • exceptions are thrown • code remains backwards compatible 3
  • 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. Why PHPUnit ? • part of xUnit family • ported by Sebastian Bergmann • PEAR package - pear channel-discover pear.phpunit.de - pear install phpunit/PHPUnit 5
  • 6. PHPUnit !== Atlassian Jira Just making sure ;-) 6
  • 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. <?php Run it require_once 'sayhello.php'; $hello = new SayHello(); echo $hello->speak(); // outputs Hello nobody! 8
  • 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. We’re good $ phpunit SayHelloTest PHPUnit 3.3.15 by Sebastian Bergmann. .. Time: 0 seconds OK (2 tests, 2 assertions) 10
  • 12. Test Driven Development • think about functionality • think about testable functionality • write functional tests • write functionality 12
  • 13. More testing • data providers (@dataProvider) • exception (@expectedException) • fixtures (setUp() and tearDown()) • doubles (mocks and stubs) • database testing 13
  • 14. Data Provider • provides arbitrary arguments - array - object (that implements Iterator) • annotated by @dataProvider provider • multiple arguments 14
  • 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. 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. Expected Exception • testing exceptions - that they are thrown - are properly catched 17
  • 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. Testing OopsTest # phpunit OopsTest OopsTest.php PHPUnit 3.3.2 by Sebastian Bergmann. . Time: 0 seconds OK (1 test, 0 assertions) 19
  • 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. <?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. Testing FixmeTest # phpunit FixmeTest FixmeTest.php PHPUnit 3.3.2 by Sebastian Bergmann. .. Time: 0 seconds OK (2 tests, 2 assertions) 22
  • 23. Doubles • stub objects • mock objects 23
  • 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. 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. Testing StubTest # phpunit StubTest StubTest.php PHPUnit 3.3.2 by Sebastian Bergmann. . Time: 0 seconds OK (1 test, 1 assertion) 26
  • 27. Mocks • simulated objects • mimics API or behaviour • in a controlled way • to test a real object 27
  • 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. 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. 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. 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. 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. Testing BankAccount $ phpunit BankAccountDBTestPHPUnit 3.3.15 by Sebastian Bergmann. ..... Time: 0 seconds OK (5 tests, 10 assertions) 33
  • 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. Testing ZF App • using ZF bootstrap • uses ZF autoloading • tests MVC controllers and views 35
  • 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. Zend_Test_PHPUnit • Dispatching: $this->dispatch(‘/’); • Testing Controller: $this->assertController(‘index’); • Testing Action: $this->assertAction(‘index’); 37
  • 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. 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. 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. NOTICE No elePHPants were harmed while performing these tests 41
  • 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. Questions ? Thank you This presentation will be available on http://slideshare.com/DragonBe Vote this talk http://joind.in/638 43