Nette Documentation Preview

syntax
Начало работы с Tester
**********************

<div class=perex>

Даже хорошие программисты допускают ошибки. Разница между хорошим программистом и плохим в том, что хороший сделает это только один раз и в следующий раз обнаружит это с помощью автоматизированных тестов.

- "Тот, кто не тестирует, обречен повторять собственные ошибки". (мудрая пословица).
- "Когда мы избавляемся от одной ошибки, появляется другая". (закон Мерфи)
- "Всякий раз, когда у вас возникает соблазн напечатать утверждение, вместо этого напишите его как тест". (Мартин Фаулер)

</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 запускается с помощью параметра [--watch |running-tests#w-watch-path].


Отчеты CodeCoverage .[#toc-codecoverage-reports]
================================================

Tester может генерировать отчеты с обзором того, какой объем исходного кода охватывают тесты. Отчет может быть либо в человекочитаемом формате HTML, либо в формате Clover XML для дальнейшей машинной обработки.

См. "пример 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
| 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`). Начиная с версии Tester 2.0 поддержка была прекращена. Использование было простым:

Начало работы с Tester

Даже хорошие программисты допускают ошибки. Разница между хорошим программистом и плохим в том, что хороший сделает это только один раз и в следующий раз обнаружит это с помощью автоматизированных тестов.

  • „Тот, кто не тестирует, обречен повторять собственные ошибки“. (мудрая пословица).
  • „Когда мы избавляемся от одной ошибки, появляется другая“. (закон Мерфи)
  • „Всякий раз, когда у вас возникает соблазн напечатать утверждение, вместо этого напишите его как тест“. (Мартин Фаулер)

Вы когда-нибудь писали следующий код на 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 запускается с помощью параметра –watch.

Отчеты CodeCoverage

Tester может генерировать отчеты с обзором того, какой объем исходного кода охватывают тесты. Отчет может быть либо в человекочитаемом формате HTML, либо в формате Clover XML для дальнейшей машинной обработки.

См. пример 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
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). Начиная с версии Tester 2.0 поддержка была прекращена. Использование было простым: