Unit Testing with PHPUnit
by Joeri Timmermans
Who am i?
- 27 years old
- Gamer, PHP Developer
with a passion for Food & Drinks - Interactive Multimedia Design
- @Joeri_timmer
- /pix-art
- www.pix-art.be



- What is Unit Testing?
- Debunking the myths
- Why do Unit Testing?
- PHPUnit
- Starting with PHPUnit
- Basic assertions
- Hello world!
- Oooops!
- Fixtures
- Mock objects
- Database testing
- Interesting reads
- Questions?
//TODO:

What is Unit Testing?
Wikipedia:
"Unit testing is a software testing method by which individual units of source code are tested to determine if they are fit for use"
Debunking the myths
- It Takes Too Long
- There’s No Need to Test:
My Code Already Works! - Expensive
- It’s No Fun
- Automation
- Readable code == Testable code
- Test code on functionality
- Reduce bugs in new and existing features
- Reduce cost of changes
- Easier refactoring
- Progress indication of the project
- Alerts generation for CI-tools
- Forces you to slow down and think
- Speed up development and reduce fear
Why do (Unit) Testing
PHPUnit
- Created by Sebastian Bergmann
- Part of xUnit Family
- /sebastianbergmann/phpunit

Starting with PHPUnit

- Download phar:
https://phpunit.de
- Composer:
"phpunit/phpunit": "4.3.*"
- Setup phpunit.xml
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="bootstrap/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Application Test Suite">
<directory>./app/tests/</directory>
</testsuite>
</testsuites>
</phpunit>
Info: https://phpunit.de/manual/current/en/appendixes.configuration.html
Basic assertions
-
AssertTrue/AssertFalse - Check the input to verify it equals true/false
-
AssertEquals - Check the result against another input for a match
-
AssertGreaterThan - Check the result to see if it’s larger than a value
(there’s also LessThan, GreaterThanOrEqual, and LessThanOrEqual) -
AssertContains - Check that the input contains a certain value
-
AssertType - Check that a variable is of a certain type
-
AssertNull - Check that a variable is null
-
AssertFileExists - Verify that a file exists
-
AssertRegExp - Check the input against a regular expression
-
...
Hello world!
<?php
namespace Example;
class HelloWorld
{
public $helloWorld;
public function __construct($string = 'Hello World!')
{
$this->helloWorld = $string;
}
public function sayHello()
{
return $this->helloWorld;
}
}
Our first test
<?php
namespace Example;
class HelloWorldTest extends \PHPUnit_Framework_TestCase
{
public function testSayHello()
{
$hw = new HelloWorld();
$string = $hw->sayHello();
$this->assertEquals('Hello World!', $string);
}
}
The result!
PHPUnit 4.2.5 by Sebastian Bergmann.
Configuration read from /var/www/example/build/phpunit.xml
.
Time: 70 ms, Memory: 3.50Mb
OK (1 test, 1 assertion)
Oooops!
<?php
namespace Example;
class OopsTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Wrong argument!
*/
public function testOops()
{
throw new \InvalidArgumentException("Wrong argument!");
}
}
The result!
PHPUnit 4.2.5 by Sebastian Bergmann.
Configuration read from /var/www/example/build/phpunit.xml
.
Time: 60 ms, Memory: 3.25Mb
OK (1 test, 2 assertions)
Fixtures
- "Known state" of an application
- needs to be "set up" at start
- needs to be "torn down" at end
- shares "states" over test methods
<?php
namespace Example;
class MyListTest extends \PHPUnit_Framework_TestCase
{
protected $myList;
public function setUp()
{
$this->myList = array();
}
public function testMyListEmpty()
{
$this->assertEquals(0, sizeof($this->myList));
}
public function testMyListHasOne()
{
array_push($this->myList, 'myItem');
$this->assertEquals(1, sizeof($this->myList));
}
public function tearDown()
{
unset($this->myList);
}
}
The result!
PHPUnit 4.2.5 by Sebastian Bergmann.
Configuration read from /var/www/example/build/phpunit.xml
..
Time: 67 ms, Memory: 3.50Mb
OK (2 tests, 2 assertions)
Mock objects
- Simulated objects
- Mimics API or behaviour
- In a controlled way
- To test real objects
Mock objects
<?php
namespace Example;
class HelloMailer
{
public $mailer;
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
public function sendMessage($message)
{
return $this->mailer->send($message);
}
}
<?php
namespace Example;
class HelloMailerTest extends \PHPUnit_Framework_TestCase
{
protected $mailer;
public function setUp()
{
$mailer = $this->getMockBuilder('Example\Mailer')
->setMockClassName('Mailer')
->disableOriginalConstructor()
->setMethods(array('send'))
->getMock();
$mailer->expects($this->any())
->method('send')
->with($this->equalTo('Hello mailer!'))
->will($this->returnValue(true));
$this->mailer = $mailer;
}
public function testSend()
{
$hm = new HelloMailer($this->mailer);
$response = $hm->sendMessage('Hello mailer!');
$this->assertTrue($response);
}
}
The result!
PHPUnit 4.2.5 by Sebastian Bergmann.
Configuration read from /var/www/example/build/phpunit.xml
.
Time: 80 ms, Memory: 4.00Mb
OK (1 test, 1 assertion)
Database testing
- DbUnit supports: MySQL, PostgreSQL, Oracle and SQLite
- getConnection()
- getDataSet()
-
The four stages of a database test
-
Set up fixture
-
Exercise System Under Test
-
Verify outcome
-
Teardown
-
Behat
Feature: homepage
This is a standard behat test to see if the homepage
shows the right notifications
Scenario: When i visit the homepage i should see notifications # app/tests/features/homepage.feature:4
Given I am on "/notifications" # FeatureContext::visit()
Then I should see "Docent A. Bastiaan zal afwezig zijn op 22/10/2014." # FeatureContext::assertPageContainsText()
Then I should see "Op 6/10 zal er een persconferentie van Telenet
plaatsvinden in de Creativity Gym."
1 scenario (1 gelukt)
3 stappen (3 gelukt)
0m0.11s
Scenario: When i visit the homepage i should see notifications
Given I am on "/notifications"
Then I should see "Docent A. Bastiaan zal afwezig zijn op 22/10/2014."
Then I should see "Op 6/10 zal er een persconferentie van Telenet
plaatsvinden in de Creativity Gym."
Interesting reads
- https://phpunit.de/
- http://www.dragonbe.com/
- http://www.sitepoint.com/tutorial-introduction-to-unit-testing-in-php-with-phpunit/
Questions?
Thank you
- @Joeri_timmer
- /pix-art
- www.pix-art.be



Unit Testing with PHPUnit
By Joeri Timmermans
Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
- 975