Nette Documentation Preview

syntax
Започване на работа с Tester
****************************

<div class=perex>

Дори добрите програмисти допускат грешки. Разликата между добрия и лошия програмист е, че добрият програмист ще го направи само веднъж и ще го открие следващия път с автоматизирани тестове.

- "Който не изпитва, е обречен да повтаря собствените си грешки". (мъдра поговорка).
- "Когато се отървем от една грешка, се появява друга." (Законът на Мърфи)
- "Винаги, когато се изкушавате да напишете изявление, напишете го като тест." (Martin Fowler)

</div>

Писали ли сте някога следния код в PHP?

```php
$obj = new MyClass;
$result = $obj->process($input);

var_dump($result);
```

Случвало ли ви се е да нулирате резултата от извикване на функция, само за да проверите на око дали тя връща това, което трябва да върне? Вероятно правите това много пъти на ден. С ръка на сърцето, ако всичко работи, изтривате ли този код и очаквате ли, че класът няма да се счупи в бъдеще? Законът на Мърфи гарантира друго :-)

Всъщност сте написали тест. Тя се нуждае от малка промяна, за да не изисква нашата проверка, а да може да се проверява сама. Ако не сте го изтрили, можем да го стартираме по всяко време в бъдеще, за да проверим дали всичко продължава да работи както трябва. С течение на времето може да създадете голям брой такива тестове, така че би било добре да можем да ги изпълняваме автоматично.

А Nette Tester просто помага за това.


