Tester: vlastní Output Handler

Output Handler umožňuje změnit finální podobu výstupu z Nette Testeru. Výstup může vypadat například takto. Osobně se mi tento výstup líbí víc, protože místo teček rovnou vidím co se skutečně spouští. Může se to hodit a sám jsem se přistil, že občas spouštím testy takto:

vendor/bin/run-tests -o tap

A to jen proto, abych viděl co se zrovna testuje (TAP). Napsat si vlastní výstupní handler je jednoduché. Jen je třeba dávat pozor na to, co je napsáno v dokumentaci, protože to nemusí být dobře… :)

Stačí Tester spouštět s přepínačem --setup:

vendor/bin/tester --setup tests/runner-setup.php

# or Testbench edition:
vendor/bin/run-tests --setup tests/runner-setup.php

Skript runner-setup.php potom obsahuje samotný handler který může vypadat třeba takto (PHP 7):

<?php declare(strict_types = 1);

use Tester\Dumper;
use Tester\Runner\Runner;

/** @var \Tester\Runner\Runner $runner */
$runner->outputHandlers = []; // delete native output handlers
$runner->outputHandlers[] = new class ($runner) extends \Tester\Runner\Output\ConsolePrinter
{

    public function begin()
    {
        ob_start();
        parent::begin();
        echo rtrim(ob_get_clean()) . ' | ' . getenv('BOOTSTRAP') . "\n\n";
    }

    public function result($testName, $result, $message)
    {
        $outputs = [
            Runner::PASSED => Dumper::color('green', '✔ ' . $testName),
            Runner::SKIPPED => Dumper::color('olive', 's ' . $testName) . "($message)",
            Runner::FAILED => Dumper::color('red', '✖ ' . $testName) . "\n" . $this->indent($message, 3) . "\n",
        ];
        echo $this->indent($outputs[$result], 2) . PHP_EOL;
    }

    public function end()
    {
        ob_start();
        parent::end();
        echo "\n" . trim(ob_get_clean()) . "\n";
    }

    private function indent($message, $spaces)
    {
        if ($message) {
            $result = '';
            foreach (explode(PHP_EOL, $message) as $line) {
                $result .= str_repeat(' ', $spaces) . $line . PHP_EOL;
            }
            return rtrim($result, PHP_EOL);
        }
        return $message;
    }

};

Je to vlastně jen o třech metodách. Začátek begin a konec end slouží jen k ořezání mezer popř. k doplnění dodatečných informací. Nejzajímavější je metoda result, která velmi mění způsob vykreslení jednotlivých řádek. Bohužel Tester sám od sebe ořezává výstupní texty a podle toho jak jsem to rychle prohlížel, tak s tím nejde nic moc udělat. Představoval bych si, že výstupní texty budou trošku lepší, ale to bez PR do Nette\Testru asi nepůjde…

To by bylo. Pozornější čtenáři kódu mohou mít teď otázku co je to getenv('BOOTSTRAP')? Dlouze jsem řešil jak psát testy s ohledem na to, že se mi nechce pořád dělat require bootstrap.php, protože mám testy hodně zanořené a cesty k tomutou souboru bývají hodně dlouhé. Navíc je to nesmírně limitující, protože nelze jednoduše bez úpravy testů měnit adresářovou strukturu. Řešením je trošku to obejít:

require getenv('BOOTSTRAP');

Existuje více řešení, ale toto mi sedělo nejlépe. Užitečné je pak napsat si vlastní skript tests/run a všechno to spojit:

#!/usr/bin/env bash

BOOTSTRAP=$(pwd)/tests/bootstrap.php vendor/bin/run-tests --setup tests/runner-setup.php

Spuštění je tak jednoduché, jako je jednoduché napsat tests/run. Pokud by si to chtěl někdo prohlédnout více detailně a popř. si s tím pohrát, tak je vše zde popisované implementováno v projektu Adeira\Connector na GitHubu.

:)

  • V komentářích jsou povolené HTML tagy <a href=""> <blockquote> <code> <em> <strong>
  • Kódy programů zapisujte takto pomocí <pre><code>alert('XSS');</code></pre>