Spouštění testů
Nejviditelnější součástí Nette Testeru je spouštěč testů z příkazové řádky. Je neobyčejně rychlý a robustní, neboť automaticky spouští všechny testy jako samostatné procesy, a to paralelně ve více vláknech. Také se umí spouštět sám v tzv. watch režimu.
Spouštěč testů voláme z příkazové řádky. Jako parametr uvedeme adresář s testy. Pro aktuální adresář stačí zadat tečku:
vendor/bin/tester .
Spouštěč testů prohledá zadaný adresář a všechny podadresáře a vyhledá testy, což jsou soubory *.phpt
a *Test.php. Zároveň čte a vyhodnocuje jejich anotace, aby věděl, které
z nich a jak spouštět.
Každý testovací soubor běží ve vlastním izolovaném PHP procesu a spouštěč jich několik zpracovává najednou – jednotkou paralelismu je tedy soubor. Kód uvnitř jednoho souboru proto běží sekvenčně. TestCase je jeden soubor, takže jeho metody se ve výchozím stavu vykonávají jedna po druhé v rámci jediného procesu; anotací @testCase docílíte toho, že spouštěč spustí každou testovací metodu jako samostatný paralelní proces.
Poté spustí testy. Během provádění testů vypisuje průběžně výsledky na terminál jako znaky:
.– test prošels– test byl přeskočen (skipped)F– test selhal (failed)
Výstup může vypadat třeba takto:
_____ ___ ___ _____ ___ ___
|_ _/ __)( __/_ _/ __)| _ )
|_| \___ /___) |_| \___ |_|_\ v2.7.1
PHP 8.5.2 (cli) | php | 8 threads
........s..........................
OK (35 tests, 1 skipped, 1.7 seconds)
Při opakovaném spuštění nejprve provádí testy, které při předchozím běhu selhaly, takže se okamžitě dozvíte, jestli se vám chybu podařilo opravit.
Pokud žádný test neselže, návratový kód Testeru je nula. Jinak je návratový kód nenulový.
Pokud Tester nenajde vůbec žádný test, třeba kvůli překlepu v cestě, skončí také nenulovým kódem. Build na CI serveru tak nemůže projít, aniž by se cokoli otestovalo.
Parametry příkazové řádky
Přehled všech voleb příkazové řádky získáme spuštěním Testeru bez parametrů, anebo s parametrem
-h:
_____ ___ ___ _____ ___ ___
|_ _/ __)( __/_ _/ __)| _ )
|_| \___ /___) |_| \___ |_|_\ v2.7.1
Usage:
tester [options] [<test file> | <directory>]...
Options:
-p <path> Specify PHP interpreter to run (default: php).
-c <path> Use custom php.ini, ignore system configuration.
-C With -c, include system configuration as well.
-d <key=value>... Define INI entry 'key' with value 'value'.
-s Show information about skipped tests.
--stop-on-fail Stop execution upon the first failure.
--timeout <seconds> Time limit for each test in seconds, can be overridden by @timeout.
-j <num> Run <num> jobs in parallel (default: 8).
-o <console|console-lines|github|tap|junit|log|none> (e.g. -o junit:output.xml)
Specify one or more output formats with optional file name.
-w | --watch <path> Watch directory.
--slowest [<count>] Print the 10 (or <count>) slowest tests after the run.
-i | --info Show tests environment info and exit.
--setup <path> Script for runner setup.
--temp <path> Path to temporary directory. Default by sys_get_temp_dir().
--colors [1|0] Enable or disable colors.
--coverage <path> Generate code coverage report to file.
--coverage-src <path> Path to source code.
-h | --help This help.
--version Show version and exit.
-p <path>
Určuje PHP binárku, která se bude používat pro spouštění testů. Standardně je to php.
tester -p /home/user/php-7.2.0-beta/php-cgi tests
-c <path>
Použije vlastní php.ini soubor a ignoruje systémovou konfiguraci. Více v části Vlastní php.ini.
-C
Při použití společně s -c zachová i systémovou konfiguraci (neignoruje ji). Více v části Vlastní php.ini.
-d <key=value>
Nastavuje hodnotu PHP konfigurační direktivy pro testy. Parametr může být použit vícekrát.
tester -d max_execution_time=20
-s
Zobrazí se informace o přeskočených testech.
--stop-on-fail
Tester zastaví testování u prvního selhávajícího testu.
--timeout <seconds>
Nastaví časový limit v sekundách pro každý test. Bez něj test, který se zasekne, třeba když čeká na server, který nikdy neodpoví, nebo uvízne v nekonečné smyčce, nechá čekat celé testování. Na CI serveru to znamená úlohu, která skončí, až když ji server sám ukončí, a vy se nedozvíte, který test za to mohl.
S časovým limitem Tester po vypršení času proces testu ukončí, test označí jako selhaný a pokračuje s ostatními:
tester --timeout 30 tests
Ve výpisu chyb pak uvidíte, který test se zasekl:
-- FAILED: database.phpt Timed out after 30 s
Ve výchozím stavu testy žádný časový limit nemají. Jednotlivý test si může nastavit vlastní limit, nebo ho vypnout, anotací @timeout.
-j <num>
Určuje, kolik paralelních procesů s testy se spustí. Výchozí hodnota je 8. Chceme-li, aby všechny testy proběhly v sérii, použijeme hodnotu 1.
-o <console|console-lines|github|tap|junit|log|none>
Nastaví formát výstupu. Výchozí je formát pro konzoli. Můžete uvést jméno souboru, do kterého se výstup zapíše
(např. -o junit:output.xml). Volbu -o lze zopakovat vícekrát a vygenerovat tak více formátů
najednou.
console: shodné s výchozím formátem, ale v tomto případě se nezobrazí ASCII logoconsole-lines: podobné jako console, ale výsledek každého testu je uveden na samostatném řádku s dalšími informacemigithub: anotace pro GitHub Actions, díky kterým se selhaný test zobrazí v pull requestu přímo u řádku, kde selhal, i s chybovou hláškoutap: TAP formát vhodný pro strojové zpracováníjunit: XML formát JUnit, taktéž vhodný pro strojové zpracovánílog: Výstupy průběhu testování. Všechny neúspěšné, přeskočené a také úspěšné testynone: nic se nevypisuje
Když Tester běží na GitHub Actions, přidá formát github sám. V běžném workflow
tak nemusíte nic nastavovat a selhané testy uvidíte v pull requestu hned, přičemž výstup do konzole zůstává jako
obvykle. Pokud formát standardního výstupu zvolíte sami přes -o, například -o tap, Tester to
respektuje a anotace nepřidá, aby se oba výstupy nesmíchaly.
-w | --watch <path>
Po dokončení testování Tester neskončí, ale zůstane běžet a sleduje PHP soubory v uvedeném adresáři. Při změně spustí testy znova. Parametr může být použit vícekrát, pokud chceme sledovat více adresářů.
Hodí se při refactoringu knihovny nebo ladění testů.
tester --watch src tests
--slowest [<count>]
Po dokončení testů vypíše nejpomalejší testy a jak dlouho který běžel. Hodí se, když se testování začne zpomalovat a chcete vědět, kterým testům se věnovat nejdřív. Ve výchozím stavu jich vypíše 10, jiný počet můžete uvést za volbou:
tester --slowest 3 tests ... Slowest tests: · database.phpt in 1.049 s · mail.phpt in 0.475 s · form.phpt in 0.089 s
-i | --info
Zobrazí informace o běhovém prostředí pro testy. Například:
tester -p /usr/bin/php7.1 -c tests/php.ini --info PHP binary: /usr/bin/php7.1 PHP version: 7.1.7-1+0~20170711133844.5+jessie~1.gbp5284f4 (cli) Code coverage engines: (not available) Loaded php.ini files: /var/www/dev/demo/tests/php.ini PHP temporary directory: /tmp Loaded extensions: Core, ctype, date, dom, ereg, fileinfo, filter, hash, ...
--version
Vypíše jen verzi Testeru, například Nette Tester 2.7.1, a skončí. Na rozdíl od úvodního banneru se tento
výstup snadno zpracuje ve skriptech.
--setup <path>
Tester při startu načte zadaný PHP skript. V něm je k dispozici proměnná Tester\Runner\Runner $runner.
Předpokládejme soubor tests/runner-setup.php s obsahem:
$runner->outputHandlers[] = new MyOutputHandler;
Tester spustíme:
tester --setup tests/runner-setup.php tests
--temp <path>
Nastaví cestu k adresáři pro dočasné soubory Testeru. Výchozí hodnotu vrací sys_get_temp_dir(). Není-li
výchozí hodnota validní, budete upozorněni.
Pokud si nejsme jisti, jaký adresář se používá, spustíme Tester s parametrem --info.
--colors 1|0
Ve výchozím stavu Tester detekuje barevný terminál a obarvuje svůj výstup. Tato volba autodetekci přebíjí. Globálně
můžeme obarvování nastavit systémovou proměnnou prostředí NETTE_TESTER_COLORS.
--coverage <path>
Tester vygeneruje report s přehledem, kolik zdrojového kódu testy pokrývají. Tato volba vyžaduje instalované PHP rozšíření Xdebug, nebo PCOV, anebo PHPDBG SAPI, které je rychlejší. Přípona cílového souboru určuje jeho formát. Buď HTML, nebo Clover XML.
tester tests --coverage coverage.html # HTML report tester tests --coverage coverage.xml # Clover XML report
Priorita výběru mechanismu je následující:
- PCOV
- PHPDBG
- Xdebug
Při použití PHPDBG můžeme u obsáhlých testů narazit na selhání testu kvůli vyčerpání paměti. Sběr informací
o pokrytém kódu je paměťově náročný. V tomto případě nám pomůže volání
Tester\CodeCoverage\Collector::flush() uvnitř testu. Zapíše nasbíraná data na disk a paměť uvolní. Volání
má efekt jen s enginem PHPDBG; při PCOV, Xdebugu nebo když sběr dat neprobíhá, je bez efektu.
Ukázka HTML reportu s pokrytím kódu.
--coverage-src <path>
Použijeme současně s volbou --coverage. <path> je cesta ke zdrojovým kódům, pro které
se report generuje. Může se použít opakovaně.
Vlastní php.ini
Pro testy můžete použít vlastní php.ini soubor. Pokud potřebujete specifická rozšíření nebo speciální
INI nastavení, doporučujeme vytvořit vlastní php.ini, který bude distribuován s testy. Tester pak spouštíme
s parametrem -c, například tester -c tests/php.ini tests, kde INI soubor může vypadat takto:
[PHP]
extension=php_pdo_mysql.dll
extension=php_pdo_pgsql.dll
memory_limit=512M
Při použití -c Tester ignoruje systémovou konfiguraci (spouští PHP s příznakem -n).
Chcete-li zachovat i systémovou konfiguraci, přidejte volbu -C: tester -c tests/php.ini -C tests. Ani
při kombinaci -c a -C se nenačtou v UNIXu ostatní INI soubory z /etc/php/conf.d/*.ini.
To je vlastnost PHP, ne Testeru.
Do verze 2.6 Tester bez uvedení -c spouštěl PHP s parametrem -n, tedy bez php.ini;
volba -C toto potlačila. Od verze 2.6 se systémové php.ini načítá automaticky. Chování při použití
-c zůstává stejné.