unit testing using phpunit
Post on 17-May-2015
3.687 Views
Preview:
TRANSCRIPT
PHPUnitAutomated Unit Testing Framework.
By : Varun TaliyanOSSCube Solutions Pvt. Ltd.
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.
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
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.
Installing PHPUnit PHPUnit is installed using the PEAR
Installer Commands to install :
pear config-set auto_discover 1 pear install pear.phpunit.de/PHPUnit
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.
Sample PHP class for testing//Filename : user.php<?phpclass User { protected $name; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function talk() { return "Hello world!"; }}?>
Test class for testing user.php
<?phprequire_once "PHPUnit/Autoload.php";require_once "user.php";
class UserTest extends PHPUnit_Framework_TestCase{}?>
Test class for testing user.php
<?php...class 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); }}
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.
Running our Tests
root@varuntaliyan:/var/www/test-1# phpunit userTest.phpPHPUnit 3.6.10 by Sebastian Bergmann..
Time: 0 seconds, Memory: 2.75Mb
OK (1 test, 1 assertion)
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.
Output when a Test fails
root@varuntaliyan:/var/www/test-1# phpunit userTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.
FaTime: 0 seconds, Memory: 2.75Mb
There was 1 failure:
1) UserTest::testTalkFailed asserting that two strings are equal.--- Expected+++ Actual@@ @@-'Hello world!'+'Non sense'
/var/www/test-1/userTest.php:14
FAILURES!Tests: 1, Assertions: 1, Failures: 1.
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.
Using the @depends annotation to express dependencies
<?phpclass StackTest extends PHPUnit_Framework_TestCase{ public function testEmpty() { $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) { $this->assertEquals('foo', array_pop($stack)); $this->assertEmpty($stack); }}?>
Running the Test
:/var/www/test-1# phroot@varuntaliyanpunit depend.php PHPUnit 3.6.10 by Sebastian Bergmann.
...
Time: 0 seconds, Memory: 2.75Mb
OK (3 tests, 5 assertions)
Data Providers
A test method can accept arbitrary argumeants. These arguments are to be provided by a data provider methods.
Using a data provider that returns an array of arrays
<?phpclass DataTest extends PHPUnit_Framework_TestCase{ /** * @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) ); }}?>
Testing Exceptions : Tests whether an exception is
thrown inside the tested code.
//Filename : exceptionclass.php<?phpini_set('display_errors', 1);class myexcepclass extends Exception {function checkNum($number) { if($number>1) { throw new Exception("Value must be 1 or below"); } return true; }}?>
Test class for exceptionclass.php
<?phprequire_once '/usr/share/php/PHPUnit/Framework/TestCase.php';require_once 'exceptionclass.php';class myexcepclassTest extends PHPUnit_Framework_TestCase {/** * @expectedException InvalidArgumentException: */
public function testcheckNum() {$obj = new MyCustomException;$obj->checkNum(2);
}}?>
Running the test PHPUnit 3.6.10 by Sebasroot@varuntaliyan:/var/www/tests/error# phpunit testexceptionclass.php tian Bergmann.FTime: 0 seconds, Memory: 2.75Mb
There was 1 failure:
1) myexcepclassTest::testcheckNumFailed asserting that exception of type "Exception" matches expected exception "InvalidArgumentException:".
FAILURES!Tests: 1, Assertions: 1, Failures: 1.
Testing Output : Sometimes you want to assert that the execution of a method, for instance, generates an expected output
//Filename : outputclass.php<?phpini_set('display_errors', 1);class Myoutputclass {function greetings() {
print 'Hello Everyone'; }function quote() {
print 'Its morning again'; }}?>
Test class for outputclass.php
//Filename : testoutputclass.php<?phprequire_once '/usr/share/php/PHPUnit/Framework/TestCase.php';require_once 'outputclass.php';
class 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(); } }?>
Running the test
root@varuntaliyan:/var/www/tests/output# phpunit testoutputclass.php PHPUnit 3.6.10 by Sebastian Bergmann.
.F
Time: 0 seconds, Memory: 2.75Mb
There was 1 failure:
1) outputclassTest::testquoteFailed asserting that two strings are equal.--- Expected+++ Actual@@ @@-'Its noon'+'Its morning again'
FAILURES!Tests: 2, Assertions: 2, Failures: 1.
Assertions assertArrayHasKey() assertContains() assertContainsOnly() assertCount() assertEmpty() assertEquals() assertFalse() assertClassHasAttribute() assertClassHasStaticAttribute().....
assertGreaterThan()
assertGreaterThanOrEqual()
assertInstanceOf()
assertInternalType()
assertLessThan()
assertLessThanOrEqual()
assertNull()
assertRegExp()
assertSame()
assertStringEndsWith()
assertStringStartsWith()......
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()
Using setUp() to create the stack fixture<?phpclass 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)); }}?>
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
The four stages of a database test
1.Set up fixture2.Exercise System Under Test3.Verify outcome4.Teardown
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
{}
Configuration of a PHPUnit Database TestCase
Must Implement getConnection() - Returns a database
connection wrapper.getDataSet() - Returns the dataset to seed
the database with.
Implementation of getConnection() and getDataset() methods
<?phprequire_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'); }}?>
Test class for database testing//Filename : dbclass.php<?phpclass BankAccount {public function __construct($accno, $conn, $bal=0) {$this->addData(array($accno,$bal),$conn);}function addData($data, $conn) {$sql = "INSERT INTO bank_account (account_number, balance) VALUES (:acc,:bal)";$q = $conn->prepare($sql);$q->execute(array(':acc'=>$data[0], ':bal'=>$data[1]));}}
Test case for dbclass.php <?phprequire_once 'PHPUnit/Extensions/Database/TestCase.php';require_once "dbclass.php";class 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() { $bank_account = new BankAccount('1234567', $this->pdo); $xml_dataset = $this->createFlatXMLDataSet('/var/www/tests/bankaccdb/files/seed-after-insert.xml'); $this->assertTablesEqual($xml_dataset->getTable('bank_account'),$this->getConnection()->createDataSet()->getTable('bank_account')); }}
Running the test root@varuntaliyan:/var/www/tests/bankaccdb# phpunit dbclasstest.php PHPUnit 3.6.10 by Sebastian Bergmann..Time: 0 seconds, Memory: 3.00Mb
OK (1 test, 1 assertion)
Output when a Test failsroot@varuntaliyan:/var/www/tests/bankaccdb# phpunit dbclasstest.php PHPUnit 3.6.10 by Sebastian Bergmann.FTime: 0 seconds, Memory: 3.00MbThere was 1 failure:1) BankAccountDBTest::testaddDataFailed asserting that +----------------------+----------------------+| bank_account |+----------------------+----------------------+| account_number | balance |+----------------------+----------------------+| 1593490 | 100 |+----------------------+----------------------+| 1593648 | 1216 |+----------------------+----------------------+| 1234861 | 89 |+----------------------+----------------------+| 1593648 | 1216 |+----------------------+----------------------+| 1234567 | 0 |+----------------------+----------------------+
is equal to expected
+----------------------+----------------------+
| bank_account |
+----------------------+----------------------+
| account_number | balance |
+----------------------+----------------------+
| 1593490 | 100.00 |
+----------------------+----------------------+
| 1593648 | 1216.00 |
+----------------------+----------------------+
| 1234861 | 89.00 |
+----------------------+----------------------+
| 1593648 | 1216.00 |
+----------------------+----------------------+
/var/www/tests/bankaccdb/dbclasstest.php:29
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
Thank you - Resources http://
www.phpunit.de/manual/3.6/en/index.html
http://www.ds-o.com/archives/63-PHPUnit-Database-Extension-DBUnit-Port.html
top related