2. Unit Test
Unit : The smallest testable part of an
application.
Unit testing : Testing a unit of code
isolated from its dependencies.
Testing with PHPUnit : The difference is
between testing, that is, checking that your program
behaves as expected, and performing a battery of
tests, runnable code-fragments that automatically
test the correctness of parts (units) of the software.
3. PHPUnit
Part of xUnit family(JUnit, Sunit,...)
Created by Sebastian Bergmann
Integrated in most IDE
Eclipse, Netbeans, Zend Stuide, PHPStorm
Integrated/supported
Zend Studio, Zend Framework, Cake, Symfony
4. PHPUnit's Goals
Tests should be:
Easy to learn to write.
Easy to write.
Easy to read.
Easy to execute.
Quick to execute.
Isolated.
Composable.
Resolve conflicts:
Easy to learn to write versus easy to write.
Isolated versus quick to execute.
5. Installing PHPUnit
PHPUnit is installed using the PEAR
Installer
Commands to install :
pear config-set auto_discover 1
pear install pear.phpunit.de/PHPUnit
6. Writing Tests for PHPUnit
The tests for a class Class go into a class
ClassTest.
ClassTest inherits (most of the time) from
PHPUnit_Framework_TestCase.
The tests are public methods that are
named test*.
Inside the test methods, assertion
methods such as assertEquals() are used
to assert that an actual value matches an
expected value.
7. /Filename : user.php
?php
Sample PHP class for testing
lass User {
protected $name;
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
public function talk() {
return "Hello world!";
8. Test class for testing user.php
?php
equire_once "PHPUnit/Autoload.php";
equire_once "user.php";
lass UserTest extends
PHPUnit_Framework_TestCase
9. ?php
Test class for testing user.php
..
lass UserTest extends PHPUnit_Framework_TestCase
// test the talk method
public function testTalk() {
// make an instance of the user
$user = new User();
// use assertEquals to ensure the greeting is what you expect
$expected = "Hello world!";
$actual = $user->talk();
$this->assertEquals($expected, $actual);
10. The Command-Line Test Runner
The PHPUnit command-line test runner
can be invoked through the phpunit
command.
phpunit UnitTest UnitTest.php
Runs the tests that are provided by the
class UnitTest. This class is expected to
be declared in the specified sourcefile.
12. For each test run, the PHPUnit command-line
tool prints one character to indicate progress:
. – Printed when a test succeeds.
F – Printed when an assertion fails.
E – Printed when an error occurs while
running the test.
S – Printed when the test has been
skipped.
I – Printed when the test is marked as
being incomplete.
13. Output when a Test fails
oot@varuntaliyan:/var/www/test-1# phpunit userTest.php
HPUnit 3.6.10 by Sebastian Bergmann.
ime: 0 seconds, Memory: 2.75Mb
here was 1 failure:
) UserTest::testTalk
ailed asserting that two strings are equal.
-- Expected
++ Actual
@ @@
'Hello world!'
'Non sense'
var/www/test-1/userTest.php:14
14. Test Dependencies
PHPUnit supports the declaration of explicit dependencies
between test methods. Such dependencies do not define the
order in which the test methods are to be executed but they allow
the returning of an instance of the test fixture by a producer and
passing it to the dependent consumers.
A producer is a test method that yields its unit under test as
return value.
A consumer is a test method that depends on one or more
producers and their return values.
15. lass StackTest extends PHPUnit_Framework_TestCase
public function testEmpty()
Using the @depends annotation to express dependencies
{
$stack = array();
$this->assertEmpty($stack);
return $stack;
}
/**
* @depends testEmpty
*/
public function testPush(array $stack)
{
array_push($stack, 'foo');
$this->assertEquals('foo', $stack[count($stack)-1]);
$this->assertNotEmpty($stack);
return $stack;
}
/**
* @depends testPush
*/
public function testPop(array $stack)
{
16. Running the Test
/var/www/test-1# phroot@varuntaliyanpunit depend.php
HPUnit 3.6.10 by Sebastian Bergmann.
..
ime: 0 seconds, Memory: 2.75Mb
K (3 tests, 5 assertions)
17. Data Providers
test method can accept arbitrary
argumeants. These arguments are to
be provided by a data provider
methods.
18. lass DataTest extends PHPUnit_Framework_TestCase
Using a data provider that returns an array of arrays
/**
* @dataProvider provider
*/
public function testAdd($a, $b, $c)
{
$this->assertEquals($c, $a + $b);
}
public function provider()
{
return array(
array(0, 0, 0),
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 3)
19. Testing Exceptions : Tests whether an exception is
/Filename : exceptionclass.php
?php
thrown inside the tested code.
ni_set('display_errors', 1);
lass myexcepclass extends Exception {
unction checkNum($number)
{
if($number>1)
{
throw new Exception("Value must be 1 or below");
}
return true;
20. ?php
Test class for exceptionclass.php
equire_once '/usr/share/php/PHPUnit/Framework/TestCase.php';
equire_once 'exceptionclass.php';
lass myexcepclassTest extends PHPUnit_Framework_TestCase {
**
* @expectedException InvalidArgumentException:
*/
public function testcheckNum() {
$obj = new MyCustomException;
$obj->checkNum(2);
}
21. Running the test
HPUnit 3.6.10 by Sebasroot@varuntaliyan:/var/www/tests/error# phpunit
testexceptionclass.php
ian Bergmann.
ime: 0 seconds, Memory: 2.75Mb
here was 1 failure:
) myexcepclassTest::testcheckNum
ailed asserting that exception of type "Exception" matches expected exception
"InvalidArgumentException:".
AILURES!
22. Testing Output : Sometimes you want to assert that the
execution of a method, for instance, generates an expected
/Filename : outputclass.php
output
?php
ni_set('display_errors', 1);
lass Myoutputclass {
unction greetings()
{
print 'Hello Everyone';
}
unction quote()
{
print 'Its morning again';
}
23. /Filename : testoutputclass.php
?php
Test class for outputclass.php
equire_once '/usr/share/php/PHPUnit/Framework/TestCase.php';
equire_once 'outputclass.php';
lass outputclassTest extends PHPUnit_Framework_TestCase
protected $obj;
protected function setUp() {
$this->obj = new Myoutputclass;
}
public function testgreetings()
{
$this->expectOutputString('Hello Everyone');
$this->obj->greetings();
}
public function testquote()
{
$this->expectOutputString('Its noon');
$this->obj->quote();
24. Running the test
oot@varuntaliyan:/var/www/tests/output# phpunit testoutputclass.php
HPUnit 3.6.10 by Sebastian Bergmann.
F
ime: 0 seconds, Memory: 2.75Mb
here was 1 failure:
) outputclassTest::testquote
ailed asserting that two strings are equal.
-- Expected
++ Actual
@ @@
'Its noon'
'Its morning again'
AILURES!
27. Fixtures
is a “known state” of an application
need to be “set up” at the start of test
need to be “torn down” at the end of the
test
shares “states” over test methods
setUp() is where you create the objects
against which you will test.
tearDown() is where you clean up the
objects against which you tested.
More setUp() than tearDown()
28. Using setUp() to create the stack fixture
<?php
class StackTest extends PHPUnit_Framework_TestCase
{
protected $stack;
protected function setUp()
{
$this->stack = array();
}
public function testEmpty()
{
$this->assertTrue(empty($this->stack));
}
public function testPush()
{
array_push($this->stack, 'foo');
$this->assertEquals('foo', $this->stack[count($this->stack)-1]);
$this->assertFalse(empty($this->stack));
}
public function testPop()
{
array_push($this->stack, 'foo');
$this->assertEquals('foo', array_pop($this->stack));
$this->assertTrue(empty($this->stack));
}
}
?>
29. PHPUnit – Database Extension
PHPUnit Database Extension – DBUnit Port
Can be installed by : pear install
phpunit/DbUnit
Currently supported databases:
MySQL
PostgreSQL
Oracle
SQLite
has access to other database systems such as IBM
DB2 or Microsoft SQL Server Through Zend
Framework or Doctrine 2 integrations
30. The four stages of a database test
1.Set up fixture
2.Exercise System Under Test
3.Verify outcome
4.Teardown
31. Configuration of a PHPUnit Database TestCase
Need to Extend abstract TestCase :
PHPUnit_Extensions_Database_TestCase
require_once
'PHPUnit/Extensions/Database/TestCase.php';
class BankAccountDBTest extends
PHPUnit_Extensions_Database_TestCase
{
}
32. Configuration of a PHPUnit Database TestCase
Must Implement
getConnection() - Returns a database
connection wrapper.
getDataSet() - Returns the dataset to seed
the database with.
33. Implementation of getConnection() and getDataset() methods
?php
require_once 'PHPUnit/Extensions/Database/TestCase.php';
class DatabaseTest extends PHPUnit_Extensions_Database_TestCase
{
protected function getConnection()
{
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'root', '');
return $this->createDefaultDBConnection($pdo, 'testdb');
}
protected function getDataSet()
{
return $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-
account-seed.xml');
}
}
?>
34. Test class for database testing
/Filename : dbclass.php
?php
lass BankAccount {
ublic function __construct($accno, $conn, $bal=0) {
this->addData(array($accno,$bal),$conn);
unction addData($data, $conn) {
sql = "INSERT INTO bank_account (account_number, balance) VALUES (:acc,:bal)";
q = $conn->prepare($sql);
q->execute(array(':acc'=>$data[0],
35. Test case for dbclass.php
?php
equire_once 'PHPUnit/Extensions/Database/TestCase.php';
equire_once "dbclass.php";
lass BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase
protected $pdo;
public function __construct()
{
$this->pdo = new PDO('mysql:host=localhost;dbname=phpunitdb', 'root', 'root');
}
protected function getConnection()
{
return $this->createDefaultDBConnection($this->pdo, 'phpunitdb');
}
protected function getDataSet()
{
return $this->createFlatXMLDataSet('/var/www/tests/bankaccdb/files/seed.xml');
}
public function testaddData()