SlideShare uma empresa Scribd logo
1 de 92
Baixar para ler offline
watch -n 15 -d 
   find tests/ -mmin -1 -iname '"*.php"' -exec 
   'phpunit -c tests/phpunit.xml {} ;'
➡
➡
➡
➡
library
!"" Controller.php
!"" Response.php
!"" Request.php
!"" View.php
#
!"" Request
#   $"" Http.php
!"" Response
#   $"" Http.php
!"" Test
#   $"" ControllerTestCase.php
$"" View
     $"" Html.php
project
!"" application
#   !"" controllers
#   #   $"" IndexController.php
#   !"" models
#   #   $"" Todo.php
#   $"" views
#       $"" index.phtml
$"" tests
    !"" application
    #   !"" controllers
    #   #   $"" IndexControllerTest.php
    #   !"" models
    #   #   $"" TodoTest.php
    #   $"" views
    #       $"" InterfaceTest.php
    !"" bootstrap.php
    $"" phpunit.xml
CREATE DATABASE `testing` CHARSET=utf8;
USE `testing`;

CREATE TABLE `todo` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '        ',
  `task` varchar(100) NOT NULL COMMENT '   ',
  `done` enum('y','n') NOT NULL DEFAULT 'n' COMMENT '       ',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Todo';
<phpunit colors="true" bootstrap="./bootstrap.php">
  <testsuite name="Application Test Suite">
    <directory>./application</directory>
  </testsuite>
  <testsuite name="Library Test Suite">
    <directory>./library</directory>
  </testsuite>
  <php>
    <var name="DB_DSN" value="mysql:dbname=testing;host=127.0.0.1" />
    <var name="DB_USER" value="username" />
    <var name="DB_PASSWD" value="password" />
  </php>
</phpunit>
➡ fetchAll()
➡ add($task)
➡ done($id)
<?php                                         <?php

class TodoTest extends                        class Todo
    PHPUnit_Framework_TestCase                {
{                                                 protected static $_pdo = null;
    private $_pdo = null;                         
                                                  public static function setDb(PDO $pdo)
    private $_todo = null;                        {
                                                      self::$_pdo = $pdo;
    public function setUp()                       }
    {
        $this->_pdo = new PDO(
                $GLOBALS['DB_DSN'],
                $GLOBALS['DB_USER'],
                $GLOBALS['DB_PASSWD']);
        $this->_pdo
            ->query('TRUNCATE TABLE todo');

        Todo::setDb($this->_pdo);
        $this->_todo = new Todo();
    }

    public function tearDown()
    {
        $this->_pdo
            ->query('TRUNCATE TABLE todo');
    }
public function testAdd()                 public function add($task)
{                                         {
    $this->assertEquals(                      $query = 'INSERT INTO todo (task) '
        1,                                           . 'VALUES (?)';
        $this->_todo->add('Task 1')
    );                                        self::$_pdo->prepare($query)
                                                  ->execute(array($task));
    $this->assertEquals(
        2,                                    return self::$_pdo->lastInsertId();
        $this->_todo->add('Task 2')       }
    );                                    
}
public function testFetchAll()                  public function fetchAll()
{                                               {
    $this->_todo->add('Task 1', 'm');               $query = 'SELECT * FROM todo';
    $this->_todo->add('Task 2', 'f');               $stmt  = self::$_pdo
                                                        ->query($query);
    $result = $this->_todo->fetchAll();
                                                  return $stmt
    $this->assertEquals(                              ->fetchAll(PDO::FETCH_ASSOC);
        2,                                    }
        count($result)
    );

    $this->assertContains(
       'Task 1',
        $result[0]
    );

    $this->assertContains(
       'Task 2',
        $result[1]
    );
}
public function testDone()             public function done($id)
    {                                      {
        $this->_todo->add('Task 1');           $query = 'UPDATE todo '
        $this->_todo->add('Task 2');                  . 'SET done = 'y''
                                                      . 'WHERE id = ?';
        $this->assertEquals(                   $stmt  = self::$_pdo->prepare($query);
            1,
            $this->_todo->done(1)              $stmt->execute(array($id));
        );
                                               return $stmt->rowCount();
        $this->assertEquals(               }
            1,                         }
            $this->_todo->done(2)
        );

        $this->assertEquals(
            0,
            $this->_todo->done(3)
        );
    }
}
➡	 
➡
➡
➡
➡
➡
<?php

