SlideShare une entreprise Scribd logo
1  sur  49
Télécharger pour lire hors ligne
Introduction to Unit Testing with PHPUnit
           by Michelangelo van Dam
Contents
✓Who am I ?                  ✓Expected Exceptions
✓What is Unit                ✓Fixtures
Testing ?                    ✓Doubles
✓Unit Testing in short       ✓Stubs
✓Why do Testing ?            ✓Mocks
✓SimpleTest                  ✓Database Testing
✓PHPUnit                     ✓Zend_Test
✓Starting w/ PHPUnit         ✓Interesting Readings
✓Example                     ✓Questions ?
✓More Testing
✓Data Provider

                         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




                      3
What is Unit Testing ?


Wikipedia: “is a method of testing that verifies
the individual units of source code are working
properly”




                      4
Unit Testing in short
•   unit: the smallest testable code of an app
    -   procedural: function or procedure
    -   OOP: a method
•   test: code that checks code on
    -   functional behavior
        ✓ expected results
        ✓ unexpected failures

                         5
Why do (Unit) Testing ?

•   automated testing
•   test code on functionality
•   detect issues that break existing code
•   progress indication of the project
•   alerts generation for monitoring tools



                        6
SimpleTest

•   comparable to JUnit/PHPUnit
•   created by Marcus Baker
•   popular for testing web pages at browser
    level




                       7
PHPUnit

•   Part of xUnit familiy (JUnit, SUnit,...)
•   created by Sebastian Bergmann
•   integrated/supported
    -   Zend Studio
    -   Zend Framework



                         8
Starting with PHPUnit
Installation is done with the PEAR installer

# pear channel-discover pear.phpunit.de
# pear install phpunit/PHPUnit

Upgrading is as simple
# pear upgrade phpunit/PHPUnit



                        9
Hello World
<?php
class HelloWorld
{
    public $helloWorld;

    public function __construct($string = ‘Hello World!’)
    {
        $this->helloWorld = $string;
    }

    public function sayHello()
    {
        return $this->helloWorld;
    }
}




                                           10
<?php
       Test HelloWorld class
require_once 'HelloWorld.php';
require_once 'PHPUnit/Framework.php';

class HelloWorldTest extends PHPUnit_Framework_TestCase
{
    public function test__construct()
    {
        $hw = new HelloWorld();
        $this->assertType('HelloWorld', $hw);
    }

    public function testSayHello()
    {
        $hw = new HelloWorld();
        $string = $hw->sayHello();
        $this->assertEquals('Hello World!', $string);
    }
}




                                11
Testing HelloWorld

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

..

Time: 0 seconds

OK (2 tests, 2 assertions)




                                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
CombineTest
<?php
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
FixmeTest
<?php
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
ObserverTest
<?php
// 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 class 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/BankAccount/BankAccount.php




                                                    30
BankAccount
<?php
require_once 'BankAccountException.php';

class BankAccount
{
    private $balance = 0;

   public function getBalance()
   {
       return $this->balance;
   }

   public function setBalance($balance)
   {
       if ($balance >= 0) {
           $this->balance = $balance;
       } else {
           throw new BankAccountException;
       }
   }

   ...




                                             31
BankAccount (2)
    ...

    public function depositMoney($balance)
    {
        $this->setBalance($this->getBalance() + $balance);
        return $this->getBalance();
    }

    public function withdrawMoney($balance)
    {
        $this->setBalance($this->getBalance() - $balance);
        return $this->getBalance();
    }
}

<?php
class BankAccountException extends RuntimeException { }




                                           32
<?php
                BankAccountTest
require_once 'PHPUnit/Extensions/Database/TestCase.php';
require_once 'BankAccount.php';

class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase
{
    protected $pdo;

    public function __construct()
    {
        $this->pdo = new PDO('sqlite::memory:');
        BankAccount::createTable($this->pdo);
    }

    protected function getConnection()
    {
        return $this->createDefaultDBConnection($this->pdo, 'sqlite');
    }

    protected function getDataSet()
    {
        return $this->createFlatXMLDataSet(
            dirname(__FILE__) . '/BankAccounts.xml');
    }

    ...




                                           33
BankAccountTest (2)

    ...

    public function testNewAccountCreation()
    {
        $bank_account = new BankAccount('12345678912345678', $this->pdo);
        $xml_dataset = $this->createFlatXMLDataSet(
            dirname(__FILE__) . '/NewBankAccounts.xml');
        $this->assertDataSetsEqual(
                $xml_dataset, $this->getConnection()->createDataSet()
        );
    }
}




                                           34
Testing BankAccount
# phpunit BankAccountDbTest BankAccountDbTest.php PHPUnit 3.3.2 by
Sebastian Bergmann.

F

Time: 0 seconds

There was 1 failure:

...




                                35
Testing BA (2)
...
1) testNewAccountCreation(BankAccountDBTest)
Failed asserting that actual
+----------------------+----------------------+
| bank_account                                |
+----------------------+----------------------+
|    account_number    |       balance        |
+----------------------+----------------------+
| 12345678912345678    |          0           |
+----------------------+----------------------+
| 12348612357236185    |          89          |
+----------------------+----------------------+
| 15934903649620486    |         100          |
+----------------------+----------------------+
| 15936487230215067    |         1216         |
+----------------------+----------------------+




                                36
...
                Testing BA (3)
is equal to expected
+----------------------+----------------------+
| bank_account                                |
+----------------------+----------------------+
|    account_number    |       balance        |
+----------------------+----------------------+
| 15934903649620486    |        100.00        |
+----------------------+----------------------+
| 15936487230215067    |       1216.00        |
+----------------------+----------------------+
| 12348612357236185    |        89.00         |
+----------------------+----------------------+

 Reason: Expected row count of 3, has a row count of 4
/root/dev/phpunittutorial/BankAccountDbTest.php:33

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.



                                37
BankAccount Dataset

<!-- file: BankAccounts.xml -->
<dataset>
    <bank_account account_number=quot;15934903649620486quot; balance=quot;100.00quot; />
    <bank_account account_number=quot;15936487230215067quot; balance=quot;1216.00quot; />
    <bank_account account_number=quot;12348612357236185quot; balance=quot;89.00quot; />
</dataset>




                                           38
Testing MVC ZF apps

•   Available from Zend Framework 1.6
•   Using Zend_Test
    http://framework.zend.com/manual/en/zend.test.html


•   Requests and Responses are mocked




                                      39
Hints & Tips
•   Make sure auto loading is set up
    -   your tests might fail on not finding classes
•   Move bootstrap to a plugin
    -   allows to PHP callback the bootstrap
    -   allows to specify environment succinctly
    -   allows to bootstrap application in a 1 line


                         40
Defining the bootstrap
/**
  * default way to approach the bootstrap
  */
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
     public $bootstrap = '/path/to/bootstrap.php';

    // ...
}


/**
  * Using PHP callback
  */
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
     public $bootstrap = array('App', 'bootstrap');

    // ...
}




                                           41
Testing homepage

class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    // ...

    public function testHomePage()
    {
        $this->dispatch('/');
        // ...
    }
}




                                           42
Testing GET params
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    // ...

    public function testGetActionShouldReceiveGetParams()
    {
        // Set GET variables:
        $this->request->setQuery(array(
            'foo' => 'bar',
            'bar' => 'baz',
        ));
    }

    // ...
}




                                           43
Testing POST params
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    // ...

    public function testPostActionShouldReceivePostParams()
    {
        // Set POST variables:
        $this->request->setPost(array(
            'foo' => 'bar',
            'bar' => 'baz',
        ));
    }

    // ...
}




                                           44
Testing COOKIE params
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    // ...

    public function testCookieActionShouldReceiveCookieParams()
    {
        // First set a cookie value
        $this->request->setCookie('username', 'DragonBe');

        // Or set multiple cookies at once
        $this->request->setCookies(array(
            'last_seen' => time(),
            'userlevel' => 'Admin',
        ));
    }

    // ...
}




                                             45
Let’s dispatch it
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    // ...

    public function testCookieActionShouldReceiveCookieParams()
    {
        // First set a cookie value
        $this->request->setCookie('username', 'DragonBe');

        // Or set multiple cookies at once
        $this->request->setCookies(array(
            'last_seen' => time(),
            'userlevel' => 'Admin',
        ));

        // Let’s define the request method
        $this->request->setMethod('POST');

        // Dispatch the homepage
        $this->dispatch('/');
    }

    // ...
}




                                             46
Demo

•   Using Zend Framework “QuickStart” app
    http://framework.zend.com/docs/quickstart


    -   modified with
        ✓ detail entry
