SlideShare una empresa de Scribd logo
1 de 49
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

Spring Core
Spring CoreSpring Core
Spring Core
 
JUnit 5
JUnit 5JUnit 5
JUnit 5
 
Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An Introduction
 
Junit
JunitJunit
Junit
 
Use Node.js to create a REST API
Use Node.js to create a REST APIUse Node.js to create a REST API
Use Node.js to create a REST API
 
Spring security
Spring securitySpring security
Spring security
 
Introduction to spring boot
Introduction to spring bootIntroduction to spring boot
Introduction to spring boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
 
PHPUnit - Unit testing
PHPUnit - Unit testingPHPUnit - Unit testing
PHPUnit - Unit testing
 
Introduction to Selenium Web Driver
Introduction to Selenium Web DriverIntroduction to Selenium Web Driver
Introduction to Selenium Web Driver
 
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and MockitoAn Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
 
Les dessous du framework spring
Les dessous du framework springLes dessous du framework spring
Les dessous du framework spring
 
NodeJS - Server Side JS
NodeJS - Server Side JS NodeJS - Server Side JS
NodeJS - Server Side JS
 
Testing in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkTesting in-python-and-pytest-framework
Testing in-python-and-pytest-framework
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Introduction to Node js
Introduction to Node jsIntroduction to Node js
Introduction to Node js
 
JUnit Presentation
JUnit PresentationJUnit Presentation
JUnit Presentation
 
Testes pythonicos com pytest
Testes pythonicos com pytestTestes pythonicos com pytest
Testes pythonicos com pytest
 

Similar a Introduction to Unit Testing with PHPUnit

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
dpc
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
varuntaliyan
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
Jace 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 Purnama
Enterprise PHP Center
 

Similar a 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
 

Más de Michelangelo 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 project
Michelangelo van Dam
 

Más 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
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 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