Unit Testing using PHPUnit


Published on

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Unit Testing using PHPUnit

  1. 1. PHPUnitAutomated Unit Testing Framework. By : Varun Taliyan OSSCube Solutions Pvt. Ltd.
  2. 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. 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. 4. PHPUnits 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. 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. 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. 7. /Filename : user.php?php Sample PHP class for testinglass User { protected $name; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function talk() { return "Hello world!";
  8. 8. Test class for testing user.php?phpequire_once "PHPUnit/Autoload.php";equire_once "user.php";lass UserTest extendsPHPUnit_Framework_TestCase
  9. 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. 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.
  11. 11. Running our Testsoot@varuntaliyan:/var/www/test-1# phpunituserTest.phpHPUnit 3.6.10 by Sebastian Bergmann.ime: 0 seconds, Memory: 2.75MbK (1 test, 1 assertion)
  12. 12. For each test run, the PHPUnit command-linetool 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. 13. Output when a Test failsoot@varuntaliyan:/var/www/test-1# phpunit userTest.phpHPUnit 3.6.10 by Sebastian Bergmann.ime: 0 seconds, Memory: 2.75Mbhere was 1 failure:) UserTest::testTalkailed asserting that two strings are equal.-- Expected++ Actual@ @@Hello world!Non sensevar/www/test-1/userTest.php:14
  14. 14. Test Dependencies PHPUnit supports the declaration of explicit dependenciesbetween test methods. Such dependencies do not define theorder in which the test methods are to be executed but they allowthe returning of an instance of the test fixture by a producer andpassing it to the dependent consumers. A producer is a test method that yields its unit under test asreturn value. A consumer is a test method that depends on one or moreproducers and their return values.
  15. 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. 16. Running the Test/var/www/test-1# phroot@varuntaliyanpunit depend.phpHPUnit 3.6.10 by Sebastian Bergmann...ime: 0 seconds, Memory: 2.75MbK (3 tests, 5 assertions)
  17. 17. Data Providerstest method can accept arbitraryargumeants. These arguments are tobe provided by a data providermethods.
  18. 18. lass DataTest extends PHPUnit_Framework_TestCaseUsing 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. 19. Testing Exceptions : Tests whether an exception is/Filename : exceptionclass.php?phpthrown 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. 20. ?phpTest class for exceptionclass.phpequire_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. 21. Running the testHPUnit 3.6.10 by Sebasroot@varuntaliyan:/var/www/tests/error# phpunittestexceptionclass.phpian Bergmann.ime: 0 seconds, Memory: 2.75Mbhere was 1 failure:) myexcepclassTest::testcheckNumailed asserting that exception of type "Exception" matches expected exception"InvalidArgumentException:".AILURES!
  22. 22. Testing Output : Sometimes you want to assert that theexecution of a method, for instance, generates an expected/Filename : outputclass.phpoutput?phpni_set(display_errors, 1);lass Myoutputclass {unction greetings(){print Hello Everyone;}unction quote(){print Its morning again;}
  23. 23. /Filename : testoutputclass.php?php Test class for outputclass.phpequire_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. 24. Running the testoot@varuntaliyan:/var/www/tests/output# phpunit testoutputclass.phpHPUnit 3.6.10 by Sebastian Bergmann.Fime: 0 seconds, Memory: 2.75Mbhere was 1 failure:) outputclassTest::testquoteailed asserting that two strings are equal.-- Expected++ Actual@ @@Its noonIts morning againAILURES!
  25. 25. Assertions assertArrayHasKey() assertContains() assertContainsOnly() assertCount() assertEmpty() assertEquals() assertFalse() assertClassHasAttribute() assertClassHasStaticAttribute().....
  26. 26.  assertGreaterThan() assertGreaterThanOrEqual() assertInstanceOf() assertInternalType() assertLessThan() assertLessThanOrEqual() assertNull() assertRegExp() assertSame() assertStringEndsWith() assertStringStartsWith()......
  27. 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. 28. 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)); }}?>
  29. 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. 30. The four stages of a database test 1.Set up fixture 2.Exercise System Under Test 3.Verify outcome 4.Teardown
  31. 31. Configuration of a PHPUnit Database TestCase Need to Extend abstract TestCase : PHPUnit_Extensions_Database_TestCaserequire_once PHPUnit/Extensions/Database/TestCase.php;class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase{}
  32. 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. 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. 34. Test class for database testing/Filename : dbclass.php?phplass 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. 35. Test case for dbclass.php?phpequire_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()
  36. 36. Running the testoot@varuntaliyan:/var/www/tests/bankaccdb# phpunit dbclasstest.phpHPUnit 3.6.10 by Sebastian Bergmann.ime: 0 seconds, Memory: 3.00Mb
  37. 37. Output when a Test failsoot@varuntaliyan:/var/www/tests/bankaccdb# phpunit dbclasstest.phpHPUnit 3.6.10 by Sebastian Bergmann.ime: 0 seconds, Memory: 3.00Mbhere was 1 failure:) BankAccountDBTest::testaddDataailed asserting that----------------------+----------------------+bank_account |----------------------+----------------------+ account_number | balance |----------------------+----------------------+ 1593490 | 100 |----------------------+----------------------+ 1593648 | 1216 |
  38. 38. +----------------------+----------------------+| bank_account |+----------------------+----------------------+| account_number | balance |+----------------------+----------------------+| 1593490 | 100.00 |+----------------------+----------------------+| 1593648 | 1216.00 |+----------------------+----------------------+| 1234861 | 89.00 |+----------------------+----------------------+| 1593648 | 1216.00 |+----------------------+----------------------+/var/www/tests/bankaccdb/dbclasstest.php:29FAILURES!Tests: 1, Assertions: 1, Failures: 1.
  39. 39. 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