•   Downloads provided on
    http://mvandam.com/demos/zftest.zip




                                      47
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


•   Zend Framework Manual: Zend_Test
    http://framework.zend.com/manual/en/zend.test.phpunit.html




                                      48
Questions ?


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




                 49

Contenu connexe

Tendances

Unit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesUnit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesDerek Smith
 
Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014Ippon
 
TestNG Session presented in PB
TestNG Session presented in PBTestNG Session presented in PB
TestNG Session presented in PBAbhishek Yadav
 
Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An IntroductionSam Brannen
 
Setting up Page Object Model in Automation Framework
Setting up Page Object Model in Automation FrameworkSetting up Page Object Model in Automation Framework
Setting up Page Object Model in Automation Frameworkvaluebound
 
Testing in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkTesting in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkArulalan T
 
Unit tests & TDD
Unit tests & TDDUnit tests & TDD
Unit tests & TDDDror Helper
 
Page Object Model and Implementation in Selenium
Page Object Model and Implementation in Selenium  Page Object Model and Implementation in Selenium
Page Object Model and Implementation in Selenium Zoe Gilbert
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first stepsRenato Primavera
 
Robot Framework :: Demo login application
Robot Framework :: Demo login applicationRobot Framework :: Demo login application
Robot Framework :: Demo login applicationSomkiat Puisungnoen
 

Tendances (20)

Unit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesUnit Testing Concepts and Best Practices
Unit Testing Concepts and Best Practices
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
TestNG Framework
TestNG Framework TestNG Framework
TestNG Framework
 
testng
testngtestng
testng
 
Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014
 
TestNG Session presented in PB
TestNG Session presented in PBTestNG Session presented in PB
TestNG Session presented in PB
 
TestNG
TestNGTestNG
TestNG
 
Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An Introduction
 
Setting up Page Object Model in Automation Framework
Setting up Page Object Model in Automation FrameworkSetting up Page Object Model in Automation Framework
Setting up Page Object Model in Automation Framework
 
Testing in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkTesting in-python-and-pytest-framework
Testing in-python-and-pytest-framework
 
Unit tests & TDD
Unit tests & TDDUnit tests & TDD
Unit tests & TDD
 
Java Unit Testing
Java Unit TestingJava Unit Testing
Java Unit Testing
 
Junit
JunitJunit
Junit
 
Junit
JunitJunit
Junit
 
Page Object Model and Implementation in Selenium
Page Object Model and Implementation in Selenium  Page Object Model and Implementation in Selenium
Page Object Model and Implementation in Selenium
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
JUnit Presentation
JUnit PresentationJUnit Presentation
JUnit Presentation
 
Unit Test
Unit TestUnit Test
Unit Test
 
API Testing
API TestingAPI Testing
API Testing
 
Robot Framework :: Demo login application
Robot Framework :: Demo login applicationRobot Framework :: Demo login application
Robot Framework :: Demo login application
 

Similaire à Introduction to Unit Testing with PHPUnit

Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09Michelangelo van Dam
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmanndpc
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)ENDelt260
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboardsDenis Ristic
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnitvaruntaliyan
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnitJace Ju
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEnterprise PHP Center
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentationThanh Robi
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Commencer avec le TDD
Commencer avec le TDDCommencer avec le TDD
Commencer avec le TDDEric Hogue
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Eric Hogue
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and youmarkstory
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Mark Niebergall
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdfHans Jones
 

Similaire à Introduction to Unit Testing with PHPUnit (20)

PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
 
Php unit (eng)
Php unit (eng)Php unit (eng)
Php unit (eng)
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
Phpunit
PhpunitPhpunit
Phpunit
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Commencer avec le TDD
Commencer avec le TDDCommencer avec le TDD
Commencer avec le TDD
 
Unit testing
Unit testingUnit testing
Unit testing
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
 

Plus de Michelangelo van Dam

GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultGDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultMichelangelo van Dam
 
Moving from app services to azure functions
Moving from app services to azure functionsMoving from app services to azure functions
Moving from app services to azure functionsMichelangelo van Dam
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyGeneral Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyMichelangelo van Dam
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageLeveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageMichelangelo van Dam
 
Open source for a successful business
Open source for a successful businessOpen source for a successful business
Open source for a successful businessMichelangelo van Dam
 
