Nette Documentation Preview

syntax
Začetek dela s Testerjem
************************

<div class=perex>

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)

</div>

Ste v PHP kdaj napisali naslednjo kodo?

```php
$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? .[#toc-what-makes-tester-unique]
===========================================================

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 .{file: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, |Assertions] 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:

/--pre .[terminal]
$ php ArrayTest.php

<span style="color:#FFF; background-color:#090">OK</span>
\--

Poskusite v testu spremeniti izjavo na `Assert::contains('XXX', $stack);` in opazujte, kaj se bo zgodilo ob zagonu:

/--pre .[terminal]
$ php ArrayTest.php

<span style="color: #FFF">Failed: </span><span style="color: #FF0">['foo']</span><span style="color: #FFF"> should contain </span><span style="color: #FF0">'XXX'</span>

<span style="color: #CCC">in </span><span style="color: #FFF">ArrayTest.php(17)</span><span style="color: #808080"> Assert::contains('XXX', $stack);</span>

<span style="color: #FFF; background-color: #900">FAILURE</span>
\--

O pisanju nadaljujemo v poglavju [Pisanje testov |Writing Tests].


Namestitev in zahteve .[#toc-installation-and-requirements]
===========================================================

Najmanjša zahtevana različica PHP, ki jo zahteva Tester, je 7.1 (za več podrobnosti glejte preglednico [podprtih različic PHP |#supported PHP versions] ). Najprimernejši način namestitve je [Composer |best-practices:composer]:

/--pre .[terminal]
composer require --dev nette/tester
\--

Poskusite zagnati Nette Tester iz ukazne vrstice (brez argumentov bo prikazan le povzetek pomoči):

/--pre .[terminal]
vendor/bin/tester
\--


Zagon testov .[#toc-running-tests]
==================================

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.

/--pre .[terminal]
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:

- <code style="color: #CCC; background-color: #000">.</code> - test je bil opravljen
- <code style="color: #CCC; background-color: #000">s</code> - test je bil preskočen
- <code style="color: #FFF; background-color: #900">F</code> - test ni uspel

Izpis je lahko videti takole:

/--pre .[terminal]
 _____ ___  ___ _____ ___  ___
|_   _/ __)( __/_   _/ __)| _ )
  |_| \___ /___) |_| \___ |_|_\  v2.5.2

Note: No php.ini is used.
PHP 8.3.2 (cli) | php -n | 8 threads

........s................<span style="color: #FFF; background-color: #900">F</span>.........

<span style="color: #F00">-- FAILED: greeting.phpt</span>
<span style="color: #CCC">   </span><span style="color: #FFF">Failed: </span><span style="color: #FF0">'Hello John'</span><span style="color: #FFF"> should be</span>
<span style="color: #FFF">       ... </span><span style="color: #FF0">'Hello Peter'</span>

<span style="color: #CCC">   in </span><span style="color: #FFF">greeting.phpt(19)</span><span style="color: #808080"> Assert::same('Hello Peter', $o->say('John'));</span>

<span style="color: #FFF; background-color: #900">FAILURES! (35 tests, 1 failures, 1 skipped, 1.7 seconds)</span>
\--

Izvedenih je bilo 35 testov, eden ni uspel, eden je bil preskočen.

Nadaljujemo v poglavju [Izvajanje testov |Running tests].


Način opazovanja .[#toc-watch-mode]
===================================

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 |running-tests#w-watch-path].


Poročila CodeCoverage .[#toc-codecoverage-reports]
==================================================

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":https://files.nette.org/tester/coverage.html s pokritostjo kode.


Podprte različice PHP .[#toc-supported-php-versions]
====================================================

| 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 |https://hhvm.com] 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:

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 opravljen
  • s – test je bil preskočen
  • F – 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: