RICARDO MELO

PHPUnit your bug
exterminator
Follow this topic:
@rjsmelo, #phpunit
PHPLX – 07 December 2013
RICARDO MELO

CTO @ DRI
● PHP, Mysql, Linux and lots of other
OSS
● ZCE, RHCE, LPI 3, ITIL, etc
● +10 years building (and breaking)
things
●

@rjsmelo

2
About

14 Year old academic spin-off
● Pragmatic OSS Orientation
● PHP, Mysql, SugarCRM, Drupal,
JavaScript, Linux, etc.
● Crafters, Integrators
●

●

Always looking for software developers
–

Yes, right now!

@rjsmelo

3
Outline

Testing Methodologies
● Testing Tools Ecosystem
● What's PHPUnit
● The "Hello World" test
● How to run your tests
● Other assertions
● Other PHPUnit topics
● The bug hunting work flow
●

1999 - 2013 DRI. Some Rights Reserved
.

4
Testing and Development Methodologies

Unit, Integration, System and
Acceptance Testing
● CMMI/Waterfall, Agile and XP
● TDD and BDD
●

1999 - 2013 DRI. Some Rights Reserved
.

5
Testing Tools Ecosystem

PHPUnit
● Behat
● Selenium
● Codeception
● And many more
●

1999 - 2013 DRI. Some Rights Reserved
.

6
What's PHPUnit

xUnit family for PHP
● Uses assertions to check the behavior
of the unit
● But it can handle other tests like
integration and system
●

1999 - 2013 DRI. Some Rights Reserved
.

7
Installing PHPUnit
●

Pear
pear config-set auto_discover 1
pear install pear.phpunit.de/PHPUnit
phpunit --version

1999 - 2013 DRI. Some Rights Reserved
.

8
Installing PHPUnit
●

Composer
{
"require-dev": {
"phpunit/phpunit": "3.7.*"
}
}
composer install
./vendor/bin/phpunit --version

1999 - 2013 DRI. Some Rights Reserved
.

9
The "Hello World" test
<?php
namespace Phplx;
class HelloWorld {
public function say(){
return "Hello World";
}
}

1999 - 2013 DRI. Some Rights Reserved
.

10
The "Hello World" test
<?php
namespace PhplxTestsHelloWorld;
use PHPUnit_Framework_TestCase
use PhplxHelloWorld;
class HelloWorldTest extends PHPUnit_Framework_TestCase
{
public function testHelloWorld(){
$obj = new HelloWorld();
$this->assertEquals("Hello World", $obj->say());
}
}

1999 - 2013 DRI. Some Rights Reserved
.

11
How to run your tests
# using PEAR / PHAR
phpunit --bootstrap vendor/autoload.php tests/
# using composer
./vendor/bin/phpunit tests/

1999 - 2013 DRI. Some Rights Reserved
.

12
How to run your tests – bootstrap.php
<?php
use PhplxApp;
require_once dirname(__DIR__) . "/vendor/autoload.php";
$app = new App();
$app->initHelloWorldApplication();

1999 - 2013 DRI. Some Rights Reserved
.

13
How to run your tests – phpunit.xml
<phpunit

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xs
d"
bootstrap="tests/bootstrap.php"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
>
<testsuites>
<testsuite name="Hello World Test Suite">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
</phpunit>

1999 - 2013 DRI. Some Rights Reserved
.

14
How to run your tests – phpunit
$ ./vendor/bin/phpunit
PHPUnit 3.7.28 by Sebastian Bergmann.
Configuration read from /home/rjsmelo/phplx/phpunit.xml
...
Time: 42 ms, Memory: 3.25Mb
OK (3 tests, 3 assertions)

1999 - 2013 DRI. Some Rights Reserved
.

15
Other assertions
●

There is a HUGE list of assertions

1999 - 2013 DRI. Some Rights Reserved
.

16
Use specific assertions - assertInstanceOf
<?php
use PhplxHelloWorld;
class InstanceOfTest extends PHPUnit_Framework_TestCase
{
public function testTrue(){
$obj = new stdClass();
$this->assertTrue(
$obj instanceof PhplxHelloWorld);
}
public function testInstanceOf(){
$obj = new stdClass();
$this->assertInstanceOf(
'PhplxHelloWorld', $obj);
}
}
1999 - 2013 DRI. Some Rights Reserved
.

17
Use specific assertions - assertInstanceOf
PHPUnit 3.7.28 by Sebastian Bergmann.
[...]
1) InstanceOfTest::testTrue
Failed asserting that false is true.
2) InstanceOfTest::testInstanceOf
Failed asserting that stdClass Object () is an instance of class
"PhplxHelloWorld".