Decouple your framework now, thank me later
Decouple your framework now, thank me laterDecouple your framework now, thank me later
Decouple your framework now, thank me laterMichelangelo van Dam
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesDeploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesMichelangelo van Dam
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heavenAzure and OSS, a match made in heaven
Azure and OSS, a match made in heavenMichelangelo van Dam
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your projectMichelangelo van Dam
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
Easily extend your existing php app with an api
Easily extend your existing php app with an apiEasily extend your existing php app with an api
Easily extend your existing php app with an apiMichelangelo van Dam
 

Plus de Michelangelo van Dam (20)

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

Dernier

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 

Dernier (20)

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 

Introduction to Unit Testing with PHPUnit

  • 1. Introduction to Unit Testing with PHPUnit by Michelangelo van Dam
  • 2. Contents ✓Who am I ? ✓Expected Exceptions ✓What is Unit ✓Fixtures Testing ? ✓Doubles ✓Unit Testing in short ✓Stubs ✓Why do Testing ? ✓Mocks ✓SimpleTest ✓Database Testing ✓PHPUnit ✓Zend_Test ✓Starting w/ PHPUnit ✓Interesting Readings ✓Example ✓Questions ? ✓More Testing ✓Data Provider 2
  • 3. 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 3
  • 4. What is Unit Testing ? Wikipedia: “is a method of testing that verifies the individual units of source code are working properly” 4
  • 5. Unit Testing in short • unit: the smallest testable code of an app - procedural: function or procedure - OOP: a method • test: code that checks code on - functional behavior ✓ expected results ✓ unexpected failures 5
  • 6. Why do (Unit) Testing ? • automated testing • test code on functionality • detect issues that break existing code • progress indication of the project • alerts generation for monitoring tools 6
  • 7. SimpleTest • comparable to JUnit/PHPUnit • created by Marcus Baker • popular for testing web pages at browser level 7
  • 8. PHPUnit • Part of xUnit familiy (JUnit, SUnit,...) • created by Sebastian Bergmann • integrated/supported - Zend Studio - Zend Framework 8
  • 9. Starting with PHPUnit Installation is done with the PEAR installer # pear channel-discover pear.phpunit.de # pear install phpunit/PHPUnit Upgrading is as simple # pear upgrade phpunit/PHPUnit 9
  • 10. Hello World <?php class HelloWorld { public $helloWorld; public function __construct($string = ‘Hello World!’) { $this->helloWorld = $string; } public function sayHello() { return $this->helloWorld; } } 10
  • 11. <?php Test HelloWorld class require_once 'HelloWorld.php'; require_once 'PHPUnit/Framework.php'; class HelloWorldTest extends PHPUnit_Framework_TestCase { public function test__construct() { $hw = new HelloWorld(); $this->assertType('HelloWorld', $hw); } public function testSayHello() { $hw = new HelloWorld(); $string = $hw->sayHello(); $this->assertEquals('Hello World!', $string); } } 11
  • 12. Testing HelloWorld # phpunit HelloWorldTest HelloWorldTest.php PHPUnit 3.3.2 by Sebastian Bergmann. .. Time: 0 seconds OK (2 tests, 2 assertions) 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. CombineTest <?php 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. FixmeTest <?php 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. ObserverTest <?php // 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 class 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/BankAccount/BankAccount.php 30
  • 31. BankAccount <?php require_once 'BankAccountException.php'; class BankAccount { private $balance = 0; public function getBalance() { return $this->balance; } public function setBalance($balance) { if ($balance >= 0) { $this->balance = $balance; } else { throw new BankAccountException; } } ... 31
  • 32. BankAccount (2) ... public function depositMoney($balance) { $this->setBalance($this->getBalance() + $balance); return $this->getBalance(); } public function withdrawMoney($balance) { $this->setBalance($this->getBalance() - $balance); return $this->getBalance(); } } <?php class BankAccountException extends RuntimeException { } 32
  • 33. <?php BankAccountTest require_once 'PHPUnit/Extensions/Database/TestCase.php'; require_once 'BankAccount.php'; class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase { protected $pdo; public function __construct() { $this->pdo = new PDO('sqlite::memory:'); BankAccount::createTable($this->pdo); } protected function getConnection() { return $this->createDefaultDBConnection($this->pdo, 'sqlite'); } protected function getDataSet() { return $this->createFlatXMLDataSet( dirname(__FILE__) . '/BankAccounts.xml'); } ... 33
  • 34. BankAccountTest (2) ... public function testNewAccountCreation() { $bank_account = new BankAccount('12345678912345678', $this->pdo); $xml_dataset = $this->createFlatXMLDataSet( dirname(__FILE__) . '/NewBankAccounts.xml'); $this->assertDataSetsEqual( $xml_dataset, $this->getConnection()->createDataSet() ); } } 34
  • 35. Testing BankAccount # phpunit BankAccountDbTest BankAccountDbTest.php PHPUnit 3.3.2 by Sebastian Bergmann. F Time: 0 seconds There was 1 failure: ... 35
  • 36. Testing BA (2) ... 1) testNewAccountCreation(BankAccountDBTest) Failed asserting that actual +----------------------+----------------------+ | bank_account | +----------------------+----------------------+ | account_number | balance | +----------------------+----------------------+ | 12345678912345678 | 0 | +----------------------+----------------------+ | 12348612357236185 | 89 | +----------------------+----------------------+ | 15934903649620486 | 100 | +----------------------+----------------------+ | 15936487230215067 | 1216 | +----------------------+----------------------+ 36
  • 37. ... Testing BA (3) is equal to expected +----------------------+----------------------+ | bank_account | +----------------------+----------------------+ | account_number | balance | +----------------------+----------------------+ | 15934903649620486 | 100.00 | +----------------------+----------------------+ | 15936487230215067 | 1216.00 | +----------------------+----------------------+ | 12348612357236185 | 89.00 | +----------------------+----------------------+ Reason: Expected row count of 3, has a row count of 4 /root/dev/phpunittutorial/BankAccountDbTest.php:33 FAILURES! Tests: 1, Assertions: 1, Failures: 1. 37
  • 38. BankAccount Dataset <!-- file: BankAccounts.xml --> <dataset> <bank_account account_number=quot;15934903649620486quot; balance=quot;100.00quot; /> <bank_account account_number=quot;15936487230215067quot; balance=quot;1216.00quot; /> <bank_account account_number=quot;12348612357236185quot; balance=quot;89.00quot; /> </dataset> 38
  • 39. Testing MVC ZF apps • Available from Zend Framework 1.6 • Using Zend_Test http://framework.zend.com/manual/en/zend.test.html • Requests and Responses are mocked 39
  • 40. Hints & Tips • Make sure auto loading is set up - your tests might fail on not finding classes • Move bootstrap to a plugin - allows to PHP callback the bootstrap - allows to specify environment succinctly - allows to bootstrap application in a 1 line 40
  • 41. Defining the bootstrap /** * default way to approach the bootstrap */ class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { public $bootstrap = '/path/to/bootstrap.php'; // ... } /** * Using PHP callback */ class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { public $bootstrap = array('App', 'bootstrap'); // ... } 41
  • 42. Testing homepage class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testHomePage() { $this->dispatch('/'); // ... } } 42
  • 43. Testing GET params class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testGetActionShouldReceiveGetParams() { // Set GET variables: $this->request->setQuery(array( 'foo' => 'bar', 'bar' => 'baz', )); } // ... } 43
  • 44. Testing POST params class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testPostActionShouldReceivePostParams() { // Set POST variables: $this->request->setPost(array( 'foo' => 'bar', 'bar' => 'baz', )); } // ... } 44
  • 45. Testing COOKIE params class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testCookieActionShouldReceiveCookieParams() { // First set a cookie value $this->request->setCookie('username', 'DragonBe'); // Or set multiple cookies at once $this->request->setCookies(array( 'last_seen' => time(), 'userlevel' => 'Admin', )); } // ... } 45
  • 46. Let’s dispatch it class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testCookieActionShouldReceiveCookieParams() { // First set a cookie value $this->request->setCookie('username', 'DragonBe'); // Or set multiple cookies at once $this->request->setCookies(array( 'last_seen' => time(), 'userlevel' => 'Admin', )); // Let’s define the request method $this->request->setMethod('POST'); // Dispatch the homepage $this->dispatch('/'); } // ... } 46
  • 47. Demo • Using Zend Framework “QuickStart” app http://framework.zend.com/docs/quickstart - modified with ✓ detail entry • Downloads provided on http://mvandam.com/demos/zftest.zip 47
  • 48. 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 • Zend Framework Manual: Zend_Test http://framework.zend.com/manual/en/zend.test.phpunit.html 48
  • 49. Questions ? Thank you. This presentation will be available on http://slideshare.com/DragonBe 49