class InterfaceTest extends PHPUnit_Extensions_SeleniumTestCase
{

    protected function setUp()
    {
        $this->setBrowser("*chrome");
        $this->setBrowserUrl("http://test.dev/");
    }

    public function testMyTestCase()
    {
        $this->open("/advanced_php_testing/mvc/");
        $this->type("id=new-todo", "Task 1");
        $this->keyPress("id=new-todo", "13");
        $this->waitForPageToLoad("30000");
        $this->assertEquals("Task 1",
            $this->getText("//ul[@id='todo-list']/div[1]/div/div"));
        $this->type("id=new-todo", "Task 2");
        $this->keyPress("id=new-todo", "13");
        $this->waitForPageToLoad("30000");
        $this->assertEquals("Task 2",
            $this->getText("//ul[@id='todo-list']/div[2]/div/div"));
    }
}
<?php

class InterfaceTest extends PHPUnit_Extensions_SeleniumTestCase
{

    protected function setUp()
    {
        $this->_pdo = new PDO(
                        $GLOBALS['DB_DSN'],
                        $GLOBALS['DB_USER'],
                        $GLOBALS['DB_PASSWD']);
        $this->_pdo->query('TRUNCATE TABLE todo');

        Todo::setDb($this->_pdo);
        $this->_todo = new Todo();

        $this->setBrowser("*chrome");
        $this->setBrowserUrl("http://test.dev/");
    }
<?php

class Request
{
    protected $_headers = array(
        'REQUEST_METHOD' => 'GET',
    );

    public function setHeader($name, $value)
    {
        $this->_headers[$name] = $value;
    }

    public function isPost()
    {
        return ('POST' === $this->_headers['REQUEST_METHOD']);
    }

    public function isAjax()
    {
        return ('XMLHttpRequest' === $this->_headers['X_REQUESTED_WITH']);
    }
<?php

class Request_Http extends Request
{
    public function isPost()
    {
        return ('POST' === $_SERVER['REQUEST_METHOD']);
    }

    public function isAjax()
    {
        return ('XMLHttpRequest' === $_SERVER['X_REQUESTED_WITH']);
    }
}
<?php

class Response
{
    protected $_headers = array(
        'Content-Type' => 'text/html; charset=utf-8',
    );

    public function setHeader($name, $content)
    {
        $this->_headers[$name] = $content;
    }

    public function getHeader($name)
    {
        return isset($this->_headers[$name])
             ? $this->_headers[$name]
             : null;
    }

    protected function sendHeaders()
    {
        // do nothing
    }
$controller = new IndexController(new Todo());
$controller->setRequest(new Request_Http())
        ->setResponse(new Response_Http())
        ->sendResponse(true)
        ->dispatch();




$controller = new IndexController(new Todo());
$controller->setRequest(new Request())
        ->setResponse(new Response())
        ->dispatch();
<?php

class Test_ControllerTestCase extends PHPUnit_Framework_TestCase
{
    protected $_controller = null;

    protected $_request = null;

    protected $_response = null;

    public function setUp()
    {
        $this->_controller->setRequest($this->_request)
                            ->setResponse($this->_response);
    }

    public function dispatch($url)
    {
        $this->_parseUrl($url);
        $this->_controller->dispatch();
        return $this;
    }

    protected function _parseUrl($url)
    {
        $urlInfo = parse_url($url);
        if (isset($urlInfo['query'])) {
            parse_str($urlInfo['query'], $_GET);
        }
    }
➡ assertAction($action)
➡ assertResponseCode($code)
➡ assertRedirectTo($url)
<?php

class IndexControllerTest extends Test_ControllerTestCase
{
    public function setUp()
    {
        $todo = new Todo();
        $this->_request = new Request();
        $this->_response = new Response();
        $this->_controller = new IndexController($todo);
        parent::setUp();
    }

    public function tearDown()
    {
        $this->_request->reset();
        $this->_response->reset();
    }

    public function testHome()
    {
        $this->dispatch('/');
        $this->assertAction('index')
                ->assertResponseCode(200);
    }
<?php

class IndexControllerTest extends Test_ControllerTestCase
{
    public function setUp()
    {
        $todo = $this->_setUpTodo();
        $this->_controller = new IndexController($todo);
        // ...
    }

    protected function _setUpTodo()
    {
        $todo = Phake::mock('Todo');
        Phake::when($todo)->fetchAll()->thenReturn(array(
            array(
                'id' => 1,
                'task' => 'Task 1',
                'done' => 'n',
            ),
        ));
        return $todo;
    }
➡ assertQuery($selector)
➡ assertQueryContain($selector, $text)
<?php

class IndexControllerTest extends Test_ControllerTestCase
{
    // ...

    public function testHome()
    {
        $this->dispatch('/');
        $this->assertAction('index')
                ->assertResponseCode(200)
                ->assertQuery('#todo-list');
    }

    public function testAdd()
    {
        $this->_request->setMethod('POST');
        $_POST['task'] = 'Task 1';
        $this->dispatch('/?act=add')
                ->assertAction('add')
                ->assertRedirectTo('./')
                ->assertResponseCode(200)
                ->assertQueryContain(
                    '#todo-list>.todo>.display>.todo-text',
                    'Task 1'
                );
    }
➡

➡

➡
➡	               	 


➡	              	 


➡	    	               	 
                           	 
➡
Advanced php testing in action
Advanced php testing in action

Mais conteúdo relacionado

Mais procurados

Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128PrinceGuru MS
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5 Wildan Maulana
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2zfconfua
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにYuya Takeyama
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в MagentoMagecom Ukraine
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Fabien Potencier
 

Mais procurados (20)

Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 

Destaque

PHPUnit 入門介紹
PHPUnit 入門介紹PHPUnit 入門介紹
PHPUnit 入門介紹Jace Ju
 
Refactoring with Patterns in PHP
Refactoring with Patterns in PHPRefactoring with Patterns in PHP
Refactoring with Patterns in PHPJace Ju
 
第一次用 PHPUnit 寫測試就上手
第一次用 PHPUnit 寫測試就上手第一次用 PHPUnit 寫測試就上手
第一次用 PHPUnit 寫測試就上手Yi-Ming Huang
 
PHP 防駭 - 基礎觀念篇
PHP 防駭 - 基礎觀念篇PHP 防駭 - 基礎觀念篇
PHP 防駭 - 基礎觀念篇Jace Ju
 
Php Security By Mugdha And Anish
Php Security By Mugdha And AnishPhp Security By Mugdha And Anish
Php Security By Mugdha And AnishOSSCube
 
PHP Advanced
PHP AdvancedPHP Advanced
PHP AdvancedNoveo
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Michelangelo van Dam
 
Advanced PHP Web Development Tools in 2015
Advanced PHP Web Development Tools in 2015Advanced PHP Web Development Tools in 2015
Advanced PHP Web Development Tools in 2015iScripts
 
PHP 物件導向 - 基礎觀念篇
PHP 物件導向 - 基礎觀念篇PHP 物件導向 - 基礎觀念篇
PHP 物件導向 - 基礎觀念篇Jace Ju
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingJace Ju
 
Advanced PHP: Design Patterns - Dennis-Jan Broerse
Advanced PHP: Design Patterns - Dennis-Jan BroerseAdvanced PHP: Design Patterns - Dennis-Jan Broerse
Advanced PHP: Design Patterns - Dennis-Jan Broersedpc
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHPBradley Holt
 
PHP Powerpoint -- Teach PHP with this
PHP Powerpoint -- Teach PHP with thisPHP Powerpoint -- Teach PHP with this
PHP Powerpoint -- Teach PHP with thisIan Macali
 

Destaque (17)

PHPUnit 入門介紹
PHPUnit 入門介紹PHPUnit 入門介紹
PHPUnit 入門介紹
 
Refactoring with Patterns in PHP
Refactoring with Patterns in PHPRefactoring with Patterns in PHP
Refactoring with Patterns in PHP
 
第一次用 PHPUnit 寫測試就上手
第一次用 PHPUnit 寫測試就上手第一次用 PHPUnit 寫測試就上手
第一次用 PHPUnit 寫測試就上手
 
PHP 防駭 - 基礎觀念篇
PHP 防駭 - 基礎觀念篇PHP 防駭 - 基礎觀念篇
PHP 防駭 - 基礎觀念篇
 
Php Security By Mugdha And Anish
Php Security By Mugdha And AnishPhp Security By Mugdha And Anish
Php Security By Mugdha And Anish
 
PHP Advanced
PHP AdvancedPHP Advanced
PHP Advanced
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010
 
Advanced PHP Simplified
Advanced PHP SimplifiedAdvanced PHP Simplified
Advanced PHP Simplified
 
Advanced PHP Web Development Tools in 2015
Advanced PHP Web Development Tools in 2015Advanced PHP Web Development Tools in 2015
Advanced PHP Web Development Tools in 2015
 
PHP 物件導向 - 基礎觀念篇
PHP 物件導向 - 基礎觀念篇PHP 物件導向 - 基礎觀念篇
PHP 物件導向 - 基礎觀念篇
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
 
DIWE - Advanced PHP Concepts
DIWE - Advanced PHP ConceptsDIWE - Advanced PHP Concepts
DIWE - Advanced PHP Concepts
 
Advanced PHP: Design Patterns - Dennis-Jan Broerse
Advanced PHP: Design Patterns - Dennis-Jan BroerseAdvanced PHP: Design Patterns - Dennis-Jan Broerse
Advanced PHP: Design Patterns - Dennis-Jan Broerse
 
PHP Web Programming
PHP Web ProgrammingPHP Web Programming
PHP Web Programming
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
PHP Powerpoint -- Teach PHP with this
PHP Powerpoint -- Teach PHP with thisPHP Powerpoint -- Teach PHP with this
PHP Powerpoint -- Teach PHP with this
 
Php Presentation
Php PresentationPhp Presentation
Php Presentation
 

Semelhante a Advanced php testing in action

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPWildan Maulana
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
R57shell
R57shellR57shell
R57shellady36
 
Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"Fwdays
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011Alessandro Nadalin
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 

Semelhante a Advanced php testing in action (20)

Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
 
Presentation1
Presentation1Presentation1
Presentation1
 
Oops in php
Oops in phpOops in php
Oops in php
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
R57shell
R57shellR57shell
R57shell
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
linieaire regressie
linieaire regressielinieaire regressie
linieaire regressie
 
Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 

Mais de Jace Ju

深入淺出 MVC
深入淺出 MVC深入淺出 MVC
深入淺出 MVCJace Ju
 
如何打造 WebMVC Framework - 基礎概念篇
如何打造 WebMVC Framework - 基礎概念篇如何打造 WebMVC Framework - 基礎概念篇
如何打造 WebMVC Framework - 基礎概念篇Jace Ju
 
Patterns in Library Design (套件設計裡的模式)
Patterns in Library Design (套件設計裡的模式)Patterns in Library Design (套件設計裡的模式)
Patterns in Library Design (套件設計裡的模式)Jace Ju
 
Patterns in Zend Framework
Patterns in Zend FrameworkPatterns in Zend Framework
Patterns in Zend FrameworkJace Ju
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationJace Ju
 
常見設計模式介紹
常見設計模式介紹常見設計模式介紹
常見設計模式介紹Jace Ju
 
Web Refactoring
Web RefactoringWeb Refactoring
Web RefactoringJace Ju
 
jQuery 實戰經驗講座
jQuery 實戰經驗講座jQuery 實戰經驗講座
jQuery 實戰經驗講座Jace Ju
 
CSS 排版 - 基礎觀念篇
CSS 排版 - 基礎觀念篇CSS 排版 - 基礎觀念篇
CSS 排版 - 基礎觀念篇Jace Ju
 

Mais de Jace Ju (9)

深入淺出 MVC
深入淺出 MVC深入淺出 MVC
深入淺出 MVC
 
如何打造 WebMVC Framework - 基礎概念篇
如何打造 WebMVC Framework - 基礎概念篇如何打造 WebMVC Framework - 基礎概念篇
如何打造 WebMVC Framework - 基礎概念篇
 
Patterns in Library Design (套件設計裡的模式)
Patterns in Library Design (套件設計裡的模式)Patterns in Library Design (套件設計裡的模式)
Patterns in Library Design (套件設計裡的模式)
 
Patterns in Zend Framework
Patterns in Zend FrameworkPatterns in Zend Framework
Patterns in Zend Framework
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & Application
 
常見設計模式介紹
常見設計模式介紹常見設計模式介紹
常見設計模式介紹
 
Web Refactoring
Web RefactoringWeb Refactoring
Web Refactoring
 
jQuery 實戰經驗講座
jQuery 實戰經驗講座jQuery 實戰經驗講座
jQuery 實戰經驗講座
 
CSS 排版 - 基礎觀念篇
CSS 排版 - 基礎觀念篇CSS 排版 - 基礎觀念篇
CSS 排版 - 基礎觀念篇
 

Último

Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
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 DiscoveryTrustArc
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
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 WorkerThousandEyes
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 

Último (20)

Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
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
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
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
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 

Advanced php testing in action

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6. watch -n 15 -d find tests/ -mmin -1 -iname '"*.php"' -exec 'phpunit -c tests/phpunit.xml {} ;'
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23. library !"" Controller.php !"" Response.php !"" Request.php !"" View.php # !"" Request #   $"" Http.php !"" Response #   $"" Http.php !"" Test #   $"" ControllerTestCase.php $"" View    $"" Html.php
  • 24.
  • 25.
  • 26. project !"" application #   !"" controllers #   #   $"" IndexController.php #   !"" models #   #   $"" Todo.php #   $"" views #   $"" index.phtml $"" tests !"" application #   !"" controllers #   #   $"" IndexControllerTest.php #   !"" models #   #   $"" TodoTest.php #   $"" views #   $"" InterfaceTest.php !"" bootstrap.php $"" phpunit.xml
  • 27.
  • 28.
  • 29.
  • 30.
  • 31. CREATE DATABASE `testing` CHARSET=utf8; USE `testing`; CREATE TABLE `todo` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT ' ', `task` varchar(100) NOT NULL COMMENT ' ', `done` enum('y','n') NOT NULL DEFAULT 'n' COMMENT ' ', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Todo';
  • 32.
  • 33. <phpunit colors="true" bootstrap="./bootstrap.php"> <testsuite name="Application Test Suite"> <directory>./application</directory> </testsuite> <testsuite name="Library Test Suite"> <directory>./library</directory> </testsuite> <php> <var name="DB_DSN" value="mysql:dbname=testing;host=127.0.0.1" /> <var name="DB_USER" value="username" /> <var name="DB_PASSWD" value="password" /> </php> </phpunit>
  • 35.
  • 36. <?php <?php class TodoTest extends class Todo PHPUnit_Framework_TestCase { {     protected static $_pdo = null; private $_pdo = null;          public static function setDb(PDO $pdo) private $_todo = null;     {         self::$_pdo = $pdo; public function setUp()     } { $this->_pdo = new PDO( $GLOBALS['DB_DSN'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD']); $this->_pdo ->query('TRUNCATE TABLE todo'); Todo::setDb($this->_pdo); $this->_todo = new Todo(); } public function tearDown() { $this->_pdo ->query('TRUNCATE TABLE todo'); }
  • 37. public function testAdd()     public function add($task) {     { $this->assertEquals(         $query = 'INSERT INTO todo (task) ' 1,  . 'VALUES (?)'; $this->_todo->add('Task 1') );         self::$_pdo->prepare($query) ->execute(array($task)); $this->assertEquals( 2,         return self::$_pdo->lastInsertId(); $this->_todo->add('Task 2')     } );      }
  • 38. public function testFetchAll()     public function fetchAll() {     { $this->_todo->add('Task 1', 'm');         $query = 'SELECT * FROM todo'; $this->_todo->add('Task 2', 'f');         $stmt  = self::$_pdo ->query($query); $result = $this->_todo->fetchAll();         return $stmt $this->assertEquals( ->fetchAll(PDO::FETCH_ASSOC); 2,     } count($result) ); $this->assertContains( 'Task 1', $result[0] ); $this->assertContains( 'Task 2', $result[1] ); }
  • 39. public function testDone()     public function done($id) {     { $this->_todo->add('Task 1');         $query = 'UPDATE todo ' $this->_todo->add('Task 2');  . 'SET done = 'y''  . 'WHERE id = ?'; $this->assertEquals(         $stmt  = self::$_pdo->prepare($query); 1, $this->_todo->done(1)         $stmt->execute(array($id)); );         return $stmt->rowCount(); $this->assertEquals(     } 1, } $this->_todo->done(2) ); $this->assertEquals( 0, $this->_todo->done(3) ); } }
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 48.
  • 49.
  • 50.
  • 52.
  • 53. <?php class InterfaceTest extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("http://test.dev/"); } public function testMyTestCase() { $this->open("/advanced_php_testing/mvc/"); $this->type("id=new-todo", "Task 1"); $this->keyPress("id=new-todo", "13"); $this->waitForPageToLoad("30000"); $this->assertEquals("Task 1", $this->getText("//ul[@id='todo-list']/div[1]/div/div")); $this->type("id=new-todo", "Task 2"); $this->keyPress("id=new-todo", "13"); $this->waitForPageToLoad("30000"); $this->assertEquals("Task 2", $this->getText("//ul[@id='todo-list']/div[2]/div/div")); } }
  • 54.
  • 55. <?php class InterfaceTest extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this->_pdo = new PDO( $GLOBALS['DB_DSN'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD']); $this->_pdo->query('TRUNCATE TABLE todo'); Todo::setDb($this->_pdo); $this->_todo = new Todo(); $this->setBrowser("*chrome"); $this->setBrowserUrl("http://test.dev/"); }
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69. <?php class Request { protected $_headers = array( 'REQUEST_METHOD' => 'GET', ); public function setHeader($name, $value) { $this->_headers[$name] = $value; } public function isPost() { return ('POST' === $this->_headers['REQUEST_METHOD']); } public function isAjax() { return ('XMLHttpRequest' === $this->_headers['X_REQUESTED_WITH']); }
  • 70. <?php class Request_Http extends Request { public function isPost() { return ('POST' === $_SERVER['REQUEST_METHOD']); } public function isAjax() { return ('XMLHttpRequest' === $_SERVER['X_REQUESTED_WITH']); } }
  • 71.
  • 72. <?php class Response { protected $_headers = array( 'Content-Type' => 'text/html; charset=utf-8', ); public function setHeader($name, $content) { $this->_headers[$name] = $content; } public function getHeader($name) { return isset($this->_headers[$name]) ? $this->_headers[$name] : null; } protected function sendHeaders() { // do nothing }
  • 73.
  • 74. $controller = new IndexController(new Todo()); $controller->setRequest(new Request_Http()) ->setResponse(new Response_Http()) ->sendResponse(true) ->dispatch(); $controller = new IndexController(new Todo()); $controller->setRequest(new Request()) ->setResponse(new Response()) ->dispatch();
  • 75.
  • 76. <?php class Test_ControllerTestCase extends PHPUnit_Framework_TestCase { protected $_controller = null; protected $_request = null; protected $_response = null; public function setUp() { $this->_controller->setRequest($this->_request) ->setResponse($this->_response); } public function dispatch($url) { $this->_parseUrl($url); $this->_controller->dispatch(); return $this; } protected function _parseUrl($url) { $urlInfo = parse_url($url); if (isset($urlInfo['query'])) { parse_str($urlInfo['query'], $_GET); } }
  • 78. <?php class IndexControllerTest extends Test_ControllerTestCase { public function setUp() { $todo = new Todo(); $this->_request = new Request(); $this->_response = new Response(); $this->_controller = new IndexController($todo); parent::setUp(); } public function tearDown() { $this->_request->reset(); $this->_response->reset(); } public function testHome() { $this->dispatch('/'); $this->assertAction('index') ->assertResponseCode(200); }
  • 79.
  • 80.
  • 81.
  • 82. <?php class IndexControllerTest extends Test_ControllerTestCase { public function setUp() { $todo = $this->_setUpTodo(); $this->_controller = new IndexController($todo); // ... } protected function _setUpTodo() { $todo = Phake::mock('Todo'); Phake::when($todo)->fetchAll()->thenReturn(array( array( 'id' => 1, 'task' => 'Task 1', 'done' => 'n', ), )); return $todo; }
  • 83.
  • 85.
  • 86. <?php class IndexControllerTest extends Test_ControllerTestCase { // ... public function testHome() { $this->dispatch('/'); $this->assertAction('index') ->assertResponseCode(200) ->assertQuery('#todo-list'); } public function testAdd() { $this->_request->setMethod('POST'); $_POST['task'] = 'Task 1'; $this->dispatch('/?act=add') ->assertAction('add') ->assertRedirectTo('./') ->assertResponseCode(200) ->assertQueryContain( '#todo-list>.todo>.display>.todo-text', 'Task 1' ); }
  • 87.
  • 89.
  • 90. ➡ ➡ ➡