Clase ajutătoare

DomQuery

Tester\DomQuery este o clasă care extinde SimpleXMLElement cu căutare ușoară în HTML sau XML folosind selectori CSS.

# crearea DomQuery dintr-un șir HTML
$dom = Tester\DomQuery::fromHtml('
	<article class="post">
		<h1>Titlu</h1>
		<div class="content">Text</div>
	</article>
');

# testarea existenței elementelor folosind selectori CSS
Assert::true($dom->has('article.post'));
Assert::true($dom->has('h1'));

# găsirea elementelor ca array de obiecte DomQuery
$headings = $dom->find('h1');
Assert::same('Titlu', (string) $headings[0]);

# testarea dacă elementul corespunde selectorului (de la versiunea 2.5.3)
$content = $dom->find('.content')[0];
Assert::true($content->matches('div'));
Assert::false($content->matches('p'));

# găsirea celui mai apropiat strămoș care corespunde selectorului (de la 2.5.5)
$article = $content->closest('.post');
Assert::true($article->matches('article'));

FileMock

Tester\FileMock emulează fișiere în memorie și facilitează astfel testarea codului care folosește funcții precum fopen(), file_get_contents(), parse_ini_file() și altele similare. Exemplu de utilizare:

# Clasa testată
class Logger
{
	public function __construct(
		private string $logFile,
	) {
	}

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

# Fișier nou gol
$file = Tester\FileMock::create('');

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

# Testăm conținutul creat
Assert::same("Login\nLogout\n", file_get_contents($file));

Assert::with()

Nu este o aserțiune, ci un ajutor pentru testarea metodelor și proprietăților private ale obiectelor.

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

$ent = new Entity;

Assert::with($ent, function () {
	Assert::true($this->enabled); // proprietatea privată $ent->enabled este accesibilă
});

Helpers::purge()

Metoda purge() creează directorul specificat și, dacă există deja, șterge întregul său conținut. Este utilă pentru crearea unui director temporar. De exemplu, în tests/bootstrap.php:

@mkdir(__DIR__ . '/tmp');  # @ - directorul poate exista deja

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

Environment::lock()

Testele se rulează în paralel. Uneori, însă, avem nevoie ca rularea testelor să nu se suprapună. Tipic la testele de baze de date, este necesar ca un test să pregătească conținutul bazei de date și alt test să nu intervină în baza de date pe durata rulării sale. În aceste teste folosim Tester\Environment::lock($name, $dir):

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

Primul parametru este numele blocării, al doilea este calea către directorul pentru stocarea blocării. Testul care obține blocarea primul rulează, celelalte teste trebuie să aștepte finalizarea sa.

Environment::bypassFinals()

Clasele sau metodele marcate ca final sunt dificil de testat. Apelul Tester\Environment::bypassFinals() la începutul testului face ca cuvintele cheie final să fie omise în timpul încărcării codului.

require __DIR__ . '/bootstrap.php';

Tester\Environment::bypassFinals();

class MyClass extends NormallyFinalClass  # <-- NormallyFinalClass nu mai este final
{
	// ...
}

Environment::setup()

  • îmbunătățește lizibilitatea afișării erorilor (inclusiv colorarea), altfel este afișat stack trace-ul PHP implicit
  • activează verificarea că au fost apelate aserțiuni în test, altfel un test fără aserțiuni (de exemplu, uitate) trece de asemenea
  • la utilizarea --coverage, pornește automat colectarea informațiilor despre codul rulat (descris mai jos)
  • afișează starea OK sau FAILURE la sfârșitul scriptului

Environment::setupFunctions()

Creează funcțiile globale test(), testException(), setUp() și tearDown(), în care puteți structura testele.

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

Environment::VariableRunner

Permite să se determine dacă testul a fost rulat direct sau prin intermediul Testerului.

if (getenv(Tester\Environment::VariableRunner)) {
	# rulat de Tester
} else {
	# rulat altfel
}

Environment::VariableThread

Tester rulează testele în paralel într-un număr specificat de fire de execuție. Dacă ne interesează numărul firului de execuție, îl aflăm din variabila de mediu:

echo "Rulez în firul de execuție numărul " . getenv(Tester\Environment::VariableThread);