1999 - 2013 DRI. Some Rights Reserved
.

18
Use specific assertions - JsonString
<?php
use PhplxObject;
class JsonStringTest extends PHPUnit_Framework_TestCase
{
protected $jsonString =
'{"someKey":"some thing","otherKey":"other thing"}';
public function testEquals(){
$obj = new Object();
$this->assertEquals(
$this->jsonString, $obj->myPreciousJson());
}
public function testJsonString(){
$obj = new Object();
$this->assertJsonStringEqualsJsonString(
$this->jsonString, $obj->myPreciousJson());
}
}
1999 - 2013 DRI. Some Rights Reserved
.

19
Use specific assertions - JsonString
PHPUnit 3.7.28 by Sebastian Bergmann.
[...]
1) JsonStringTest::testEquals
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'{"someKey":"some thing","otherKey":"other thing"}'
+'{"someKey":"some value","otherKey":"other thing"}'
2) JsonStringTest::testJsonString
Failed asserting that two objects are equal.
--- Expected
+++ Actual
@@ @@
stdClass Object (
'someKey' => 'some thing'
+
'someKey' => 'some value'
'otherKey' => 'other thing'
)
1999 - 2013 DRI. Some Rights Reserved
.

20
Other PHPUnit topics

Setup / Teardown
● Data providers
● Test doubles
●

1999 - 2013 DRI. Some Rights Reserved
.

21
The bug hunting work flow

Gather information on the problem
● Reproduce the problem
● Capture that as a test
● Fix it (ok... this sometimes is hard)
● All green... mission accomplished
●

1999 - 2013 DRI. Some Rights Reserved
.

22
The community challenge

Go to your favorite PHP project
● Or go to
https://github.com/trending?l=php
and pick one
● Fix Some Bugs!
●

1999 - 2013 DRI. Some Rights Reserved
.

23
Thank you
QA
Follow this topic:
@rjsmelo, #phpunit

Code: https://github.com/rjsmelo/talk-phpunit
Feedback: https://joind.in/talk/view/10305
www.dri-global.com
@rjsmelo
ricardo.melo@dri-global.com

