Imagine that we have a class Math.php
with logic of calculating of fiobanacci and factorial numbers. Something like this:
<?php
class Math {
public function fibonacci($n) {
if (is_int($n) && $n > 0) {
$elements = array();
$elements[1] = 1;
$elements[2] = 1;
for ($i = 3; $i <= $n; $i++) {
$elements[$i] = bcadd($elements[$i-1], $elements[$i-2]);
}
return $elements[$n];
} else {
throw new
InvalidArgumentException('You should pass integer greater than 0');
}
}
public function factorial($n) {
if (is_int($n) && $n >= 0) {
$factorial = 1;
for ($i = 2; $i <= $n; $i++) {
$factorial *= $i;
}
return $factorial;
} else {
throw new
InvalidArgumentException('You should pass non-negative integer');
}
}
}
We want to test logic of methods fibonacci
and factorial
. Let's create file MathTest.php
into the same directory with Math.php
. In our code we can use different assertions. The simplest code will be something like this (we use only assertEquals
and assertTrue
):
<?php
require 'Math.php';
use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;
class MathTest extends TestCase{
public function testFibonacci() {
$math = new Math();
$this->assertEquals(34, $math->fibonacci(9));
}
public function testFactorial() {
$math = new Math();
$this->assertEquals(120, $math->factorial(5));
}
public function testFactorialGreaterThanFibonacci() {
$math = new Math();
$this->assertTrue($math->factorial(6) > $math->fibonacci(6));
}
}
We can run this test from console with command phpunit MathTest
and output will be:
PHPUnit 5.3.2 by Sebastian Bergmann and contributors.
... 3 / 3 (100%)
Time: 88 ms, Memory: 10.50Mb
OK (3 tests, 3 assertions)
A test method can accept arbitrary arguments. These arguments are to be provided by a data provider method. The data provider method to be used is specified using the @dataProvider
annotation.
:
<?php
require 'Math.php';
use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;
class MathTest extends TestCase {
/**
* test with data from dataProvider
* @dataProvider providerFibonacci
*/
public function testFibonacciWithDataProvider($n, $result) {
$math = new Math();
$this->assertEquals($result, $math->fibonacci($n));
}
public function providerFibonacci() {
return array(
array(1, 1),
array(2, 1),
array(3, 2),
array(4, 3),
array(5, 5),
array(6, 8),
);
}
}
We can run this test from console with command phpunit MathTest
and output will be:
PHPUnit 5.3.2 by Sebastian Bergmann and contributors.
...... 6 / 6 (100%)
Time: 97 ms, Memory: 10.50Mb
OK (6 tests, 6 assertions)
<?php
require 'Math.php';
use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;
We can test whether an exception is thrown by the code under test using method expectException()
. Also in this example we add one failed test to show console output for failed tests.
<?php
require 'Math.php';
use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;
class MathTest extends TestCase {
public function testExceptionsForNegativeNumbers() {
$this->expectException(InvalidArgumentException::class);
$math = new Math();
$math->fibonacci(-1);
}
public function testFailedForZero() {
$this->expectException(InvalidArgumentException::class);
$math = new Math();
$math->factorial(0);
}
}
We can run this test from console with command phpunit MathTest
and output will be:
PHPUnit 5.3.2 by Sebastian Bergmann and contributors.
.F 2 / 2 (100%)
Time: 114 ms, Memory: 10.50Mb
There was 1 failure:
1) MathTest::testFailedForZero
Failed asserting that exception of type "InvalidArgumentException" is thrown.
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
Also PHPUnit
supports sharing the setup code. Before a test method is run, a template method called setUp() is invoked. setUp()
is where you create the objects against which you will test. Once the test method has finished running, whether it succeeded or failed, another template method called tearDown()
is invoked. tearDown()
is where you clean up the objects against which you tested.
<?php
require 'Math.php';
use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;
class MathTest extends TestCase {
public $fixtures;
protected function setUp() {
$this->fixtures = [];
}
protected function tearDown() {
$this->fixtures = NULL;
}
public function testEmpty() {
$this->assertTrue($this->fixtures == []);
}
}
There are much more great opportunities of PHPUnit
which you can use in your test. For more info see in official manual