Začetek dela s Testerjem
Tudi dobri programerji delajo napake. Razlika med dobrim in slabim programerjem je v tem, da jih bo dober programer naredil le enkrat, naslednjič pa jih bo odkril z uporabo avtomatiziranih testov.
- “Kdor ne testira, je obsojen na ponavljanje lastnih napak.” (modri pregovor)
- “Ko se znebimo ene napake, se pojavi druga.” (Murphyjev zakon)
- “Kadarkoli vas mika, da bi natisnili izjavo, jo namesto tega napišite kot test.” (Martin Fowler)
Ste v PHP kdaj napisali naslednjo kodo?
$obj = new MyClass;
$result = $obj->process($input);
var_dump($result);
Ste že kdaj izpisali rezultat klica funkcije samo zato, da bi na oko preverili, ali vrne tisto, kar bi morala vrniti? Zagotovo to počnete večkrat na dan. Z roko na srcu, če vse deluje, izbrišete to kodo in pričakujete, da se razred v prihodnosti ne bo pokvaril? Murphyjev zakon zagotavlja nasprotno :-)
Pravzaprav ste test napisali vi. Potrebuje rahlo spremembo, da ne bi zahteval našega pregleda, temveč da bi se preprosto lahko preveril sam. In če ga ne bi izbrisali, bi ga lahko kadar koli v prihodnosti zagnali in preverili, ali vse še vedno deluje, kot mora. Sčasoma lahko ustvarite veliko število teh testov, zato bi bilo lepo, če bi jih lahko izvajali samodejno.
In Nette Tester pomaga prav pri tem.
V čem je Tester edinstven?
Pisanje testov za Nette Tester je edinstveno, saj je kakršen test standardna skripta PHP, ki jo lahko zaženete samostojno.
Ko napišete test, ga lahko preprosto zaženete in preverite, ali je prišlo do programske napake. Če deluje pravilno. Če ne, lahko program preprosto pregledate v svojem IDE in poiščete napako. Lahko ga celo odprete v brskalniku.
In kar je najpomembneje – z njegovim zagonom boste opravili test. Takoj boste izvedeli, ali je bil uspešno ali neuspešno
opravljen. Kako? Pokažimo tukaj. Napišimo trivialen test za uporabo polja PHP in ga shranimo v datoteko
ArrayTest.php
:
<?php
use Tester\Assert;
require __DIR__ . '/vendor/autoload.php'; # load Composer autoloader
Tester\Environment::setup(); # initialization of Nette Tester
$stack = [];
Assert::same(0, count($stack)); # we expect count() to return zero
$stack[] = 'foo';
Assert::same(1, count($stack)); # we expect count() to return one
Assert::contains('foo', $stack); # verify that the $stack contains the item 'foo'
Kot lahko vidite, se metode za potrjevanje, kot je
Assert::same()
, uporabljajo za potrjevanje, da se dejanska vrednost ujema s pričakovano vrednostjo.
Test je napisan, lahko ga zaženemo iz ukazne vrstice. Prvi zagon bo razkril morebitne sintaktične napake, in če niste naredili tiskarske napake, boste videli:
$ php ArrayTest.php
OK
Poskusite v testu spremeniti izjavo na Assert::contains('XXX', $stack);
in opazujte, kaj se bo zgodilo ob
zagonu:
$ php ArrayTest.php Failed: ['foo'] should contain 'XXX' in ArrayTest.php(17) Assert::contains('XXX', $stack); FAILURE
O pisanju nadaljujemo v poglavju Pisanje testov.
Namestitev in zahteve
Najmanjša zahtevana različica PHP, ki jo zahteva Tester, je 7.1 (za več podrobnosti glejte preglednico podprtih različic PHP ). Najprimernejši način namestitve je Composer:
composer require --dev nette/tester
Poskusite zagnati Nette Tester iz ukazne vrstice (brez argumentov bo prikazan le povzetek pomoči):
vendor/bin/tester
Zagon testov
Z rastjo naše aplikacije raste tudi število testov. Izvajanje testov enega za drugim ne bi bilo praktično. Zato ima Tester na voljo množični izvajalec testov, ki ga prikličemo iz ukazne vrstice. Parameter je imenik, v katerem se nahajajo testi. Pika označuje trenutni imenik.
vendor/bin/tester .
Prožilec Nette Tester preišče navedeni imenik in vse podimenike ter poišče teste, ki so datoteke *.phpt
in
*Test.php
. Našel bo tudi naš test ArrayTest.php
, saj se ujema z masko.
Nato začne s testiranjem. Vsak test zažene kot nov proces PHP, tako da teče popolnoma ločeno od drugih. Deluje vzporedno v več niti, zato je izjemno hiter. In najprej izvede teste, ki so bili med prejšnjim zagonom neuspešni, tako da boste takoj vedeli, ali ste napako odpravili.
Za vsak opravljen test izvajalec izpiše en znak, ki označuje napredek:
.
– test je bil opravljens
– test je bil preskočenF
– test ni uspel
Izpis je lahko videti takole:
_____ ___ ___ _____ ___ ___ |_ _/ __)( __/_ _/ __)| _ ) |_| \___ /___) |_| \___ |_|_\ v2.5.2 Note: No php.ini is used. PHP 8.3.2 (cli) | php -n | 8 threads ........s................F......... -- FAILED: greeting.phpt Failed: 'Hello John' should be ... 'Hello Peter' in greeting.phpt(19) Assert::same('Hello Peter', $o->say('John')); FAILURES! (35 tests, 1 failures, 1 skipped, 1.7 seconds)
Izvedenih je bilo 35 testov, eden ni uspel, eden je bil preskočen.
Nadaljujemo v poglavju Izvajanje testov.
Način opazovanja
Ali kodo refaktorirate? Ali sploh razvijate po metodologiji TDD (Test Driven Development)? Potem vam bo všeč način opazovanja. Tester spremlja izvorno kodo in se sam zažene, ko se ta spremeni.
Med razvojem imate v kotu monitorja terminal, v katerem se vam prižge zelena vrstica stanja, in ko nenadoma postane rdeča, veste, da ste pravkar naredili nekaj neželenega. To je pravzaprav odlična igra, v kateri programirate in se poskušate držati barve.
Način opazovanja zaženete s parametrom –watch.
Poročila CodeCoverage
Tester lahko ustvari poročila s pregledom, koliko izvorne kode pokrivajo testi. Poročilo je lahko v človeku berljivem formatu HTML ali Clover XML za nadaljnjo strojno obdelavo.
Oglejte si vzorec poročila HTML s pokritostjo kode.
Podprte različice PHP
različica | združljiva s PHP |
---|---|
Tester 2.5 | PHP 8.0 – 8.3 |
Tester 2.4 | PHP 7.2 – 8.2 |
Tester 2.3 | PHP 7.1 – 8.0 |
Tester 2.1 – 2.2 | PHP 7.1 – 7.3 |
Tester 2.0 | PHP 5.6 – 7.3 |
Tester 1.7 | PHP 5.3 – 7.3 + HHVM 3.3+ |
Tester 1.6 | PHP 5.3 – 7.0 + HHVM |
Tester 1.3 – 1.5 | PHP 5.3 – 5.6 + HHVM |
Tester 0.9 – 1.2 | PHP 5.3 – 5.6 |
Velja za najnovejše različice popravkov.
Do različice 1.7 je Tester podpiral HHVM 3.3.0 ali novejšo različico (z uporabo
tester -p hhvm
). Od različice Tester 2.0 je podpora ukinjena. Uporaba je bila preprosta: