Початок роботи з 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 підтримку було припинено. Використання було простим: