The most unknown parts of
PHPUnit




Bastian Feder         IPC Spring 2011 Berlinl
lapistano@php.net              1st June 2011
Me, myself & I

 JavaScript since 2002
 PHP since 2001
 Trainer & coach
 Opensource addict
   PHP manual translations
   FluentDOM
   ...
CLI
… on the command line

 -- testdox[-(html|text)]         -- filter <pattern>
 generates a especially styled    filters which testsuite to run.
 test report.

     $ phpunit --filter Handler --testdox ./
     PHPUnit 3.4.15 by Sebastian Bergmann.

     FluentDOMCore
      [x] Get handler

     FluentDOMHandler
      [x] Insert nodes after
      [x] Insert nodes before
… on the command line                            (cont.)



 -- strict
 marks test without an assertion as incomplete. Use in
 combination with –verbose to get the name of the test.
 -- coverage-(html|source|clover) <(dir|file)>
 generates a report on how many lines of the code has how often
 been executed.
 -- group <groupname [, groupname]>
 runs only the named group(s).
 -- d key[=value]
 alter ini-settings (e.g. memory_limit, max_execution_time)
Annotations
Annotations

 „In software programming, annotations are used
 mainly for the purpose of expanding code
 documentation and comments. They are typically
 ignored when the code is compiled or executed.“
 ( Wikipedia: http://en.wikipedia.org/w/index.php?title=Annotation&oldid=385076084 )
Annotations              (cont.)



/** @covers, @group
 * @covers myClass::run
 * @group exceptions
 * @group Trac-123
 */
public function testInvalidArgumentException() {

     $obj = new myClass();
     try{
         $obj->run( 'invalidArgument' );
         $this->fail('Expected exception not thrown.');
     } catch ( InvalidArgumentException $e ) {
     }
}
Annotations              (cont.)



    Depending on other tests

public function testIsApcAvailable() {

     if ( ! extension_loaded( 'apc' ) ) {
         $this->markTestSkipped( 'Required APC not available' );
     }
}

/**
 * @depend testIsApcAvailable
 */
public function testGetFileFromAPC () {

}
Assertions
Assertions

 „In computer programming, an assertion is a predicate
 (for example a true–false statement) placed in a
 program to indicate that the developer thinks that the
 predicate is always true at that place. [...]
 It may be used to verify that an assumption made by
 the programmer during the implementation of the
 program remains valid when the program is executed..
 [...]“

 (Wikipedia, http://en.wikipedia.org/w/index.php?title=Assertion_(computing)&oldid=382473744)
Assertions          (cont.)



 assertContains(), assertContainsOnly()

 Cameleon within the asserts, handles
    Strings ( like strpos() )
    Arrays ( like in_array() )

$this->assertContains('bar', 'foobar');                    // ✓

$this->assertContainsOnly('string', array('1', '2', 3));   // ✗
Assertions         (cont.)



 assertXMLFileEqualsXMLFile()
 assertXMLStringEqualsXMLFile()
 assertXMLStringEqualsXMLString()

 $this->assertXMLFileEqualsXMLFile(
     '/path/to/Expected.xml',
     '/path/to/Fixture.xml'
 );
Assertions      (cont.)


     $ phpunit XmlFileEqualsXmlFileTest.php
     PHPUnit 3.4.15 by Sebastian Bergmann.
     …

     1) XmlFileEqualsXmlFileTest::testFailure
     Failed asserting that two strings are
     equal.
     --- Expected
     +++ Actual
     @@ -1,4 +1,4 @@
      <?xml version="1.0"?>
      <foo>
     - <bar/>
     + <baz/>
      </foo>

     /dev/tests/XmlFileEqualsXmlFileTest.php:7
Assertions           (cont.)


 assertAttribute*()

 Asserts the content of a class attribute regardless its
 visibility
 […]
       private $collection = array( 1, 2, '3' );
       private $name = 'Jakob';
 […]

 $this->assertAttributeContainsOnly(
     'integer', 'collection', new myClass );

 $this->assertAttributeContains(
     'ko', 'name', new myClass );
Assertions         (cont.)



 assertType()
 // TYPE_OBJECT
 $this->assertType( 'FluentDOM', new FluentDOM );

 $this->assertInstanceOf( 'FluentDOM', new FluentDOM );

 // TYPE_STRING
 $this->assertInternalType( 'string', '4221' );

 // TYPE_INTEGER
 $this->assertInternalType( 'integer', 4221 );

 // TYPE_RESSOURCE
 $this->assertInternalType(
     'resource', fopen('/file.txt', 'r' );
Assertions         (cont.)



 assertSelectRegExp()
 $xml = '
      <items version="1.0">
        <persons>
          <person class="firstname">Thomas</person>
          <person class="firstname">Jakob</person>
          <person class="firstname">Bastian</person>
        </persons>
      </items>
   ';

 $this->assertSelectRegExp(
     'person[class*="name"]','(Jakob|Bastian)', 2, $xml);
Assertions         (cont.)



 assertThat()

 Evaluates constraints to build complex assertions.
 $this->assertThat(
     $expected,
     $ths->logicalAnd(
         $this->isInstanceOf('tire'),
         $this->logicalNot(
             $this->identicalTo($myFrontTire)
         )
     )
 );
Weaving in
Test Listeners

 Get called on several states of the test runner
   startTest
   endTest
   addIncompleteTest
   …
Test Listeners            (cont.)



 Configuration
   Add to your phpunit.xml
 <listeners>
   <listener class="myListener"
             file="PATH/TO/YOUR/CODE">
     <arguments>
       <string>build/log</string>
     </arguments>
   </listener>
 </listeners>
Test Listeners               (cont.)



      Implementation example
class ListenerLog implements PHPUnit_Framework_TestListener
{
  public function __construct($path)
  {
    $this->path = $path;
  }

    public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
    {
      $this->log("Test suite '%s' precesed.n", $test->getName());
    }

}
Specialities
Special tests

 Testing exceptions
     @expectedException

 /**
  * @expectedException InvalidArgumentException
  */
 public function testInvalidArgumentException() {

      $obj = new myClass();
      $obj->run('invalidArgument');

 }
Special tests         (cont.)



 Testing exceptions
   setExpectedException( 'Exception' )
     for internal use only!!
     don't use it directly any more.
Special tests              (cont.)



    Testing exceptions
      try/catch
      Does not work when using --strict switch

public function testInvalidArgumentException() {

      $obj = new myClass();
      try{
          $obj->run( 'invalidArgument' );
          $this->fail('Expected exception not thrown.');
      } catch ( InvalidArgumentException $e ) {
      }
}
Special tests            (cont.)


 public function callbackGetObject($name, $className = '')
 {
     retrun strtolower($name) == 'Jakob';
 }

 […]

 $application = $this->getMock('FluentDOM');
 $application
     ->expects($this->any())
     ->method('getObject')
     ->will(
         $this->returnCallback(
             array($this, 'callbackGetObject')
         )
     );
 […]
Special tests             (cont.)



[…]

$application = $this->getMock('FluentDOM');
$application
    ->expects($this->any())
    ->method('getObject')
    ->will(
        $this->onConsecutiveCalls(
            array($this, 'callbackGetObject',
            $this->returnValue(true),
            $this->returnValue(false),
            $this->equalTo($expected)
        )
    );

[…]
Special tests              (cont.)


    implicit integration tests

public function testGet() {

      $mock = $this->getMock(
          'myAbstraction'
      );

      $mock
          ->expected( $this->once() )
          ->method( 'method' )
          ->will( $this->returnValue( 'return' );
}
Questions
@lapistano

lapistano@php.net
Slides'n contact

 Please comment the talk on joind.in
   http://joind.in/3518
 Slides
   http://slideshare.net/lapistano
 Email:
   lapistano@php.net
PHP5.3 Powerworkshop

               New features of PHP5.3
               Best Pratices using OOP
               PHPUnit
               PHPDocumentor
License

    
        This set of slides and the source code included
        in the download package is licensed under the

Creative Commons Attribution-Noncommercial-Share
            Alike 2.0 Generic License


         http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en

Php unit the-mostunknownparts

  • 1.
    The most unknownparts of PHPUnit Bastian Feder IPC Spring 2011 Berlinl lapistano@php.net 1st June 2011
  • 2.
    Me, myself &I JavaScript since 2002 PHP since 2001 Trainer & coach Opensource addict PHP manual translations FluentDOM ...
  • 3.
  • 4.
    … on thecommand line -- testdox[-(html|text)] -- filter <pattern> generates a especially styled filters which testsuite to run. test report. $ phpunit --filter Handler --testdox ./ PHPUnit 3.4.15 by Sebastian Bergmann. FluentDOMCore [x] Get handler FluentDOMHandler [x] Insert nodes after [x] Insert nodes before
  • 5.
    … on thecommand line (cont.) -- strict marks test without an assertion as incomplete. Use in combination with –verbose to get the name of the test. -- coverage-(html|source|clover) <(dir|file)> generates a report on how many lines of the code has how often been executed. -- group <groupname [, groupname]> runs only the named group(s). -- d key[=value] alter ini-settings (e.g. memory_limit, max_execution_time)
  • 6.
  • 7.
    Annotations „In softwareprogramming, annotations are used mainly for the purpose of expanding code documentation and comments. They are typically ignored when the code is compiled or executed.“ ( Wikipedia: http://en.wikipedia.org/w/index.php?title=Annotation&oldid=385076084 )
  • 8.
    Annotations (cont.) /** @covers, @group * @covers myClass::run * @group exceptions * @group Trac-123 */ public function testInvalidArgumentException() { $obj = new myClass(); try{ $obj->run( 'invalidArgument' ); $this->fail('Expected exception not thrown.'); } catch ( InvalidArgumentException $e ) { } }
  • 9.
    Annotations (cont.) Depending on other tests public function testIsApcAvailable() { if ( ! extension_loaded( 'apc' ) ) { $this->markTestSkipped( 'Required APC not available' ); } } /** * @depend testIsApcAvailable */ public function testGetFileFromAPC () { }
  • 10.
  • 11.
    Assertions „In computerprogramming, an assertion is a predicate (for example a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place. [...] It may be used to verify that an assumption made by the programmer during the implementation of the program remains valid when the program is executed.. [...]“ (Wikipedia, http://en.wikipedia.org/w/index.php?title=Assertion_(computing)&oldid=382473744)
  • 12.
    Assertions (cont.) assertContains(), assertContainsOnly() Cameleon within the asserts, handles Strings ( like strpos() ) Arrays ( like in_array() ) $this->assertContains('bar', 'foobar'); // ✓ $this->assertContainsOnly('string', array('1', '2', 3)); // ✗
  • 13.
    Assertions (cont.) assertXMLFileEqualsXMLFile() assertXMLStringEqualsXMLFile() assertXMLStringEqualsXMLString() $this->assertXMLFileEqualsXMLFile( '/path/to/Expected.xml', '/path/to/Fixture.xml' );
  • 14.
    Assertions (cont.) $ phpunit XmlFileEqualsXmlFileTest.php PHPUnit 3.4.15 by Sebastian Bergmann. … 1) XmlFileEqualsXmlFileTest::testFailure Failed asserting that two strings are equal. --- Expected +++ Actual @@ -1,4 +1,4 @@ <?xml version="1.0"?> <foo> - <bar/> + <baz/> </foo> /dev/tests/XmlFileEqualsXmlFileTest.php:7
  • 15.
    Assertions (cont.) assertAttribute*() Asserts the content of a class attribute regardless its visibility […] private $collection = array( 1, 2, '3' ); private $name = 'Jakob'; […] $this->assertAttributeContainsOnly( 'integer', 'collection', new myClass ); $this->assertAttributeContains( 'ko', 'name', new myClass );
  • 16.
    Assertions (cont.) assertType() // TYPE_OBJECT $this->assertType( 'FluentDOM', new FluentDOM ); $this->assertInstanceOf( 'FluentDOM', new FluentDOM ); // TYPE_STRING $this->assertInternalType( 'string', '4221' ); // TYPE_INTEGER $this->assertInternalType( 'integer', 4221 ); // TYPE_RESSOURCE $this->assertInternalType( 'resource', fopen('/file.txt', 'r' );
  • 17.
    Assertions (cont.) assertSelectRegExp() $xml = ' <items version="1.0"> <persons> <person class="firstname">Thomas</person> <person class="firstname">Jakob</person> <person class="firstname">Bastian</person> </persons> </items> '; $this->assertSelectRegExp( 'person[class*="name"]','(Jakob|Bastian)', 2, $xml);
  • 18.
    Assertions (cont.) assertThat() Evaluates constraints to build complex assertions. $this->assertThat( $expected, $ths->logicalAnd( $this->isInstanceOf('tire'), $this->logicalNot( $this->identicalTo($myFrontTire) ) ) );
  • 19.
  • 20.
    Test Listeners Getcalled on several states of the test runner startTest endTest addIncompleteTest …
  • 21.
    Test Listeners (cont.) Configuration Add to your phpunit.xml <listeners> <listener class="myListener" file="PATH/TO/YOUR/CODE"> <arguments> <string>build/log</string> </arguments> </listener> </listeners>
  • 22.
    Test Listeners (cont.) Implementation example class ListenerLog implements PHPUnit_Framework_TestListener { public function __construct($path) { $this->path = $path; } public function startTestSuite(PHPUnit_Framework_TestSuite $suite) { $this->log("Test suite '%s' precesed.n", $test->getName()); } }
  • 23.
  • 24.
    Special tests Testingexceptions @expectedException /** * @expectedException InvalidArgumentException */ public function testInvalidArgumentException() { $obj = new myClass(); $obj->run('invalidArgument'); }
  • 25.
    Special tests (cont.) Testing exceptions setExpectedException( 'Exception' ) for internal use only!! don't use it directly any more.
  • 26.
    Special tests (cont.) Testing exceptions try/catch Does not work when using --strict switch public function testInvalidArgumentException() { $obj = new myClass(); try{ $obj->run( 'invalidArgument' ); $this->fail('Expected exception not thrown.'); } catch ( InvalidArgumentException $e ) { } }
  • 27.
    Special tests (cont.) public function callbackGetObject($name, $className = '') { retrun strtolower($name) == 'Jakob'; } […] $application = $this->getMock('FluentDOM'); $application ->expects($this->any()) ->method('getObject') ->will( $this->returnCallback( array($this, 'callbackGetObject') ) ); […]
  • 28.
    Special tests (cont.) […] $application = $this->getMock('FluentDOM'); $application ->expects($this->any()) ->method('getObject') ->will( $this->onConsecutiveCalls( array($this, 'callbackGetObject', $this->returnValue(true), $this->returnValue(false), $this->equalTo($expected) ) ); […]
  • 29.
    Special tests (cont.) implicit integration tests public function testGet() { $mock = $this->getMock( 'myAbstraction' ); $mock ->expected( $this->once() ) ->method( 'method' ) ->will( $this->returnValue( 'return' ); }
  • 30.
  • 31.
    Slides'n contact Pleasecomment the talk on joind.in http://joind.in/3518 Slides http://slideshare.net/lapistano Email: lapistano@php.net
  • 32.
    PHP5.3 Powerworkshop New features of PHP5.3 Best Pratices using OOP PHPUnit PHPDocumentor
  • 33.
    License  This set of slides and the source code included in the download package is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 2.0 Generic License http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en