Helpers

DomQuery

Tester\DomQuery is a class extending SimpleXMLElement with easy querying in HTML or XML using CSS selectors.

# create DomQuery from HTML string
$dom = Tester\DomQuery::fromHtml('
	<article class="post">
		<h1>Title</h1>
		<div class="content">Text</div>
	</article>
');

# test element existence using CSS selectors
Assert::true($dom->has('article.post'));
Assert::true($dom->has('h1'));

# find elements as an array of DomQuery objects
$headings = $dom->find('h1');
Assert::same('Title', (string) $headings[0]);

# test if element matches selector (since version 2.5.3)
$content = $dom->find('.content')[0];
Assert::true($content->matches('div'));
Assert::false($content->matches('p'));

# find the closest ancestor matching the selector (since 2.5.5)
$article = $content->closest('.post');
Assert::true($article->matches('article'));

FileMock

Tester\FileMock emulates files in memory and facilitates testing code that uses functions like fopen(), file_get_contents(), parse_ini_file() and similar. Example usage:

# Tested class
class Logger
{
	public function __construct(
		private string $logFile,
	) {
	}

	public function log(string $message): void
	{
		file_put_contents($this->logFile, $message . "\n", FILE_APPEND);
	}
}

# New empty file
$file = Tester\FileMock::create('');

$logger = new Logger($file);
$logger->log('Login');
$logger->log('Logout');

# Test the created content
Assert::same("Login\nLogout\n", file_get_contents($file));

Assert::with()

This is not an assertion, but a helper for testing private methods and properties of objects.

class Entity
{
	private $enabled;
	// ...
}

$ent = new Entity;

Assert::with($ent, function () {
	Assert::true($this->enabled); // accessible private $ent->enabled
});

Helpers::purge()

The purge() method creates the specified directory, and if it already exists, it deletes its entire content. It is useful for creating a temporary directory. For example, in tests/bootstrap.php:

@mkdir(__DIR__ . '/tmp');  # @ - directory may already exist

define('TempDir', __DIR__ . '/tmp/' . getmypid());
Tester\Helpers::purge(TempDir);

Environment::lock()

Tests run in parallel. Sometimes, however, we need for the tests' execution not to overlap. Typically, database tests require preparing the database content and ensuring no other test interferes with the database during its execution. In these tests, we use Tester\Environment::lock($name, $dir):

Tester\Environment::lock('database', __DIR__ . '/tmp');

The first parameter is the name of the lock, the second is the path to the directory for storing the lock. The test that acquires the lock first proceeds, other tests must wait for it to complete.

Environment::bypassFinals()

Classes or methods marked as final are difficult to test. Calling Tester\Environment::bypassFinals() at the beginning of a test causes the final keywords to be omitted during code loading.

require __DIR__ . '/bootstrap.php';

Tester\Environment::bypassFinals();

class MyClass extends NormallyFinalClass  # <-- NormallyFinalClass is no longer final
{
	// ...
}

Environment::setup()

  • improves the readability of error dumps (including coloring); otherwise, the default PHP stack trace is printed
  • enables checking that assertions were called in the test; otherwise, tests without assertions (e.g., forgotten ones) also pass
  • automatically starts collecting information about the executed code (when --coverage is used) (described further)
  • prints the status OK or FAILURE at the end of the script

Environment::setupFunctions()

Creates the global functions test(), testException(), setUp(), and tearDown(), into which you can structure your tests.

test('test description', function () {
	Assert::same(123, foo());
	Assert::false(bar());
	// ...
});

Environment::VariableRunner

Allows you to determine whether the test was run directly or via the Tester.

if (getenv(Tester\Environment::VariableRunner)) {
	# run by Tester
} else {
	# run some other way
}

Environment::VariableThread

Tester runs tests in parallel in the specified number of threads. If we are interested in the thread number, we find it from the environment variable:

echo "Running in thread number " . getenv(Tester\Environment::VariableThread);