KD2\Test is a unit testing library, easy to use and understand, and very lightweight and fast.
Simple example of various test methods:
use KD2\Test;
Test::assert(true, 'true should always be true');
Test::equals(true, 1, '1 is expected to be true');
Test::strictlyEquals(4, strlen('test'), 'strlen is supposed to be returning an integer of 4');
$obj = (object) ['test' => 42];
Test::isObject($obj, '$obj should be an object');
Test::isInstanceOf(\stdClass::class, $obj, 'object is not an instance of stdClass');
Test::hasPropery('test', $obj, 'Object should have a test property');
Test::exception('RuntimeException',
function () { throw new \RuntimeException('Error'); },
'Expected exception of type RuntimeException');
When a test fail, a new KD2\TestException exception will be thrown including details to the specific error.
You can also invoke private/protected methods and access private/protected properties from classes:
class MyClass
{
private $secret = 'abcd';
protected getSecret(bool $really_get = false): ?string
{
return $really_get ? $this->secret : null;
}
}
$c = new MyClass;
Test::strictlyEquals('abcd', Test::invoke($c, 'getSecret'));
Test::strictlyEquals('abcd', Test::invoke($c, 'getSecret', [true]));
Test::strictlyEquals('abcd', Test::getProperty($c, 'secret'));
Finally helper methods similar to PHPunit are available to run sets of units tests:
class MyTest
{
protected $redis;
public function setUp()
{
$this->redis = new RedisClient('localhost:6379');
$this->redis->connect();
$this->redis->select(42);
}
public function tearDown()
{
$this->redis->flushdb();
}
public function testHashTable()
{
Test::equals(1, $this->redis->hset('testhash', 'name', 'Bohwaz'));
Test::equals('BohwaZ', $this->redis->hget('testhash', 'name'));
}
public function testKeys()
{
Test::equals(1, $this->redis->set('testkey', 'pizza'));
Test::equals('pizza', $this->redis->get('testkey'));
}
}
Test::runMethods(new MyTest);
This example will run each method which name begins with 'test' in its name. If a method named 'setUp' exists it will be run before each test, and if a method named 'tearDown' exists it will be run after each test too. So in this case it is the same as doing:
$t = new MyTest;
$t->setUp();
$t->testHashTable();
$t->tearDown();
$t->setUp();
$t->testKeys();
$t->tearDown();
runMethods
returns an array containing all errors and failed assertions. If everything was fine, the array will be empty.
A second method is available to run all methods of all classes contained in a file :
Test::runFile('RedisClient.php');
Like runMethods
it will return an array containing all errors encountered.
Finally, an utility method run
, the most useful, is available to test all files in a directory and display the results. It will take either a directory or a file name and run all methods of all files, displaying the results after each file.
KD2\Test::run(__DIR__ . '/tests');
If passed a directory name, this will only select files where the name ends with Test.php
, to change that it is possible to pass a different regexp pattern as a second argument:
KD2\Test::run(__DIR__ . '/tests', '/^.*\.php$/');
Sample output:
QueueCookieTest.php: 18 successful assertions, 1 errors
1. QueueCookieTest::testConfig
[equals] Equals condition failed:
--- string(9) "localhost"
+++ string(10) "localhosst"
Line 24 in QueueCookieTest.php
RedisClientTest.php: 3 successful assertions, no errors
QueueTest.php: 49 successful assertions, no errors