PHPUnit your bug exterminator

  • 1.
    RICARDO MELO PHPUnit yourbug exterminator Follow this topic: @rjsmelo, #phpunit PHPLX – 07 December 2013
  • 2.
    RICARDO MELO CTO @DRI ● PHP, Mysql, Linux and lots of other OSS ● ZCE, RHCE, LPI 3, ITIL, etc ● +10 years building (and breaking) things ● @rjsmelo 2
  • 3.
    About 14 Year oldacademic spin-off ● Pragmatic OSS Orientation ● PHP, Mysql, SugarCRM, Drupal, JavaScript, Linux, etc. ● Crafters, Integrators ● ● Always looking for software developers – Yes, right now! @rjsmelo 3
  • 4.
    Outline Testing Methodologies ● TestingTools Ecosystem ● What's PHPUnit ● The "Hello World" test ● How to run your tests ● Other assertions ● Other PHPUnit topics ● The bug hunting work flow ● 1999 - 2013 DRI. Some Rights Reserved . 4
  • 5.
    Testing and DevelopmentMethodologies Unit, Integration, System and Acceptance Testing ● CMMI/Waterfall, Agile and XP ● TDD and BDD ● 1999 - 2013 DRI. Some Rights Reserved . 5
  • 6.
    Testing Tools Ecosystem PHPUnit ●Behat ● Selenium ● Codeception ● And many more ● 1999 - 2013 DRI. Some Rights Reserved . 6
  • 7.
    What's PHPUnit xUnit familyfor PHP ● Uses assertions to check the behavior of the unit ● But it can handle other tests like integration and system ● 1999 - 2013 DRI. Some Rights Reserved . 7
  • 8.
    Installing PHPUnit ● Pear pear config-setauto_discover 1 pear install pear.phpunit.de/PHPUnit phpunit --version 1999 - 2013 DRI. Some Rights Reserved . 8
  • 9.
    Installing PHPUnit ● Composer { "require-dev": { "phpunit/phpunit":"3.7.*" } } composer install ./vendor/bin/phpunit --version 1999 - 2013 DRI. Some Rights Reserved . 9
  • 10.
    The "Hello World"test <?php namespace Phplx; class HelloWorld { public function say(){ return "Hello World"; } } 1999 - 2013 DRI. Some Rights Reserved . 10
  • 11.
    The "Hello World"test <?php namespace PhplxTestsHelloWorld; use PHPUnit_Framework_TestCase use PhplxHelloWorld; class HelloWorldTest extends PHPUnit_Framework_TestCase { public function testHelloWorld(){ $obj = new HelloWorld(); $this->assertEquals("Hello World", $obj->say()); } } 1999 - 2013 DRI. Some Rights Reserved . 11
  • 12.
    How to runyour tests # using PEAR / PHAR phpunit --bootstrap vendor/autoload.php tests/ # using composer ./vendor/bin/phpunit tests/ 1999 - 2013 DRI. Some Rights Reserved . 12
  • 13.
    How to runyour tests – bootstrap.php <?php use PhplxApp; require_once dirname(__DIR__) . "/vendor/autoload.php"; $app = new App(); $app->initHelloWorldApplication(); 1999 - 2013 DRI. Some Rights Reserved . 13
  • 14.
    How to runyour tests – phpunit.xml <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xs d" bootstrap="tests/bootstrap.php" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" > <testsuites> <testsuite name="Hello World Test Suite"> <directory suffix="Test.php">tests</directory> </testsuite> </testsuites> </phpunit> 1999 - 2013 DRI. Some Rights Reserved . 14
  • 15.
    How to runyour tests – phpunit $ ./vendor/bin/phpunit PHPUnit 3.7.28 by Sebastian Bergmann. Configuration read from /home/rjsmelo/phplx/phpunit.xml ... Time: 42 ms, Memory: 3.25Mb OK (3 tests, 3 assertions) 1999 - 2013 DRI. Some Rights Reserved . 15
  • 16.
    Other assertions ● There isa HUGE list of assertions 1999 - 2013 DRI. Some Rights Reserved . 16
  • 17.
    Use specific assertions- assertInstanceOf <?php use PhplxHelloWorld; class InstanceOfTest extends PHPUnit_Framework_TestCase { public function testTrue(){ $obj = new stdClass(); $this->assertTrue( $obj instanceof PhplxHelloWorld); } public function testInstanceOf(){ $obj = new stdClass(); $this->assertInstanceOf( 'PhplxHelloWorld', $obj); } } 1999 - 2013 DRI. Some Rights Reserved . 17
  • 18.
    Use specific assertions- assertInstanceOf PHPUnit 3.7.28 by Sebastian Bergmann. [...] 1) InstanceOfTest::testTrue Failed asserting that false is true. 2) InstanceOfTest::testInstanceOf Failed asserting that stdClass Object () is an instance of class "PhplxHelloWorld". 1999 - 2013 DRI. Some Rights Reserved . 18
  • 19.
    Use specific assertions- JsonString <?php use PhplxObject; class JsonStringTest extends PHPUnit_Framework_TestCase { protected $jsonString = '{"someKey":"some thing","otherKey":"other thing"}'; public function testEquals(){ $obj = new Object(); $this->assertEquals( $this->jsonString, $obj->myPreciousJson()); } public function testJsonString(){ $obj = new Object(); $this->assertJsonStringEqualsJsonString( $this->jsonString, $obj->myPreciousJson()); } } 1999 - 2013 DRI. Some Rights Reserved . 19
  • 20.
    Use specific assertions- JsonString PHPUnit 3.7.28 by Sebastian Bergmann. [...] 1) JsonStringTest::testEquals Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'{"someKey":"some thing","otherKey":"other thing"}' +'{"someKey":"some value","otherKey":"other thing"}' 2) JsonStringTest::testJsonString Failed asserting that two objects are equal. --- Expected +++ Actual @@ @@ stdClass Object ( 'someKey' => 'some thing' + 'someKey' => 'some value' 'otherKey' => 'other thing' ) 1999 - 2013 DRI. Some Rights Reserved . 20
  • 21.
    Other PHPUnit topics Setup/ Teardown ● Data providers ● Test doubles ● 1999 - 2013 DRI. Some Rights Reserved . 21
  • 22.
    The bug huntingwork flow Gather information on the problem ● Reproduce the problem ● Capture that as a test ● Fix it (ok... this sometimes is hard) ● All green... mission accomplished ● 1999 - 2013 DRI. Some Rights Reserved . 22
  • 23.
    The community challenge Goto your favorite PHP project ● Or go to https://github.com/trending?l=php and pick one ● Fix Some Bugs! ● 1999 - 2013 DRI. Some Rights Reserved . 23
  • 24.
  • 25.
    QA Follow this topic: @rjsmelo,#phpunit Code: https://github.com/rjsmelo/talk-phpunit Feedback: https://joind.in/talk/view/10305
  • 26.