Какво прави Tester уникален? .[#toc-what-makes-tester-unique]
=============================================================

Писането на тестове за Nette Tester е уникално с това, че **всеки тест е стандартен PHP скрипт, който може да се изпълнява отделно.

Така че, когато напишете тест, можете просто да го стартирате, за да проверите дали има програмна грешка. Ако работи правилно. Ако това не е така, можете лесно да преминете през програмата в IDE и да потърсите грешката. Можете дори да го отворите в браузъра си.

И най-важното - след като го стартирате, стартирате тест. Веднага ще разберете дали е преминал успешно или не. Как? Нека ви покажем как. Нека напишем тривиален тест на PHP за масиви и да го запишем във файл `ArrayTest.php`:

```php .{file:ArrayTest.php}
<?php
use Tester\Assert;

require __DIR__ . '/vendor/autoload.php'; # загрузить автозагрузку Composer
Tester\Environment::setup();       # инициализация Nette Tester

$stack = [];
Assert::same(0, count($stack));    # мы ожидаем, что count() вернет ноль

$stack[] = 'foo';
Assert::same(1, count($stack));    # мы ожидаем, что count() вернет единицу
Assert::contains('foo', $stack);   # проверяем, что $stack содержит элемент 'foo'
```

Както можете да видите, [методите за утвърждаване, |Assertions] като например `Assert::same()`, се използват за утвърждаване, че действителната стойност съвпада с очакваната стойност.

Тестът е написан, можем да го стартираме от командния ред. Първото пускане ще разкрие всички грешки в синтаксиса и ако не сте допуснали никакви грешки, ще видите:

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

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

Опитайте да промените декларацията на `Assert::contains('XXX', $stack);` в теста и вижте какво ще се случи, когато го стартирате:

/--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>
\--

Продължаваме с писането на [тестове |Writing Tests] в главата [Писане на тестове |Writing Tests].


Монтаж и изисквания .[#toc-installation-and-requirements]
=========================================================

Минималната необходима версия на PHP за Tester е 7.1 (за повече информация вижте таблицата с [поддържаните версии на PHP |#Supported-PHP-Versions] ). Предпочитаният метод за инсталиране е [Composer |best-practices:composer]:

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

Опитайте се да стартирате Nette Tester от командния ред (той ще покаже само кратка справка без аргументи):

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


Изпълнение на тестове .[#toc-running-tests]
===========================================

С разрастването на нашето приложение се увеличава и броят на тестовете. Би било непрактично да се изпълняват тестовете един по един. Затова Tester има пакетно стартиране на тестове, което се извиква от командния ред. Параметърът е директорията, в която се намират тестовете. Точката сочи към текущата директория.

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

Nette Tester претърсва посочената директория и всички поддиректории и търси тестове, които са `*.phpt` и `*Test.php`. Той ще открие и нашия тест `ArrayTest.php`, тъй като той съвпада с маската.

След това се стартира тестът. Всеки тест се изпълнява като нов процес на PHP, така че се изпълнява напълно изолирано от останалите. Тя работи паралелно в няколко нишки, което я прави изключително бърза. Тестовете, които са се провалили при предишното изпълнение, се изпълняват първи, така че веднага ще разберете дали сте отстранили грешката.

За всеки завършен тест програмата отпечатва един символ, за да покаже напредъка:

- <code style="color: #CCC; background-color: #000">.</code> - тестът е преминал успешно
- <code style="color: #CCC; background-color: #000">s</code> - тестът е преминал успешно
- <code style="color: #FFF; background-color: #900">F</code> - тестът не е преминат

Изходът може да изглежда по следния начин:

/--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>
\--

Бяха попълнени 35 теста, един не беше издържан и един беше пропуснат.

Ще продължим в главата [Изпълнение на тестове |Running tests].


Режим на наблюдение .[#toc-watch-mode]
======================================

Рефакторирате ли кода си? Или дори да разработвате по методологията TDD (Test Driven Development)? Тогава режимът за наблюдение ще ви хареса. Tester следи изходния код и се стартира, когато той се промени.

По време на разработката имате терминал в ъгъла на монитора, където светва зелената лента за състоянието, и когато тя внезапно стане червена, знаете, че току-що сте направили нещо нежелано. Всъщност това е страхотна игра, в която програмирате и се опитвате да се придържате към цвета.

Режимът на наблюдение се стартира с параметъра [--watch |running-tests#w-watch-path].


Доклади CodeCoverage .[#toc-codecoverage-reports]
=================================================

Tester може да генерира отчети с обща информация за това колко изходен код обхващат тестовете. Отчетът може да бъде в разбираем за човека HTML формат или в XML формат на Clover за по-нататъшна машинна обработка.

Вижте  пример за HTML отчет:https://files.nette.org/tester/coverage.html с покритие на кода.


Поддържани версии на PHP .[#toc-supported-php-versions]
=======================================================

| 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 3+
| Tester 1.3 - 1.5 | PHP 5.3 - 5.6 + HHVM
| Tester 0.9 - 1.2 | PHP 5.3 - 5.6

Отнася се за най-новите версии на кръпките.

Преди версия 1.7 Tester поддържаше [HHVM |https://hhvm.com] 3.3.0 или по-нова версия (с помощта на `tester -p hhvm`). От версия 2.0 нататък поддръжката е преустановена. Използването е просто:

Започване на работа с Tester

Дори добрите програмисти допускат грешки. Разликата между добрия и лошия програмист е, че добрият програмист ще го направи само веднъж и ще го открие следващия път с автоматизирани тестове.

  • „Който не изпитва, е обречен да повтаря собствените си грешки“. (мъдра поговорка).
  • „Когато се отървем от една грешка, се появява друга.“ (Законът на Мърфи)
  • „Винаги, когато се изкушавате да напишете изявление, напишете го като тест.“ (Martin Fowler)

Писали ли сте някога следния код в PHP?

$obj = new MyClass;
$result = $obj->process($input);

var_dump($result);

Случвало ли ви се е да нулирате резултата от извикване на функция, само за да проверите на око дали тя връща това, което трябва да върне? Вероятно правите това много пъти на ден. С ръка на сърцето, ако всичко работи, изтривате ли този код и очаквате ли, че класът няма да се счупи в бъдеще? Законът на Мърфи гарантира друго :-)

Всъщност сте написали тест. Тя се нуждае от малка промяна, за да не изисква нашата проверка, а да може да се проверява сама. Ако не сте го изтрили, можем да го стартираме по всяко време в бъдеще, за да проверим дали всичко продължава да работи както трябва. С течение на времето може да създадете голям брой такива тестове, така че би било добре да можем да ги изпълняваме автоматично.

А Nette Tester просто помага за това.

Какво прави Tester уникален?

Писането на тестове за Nette Tester е уникално с това, че **всеки тест е стандартен PHP скрипт, който може да се изпълнява отделно.

Така че, когато напишете тест, можете просто да го стартирате, за да проверите дали има програмна грешка. Ако работи правилно. Ако това не е така, можете лесно да преминете през програмата в IDE и да потърсите грешката. Можете дори да го отворите в браузъра си.

И най-важното – след като го стартирате, стартирате тест. Веднага ще разберете дали е преминал успешно или не. Как? Нека ви покажем как. Нека напишем тривиален тест на PHP за масиви и да го запишем във файл ArrayTest.php:

<?php
use Tester\Assert;

require __DIR__ . '/vendor/autoload.php'; # загрузить автозагрузку Composer
Tester\Environment::setup();       # инициализация Nette Tester

$stack = [];
Assert::same(0, count($stack));    # мы ожидаем, что count() вернет ноль

$stack[] = 'foo';
Assert::same(1, count($stack));    # мы ожидаем, что count() вернет единицу
Assert::contains('foo', $stack);   # проверяем, что $stack содержит элемент 'foo'

Както можете да видите, методите за утвърждаване, като например Assert::same(), се използват за утвърждаване, че действителната стойност съвпада с очакваната стойност.

Тестът е написан, можем да го стартираме от командния ред. Първото пускане ще разкрие всички грешки в синтаксиса и ако не сте допуснали никакви грешки, ще видите:

$ php ArrayTest.php

OK

Опитайте да промените декларацията на Assert::contains('XXX', $stack); в теста и вижте какво ще се случи, когато го стартирате:

$ php ArrayTest.php

Failed: ['foo'] should contain 'XXX'

in ArrayTest.php(17) Assert::contains('XXX', $stack);

FAILURE

Продължаваме с писането на тестове в главата Писане на тестове.

Монтаж и изисквания

Минималната необходима версия на PHP за Tester е 7.1 (за повече информация вижте таблицата с поддържаните версии на PHP ). Предпочитаният метод за инсталиране е Composer:

composer require --dev nette/tester

Опитайте се да стартирате Nette Tester от командния ред (той ще покаже само кратка справка без аргументи):

vendor/bin/tester

Изпълнение на тестове

С разрастването на нашето приложение се увеличава и броят на тестовете. Би било непрактично да се изпълняват тестовете един по един. Затова Tester има пакетно стартиране на тестове, което се извиква от командния ред. Параметърът е директорията, в която се намират тестовете. Точката сочи към текущата директория.

vendor/bin/tester .

Nette Tester претърсва посочената директория и всички поддиректории и търси тестове, които са *.phpt и *Test.php. Той ще открие и нашия тест ArrayTest.php, тъй като той съвпада с маската.

След това се стартира тестът. Всеки тест се изпълнява като нов процес на PHP, така че се изпълнява напълно изолирано от останалите. Тя работи паралелно в няколко нишки, което я прави изключително бърза. Тестовете, които са се провалили при предишното изпълнение, се изпълняват първи, така че веднага ще разберете дали сте отстранили грешката.

За всеки завършен тест програмата отпечатва един символ, за да покаже напредъка:

  • . – тестът е преминал успешно
  • s – тестът е преминал успешно
  • F – тестът не е преминат

Изходът може да изглежда по следния начин:

 _____ ___  ___ _____ ___  ___
|_   _/ __)( __/_   _/ __)| _ )
  |_| \___ /___) |_| \___ |_|_\  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)

Бяха попълнени 35 теста, един не беше издържан и един беше пропуснат.

Ще продължим в главата Изпълнение на тестове.

Режим на наблюдение

Рефакторирате ли кода си? Или дори да разработвате по методологията TDD (Test Driven Development)? Тогава режимът за наблюдение ще ви хареса. Tester следи изходния код и се стартира, когато той се промени.

По време на разработката имате терминал в ъгъла на монитора, където светва зелената лента за състоянието, и когато тя внезапно стане червена, знаете, че току-що сте направили нещо нежелано. Всъщност това е страхотна игра, в която програмирате и се опитвате да се придържате към цвета.

Режимът на наблюдение се стартира с параметъра –watch.

Доклади CodeCoverage

Tester може да генерира отчети с обща информация за това колко изходен код обхващат тестовете. Отчетът може да бъде в разбираем за човека HTML формат или в XML формат на Clover за по-нататъшна машинна обработка.

Вижте пример за HTML отчет:https://files.nette.org/…overage.html с покритие на кода.

Поддържани версии на PHP

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 3+
Tester 1.3 – 1.5 PHP 5.3 – 5.6 + HHVM
Tester 0.9 – 1.2 PHP 5.3 – 5.6

Отнася се за най-новите версии на кръпките.

Преди версия 1.7 Tester поддържаше HHVM 3.3.0 или по-нова версия (с помощта на tester -p hhvm). От версия 2.0 нататък поддръжката е преустановена. Използването е просто: