Починаємо з Nette 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'
Як бачите, так звані методи assertion як
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 (детальніше в таблиці podporované verze PHP). Переважний спосіб встановлення — за допомогою Composer:
composer require --dev nette/tester
Спробуйте запустити Nette Tester з командного рядка (без параметрів він лише виведе довідку):
vendor/bin/tester
Запуск тестів
З ростом застосунку кількість тестів зростає разом з ним. Було б непрактично запускати тести по одному. Тому Tester має пакетний запускач тестів, який ми викликаємо з командного рядка. Як параметр вкажемо директорію, в якій знаходяться тести. Крапка означає поточну директорію.
vendor/bin/tester .
Запускач тестів просканує вказану директорію та всі піддиректорії
та знайде тести, тобто файли *.phpt
та *Test.php
. Він знайде й наш
тест ArrayTest.php
, оскільки він відповідає масці.
Потім він розпочне тестування. Кожен тест запускається як новий PHP-процес, тому він відбувається повністю ізольовано від інших. Він запускає їх паралельно в кількох потоках, і завдяки цьому він надзвичайно швидкий. І першими він запускає тести, які зазнали невдачі під час попереднього запуску, тому ви миттєво дізнаєтеся, чи вдалося вам виправити помилку.
Під час виконання тестів Tester постійно виводить результати на термінал у вигляді символів:
.
– тест пройшовs
– тест був пропущений (skipped)F
– тест зазнав невдачі (failed)
Вивід може виглядати так:
_____ ___ ___ _____ ___ ___ |_ _/ __)( __/_ _/ __)| _ ) |_| \___ /___) |_| \___ |_|_\ 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 тестів, один зазнав невдачі, один був пропущений.
Далі продовжуємо в розділі Запуск тестів.
Режим Watch
Рефакторите код? Або навіть розробляєте за методикою TDD (Test Driven Development)? Тоді вам сподобається режим watch. 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 |
Застосовується до останньої версії патча.
Tester до версії 1.7 підтримував також HHVM 3.3.0 або вище
(через tester -p hhvm
). Підтримка була припинена з версії Tester 2.0.