Тестування коду з PHPUnit

462

Від автора: при розробці веб-додатків так чи інакше будуть виникати різні помилки і неточності в роботі деяких елементів, на пошук і виправлення яких можна витратити значну кількість часу. Тому в даному уроці ми з Вами познайомимося з дуже хорошим інструментом бібліотеки PEAR, який дозволяє виконувати тестування окремих елементів майбутнього сценарію. Назва даного інструменту PHPUnit.

Тестування коду з PHPUnitТестування коду з PHPUnit

1. Установка PHPUnit

PHPUnit – це спеціальний фреймворк, призначений для модульного тестування мови скриптів PHP, розроблений Себастьяном Бергманом. Переваги PHPUnit:

Інструменти для створення модульних тестів та організації їх в ієрархічні набори.

Інтерфейс командного рядка для виконання тестів.

Провайдери даних – генератори наборів даних, для тестування елементів скрипта, використовуючи різні вхідні параметри.

Підтримка тестування коду, який працює з базою даних.

Тестування винятків.

Підтримка так званих фіктивних об’єктів.

Генератори звітів.

Робота цього фреймворку не можлива без встановленої у Вашому інтерпретатор мови PHP бібліотеки PEAR. Звичайно, зараз ми не будемо докладно зупинятися на даній бібліотеці, бо це не тема даного уроку.

Але коротко скажу, що PEAR — це абревіатура від «PHP Extension and Application Repository» (Репозиторій програм та модулів PHP). Тобто PEAR – це набір класів і модулів, які істотно розширюють функціонал мови PHP і кожен з них, це закінчений веб-додаток, що виконує свої цілі і завдання. Тому насамперед необхідно встановити бібліотеку PEAR. Для цього перейдемо на сайт http://pear.php.net/:

Тестування коду з PHPUnit

Далі клікаєм за посиланням: installing PEAR on your system.

Тестування коду з PHPUnit

Потім переходимо вп ссылке Getting and installing the PEAR package manager:

Тестування коду з PHPUnit

На цій сторінці нам необхідно завантажити інсталяційний файл бібліотеки PEAR. Тому клацаємо по посиланню: http://pear.php.net/go-pear.phar. Скачаний файл необхідно помістити в папку з інтерпретатором мови PHP. Якщо Ви використовуєте Denwer, то дана папка міститься за адресою: usr/local/php5. Тепер відкриваємо ” командний рядок, переходимо в папку з інтерпретатором мови PHP і набираємо команду:

php go-pear.phar

Так, хотів би сказати, що якщо у Вас в системної змінної $path (змінні середовища) прописаний шлях до інтерпретатору PHP, то попередню команду можна виконувати, перебуваючи в будь-якій папці.

Тестування коду з PHPUnit

Далі, вибираємо режим установки local (тобто, набираємо команду local) і підтверджуємо свій вибір, набором рядка “yes”:

Тестування коду з PHPUnit

Далі необхідно перевірити шляхом встановлення окремих компонентів бібліотеки (тобто, як Ви бачите перед початком установки, показано куди будуть встановлені елементи бібліотеки.). Я Вам рекомендую встановлювати бібліотеку PEAR в папку з інтерпретатором PHP. Якщо Вам потрібно відредагувати шлях установки, наберіть у командному рядку 1 і виберіть папку для установки. Якщо все вірно натискаємо ENTER і починається установка:

Тестування коду з PHPUnit

Отже, бібліотека PEAR успішно встановлена. Тепер необхідно встановити PHPUnit. Для цього перейдемо на сайт http://pear.phpunit.de/. Тут, як Ви бачите, докладно описаний процес установки інструменту PHPUnit і нижче представлено докладний опис, доступні версії і так звані залежності. Тобто елементи, які необхідні для нормальної роботи і установки PHPUnit.

Тестування коду з PHPUnit

Тепер повертаємося в командний рядок і у відповідності з інструкцією додаємо наступну команду, яка зареєструє канал установки інструменту PHPUnit:

Далі для правильної установки PHPUnit, необхідно зареєструвати канал компонента pear.symfony (без нього PHPUnit працювати не буде). Тому перейдемо на сайт http://pear.symfony.com і в верхній частині сайту Ви побачите аналогічну інструкцію по реєстрації каналу symfony. Тому в командному рядку виконаємо наступну команду

pear channel-discover pear.symfony.com

Далі встановлюємо PHPUnit, виконавши таку команду в командному рядку:

pear install phpunit/PHPUnit

Тестування коду з PHPUnit

Як Ви бачите PHPUnit успішно встановлений. Для перевірки його працездатності, достатньо виконати команду phpunit. На екрані Ви побачите невелику довідку по цьому інструменту.

2. Створюємо перший тест

Отже, давайте розглянемо наступний клас (файл sqrt_class.php):

Як Ви бачите, це дуже простий клас, який містить лише один метод, який повертає корінь квадратний переданого йому параметра $x. Також даний метод перевіряє значення даного параметра і якщо воно дорівнює 5, значить, повертаємо TRUE. Якщо значення параметра $x дорівнює 100, значить, повернемо FALSE.

Тепер, необхідно створити спеціальний клас, який і буде виконувати тест. Для цього створимо новий файл, за назвою test.php. Насамперед необхідно підключити головний файл інструменту PHPUnit, без якого робота тестів не можлива.

require_once ‘PHPUnit/Autoload.php’;

Потім підключаємо клас, який потрібно протестувати:

require_once ‘sqrt_class.php’;

Перед створенням класу для тестування розглянемо кілька правил створення таких класів:

Назва класу тесту складається з назви досліджуваного класу плюс “Test”.

Клас для тестування практично завжди повинен бути спадкоємцем класу PHPUnit_Framework_TestCase.

Кожен метод тесту є публічним методом, назва якого починається з префікса “test”.

Усередині методу тесту ми використовуються спеціальні методи тестування – assert-методи. Які і задають спосіб тестування.

Тепер створимо клас для тестування (для кращого розуміння наведу повний код файлу test.php):

assertEquals(4, $my->sq(16));
}
}
?>

Як Ви бачите, клас для тестування досить простий і містить всього один метод testSq. Ім’я даного методу вибрано в відповідності з викладеними вище правилами. Тобто ми хочемо протестувати метод sq(), значить, ім’я буде таким же, але з додаванням префікса test. В даному методі, ми створюємо об’єкт класу sqrt_class() (клас, метод якого ми хочемо протестувати), і зберігаємо його в змінній $my. Тепер в залежності від того, який тест потрібно виконати, необхідно викликати спеціальний assert-метод.

Для першого тесту, ми застосуємо метод assertEquals(), який першим параметром приймає очікуване значення (тобто те вірне значення яке повинен повертати метод), другим — реальне значення (тобто значення яке дійсно повертається методом). І зрівнює ці два значення. Якщо вони рівні – тест пройдено успішно. Якщо ж ні — то помилка.

Тепер як Ви бачите, при виклику методу assertEquals(), першим параметром ми передаємо значення 4, як очікуване. І другим, передаємо виклик методу sq() класу sqrt_class – як реально обчислене значення. Параметром методу sq(), передамо значення 16. Значить у результаті відпрацювання методу ми повинні отримати число 4, при цьому очікуване значення, ми так само передали 4. Значить, тест повинен завершитися успішно. Тому, давайте виконаємо тест і перевіримо.
Для запуску тесту, необхідно повернутися в командний рядок, перейти в папку з інтерпретатором мови php і набрати команду:

phpunit path,

де path – це шлях до файлу з тестом, в нашому випадку це файл test.php. Тобто в командному рядку виконуємо команду:

phpunit z:\home\localhost\www\for_pear\test.php

В результаті ми побачимо наступне:

Тестування коду з PHPUnit

Отже, що ми бачимо. Перше, що кидається в очі – це привітання, то є версія PHPUnit і ім’я творця. Далі – точка. Точка – це ознака того, що тест успішно. Потім вказана різна сервісна інформація (кількість затраченого часу, пам’яті і т. д). Тепер давайте змінимо очікуване значення, з 4 на 2 (тобто першим параметром методу assertEquals() передамо 2) і запустимо тест:

Тестування коду з PHPUnit

Тепер замість точки ми бачимо букву F, що означає Fault – помилка. Нижче можна прочитати в чому саме полягає помилка тесту. Тобто тест закінчився з помилкою.

В даному прикладі, ми розглянули передачу двох параметрів метод assertEquals(), але що робити, якщо потрібно протестувати відпрацювання методу для різних параметрів. Не будемо ж ми для кожного набору параметрів, вручну запускати тест? Звичайно немає. Для вирішення даної задачі, необхідно використовувати провайдери даних. Провайдери даних, містять в собі масив параметрів, які будуть підставлені під час запуску тесту. Тим самим, запускаючи тест ми виконаємо стільки тестів, скільки наборів параметрів міститься в провайдері даних.

Провайдер даних це звичайний метод, який повертає масив з набором параметрів наступному форматі:

public function providerSq ()
{
return array (
array (param1, param2),//параметри для тест 1
array (param1, param2),// параметри для тест 2
array (param1, param2),// параметри для тест 3
array (param1, param2)// параметри для тест 4
);
}

Масив повинен бути багатовимірним. Кожна комірка повинна містити ще масив з параметрами для конкретного тесту (якщо потрібно передати два параметра, то відповідно масив містить дві клітинки). Кількість осередків, дорівнює кількості тестів. Для використання провайдерів необхідно дотримувати два правила:

Метод є провайдером, повинен бути названий, як і досліджуваний метод, з додаванням приставки provider.

Перед досліджуваним метод, необхідно вказати у спеціальному коментарі назва його провайдера. Наступним чином:

/**
* @dataProvider ім’я провайдера
*/

Тому давайте змінимо код класу sqrt_classTest, для використання провайдерів:

class sqrt_classTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider providerSq
*/
public function testSq($a,$b) {
$my = new sqrt_class();
$this->assertEquals($a, $my->sq($b));
}
public function providerSq ()
{
return array (
array (2, 4),
array (4, 16),
array (5, 5),
array (3, 100)
);
}
}

Тепер, давайте виконаємо даний тест:

Тестування коду з PHPUnit

Як Ви бачите, зараз виповнилося чотири тесту – для кожного набору параметрів. Четвертий тест виконався з помилкою. Так як корінь квадратний із 100, ні як не може бути дорівнює 3. Поряд з методом assertEquals, є ще дві корисні методу assertTrue() і assertFalse(), які перевіряють, чи є передане вираз істинним або хибним відповідно. Тобто, метод для тестування істинності значення, що повертається:

/**
* @dataProvider providerSq
*/
public function testSq($a,$b) {
$my = new sqrt_class();
$this->assertTrue($my->sq($b));
}

Даний тест успішно виконається якщо метод sq () поверне TRUE. І метод для тестування того, що досліджуваний метод поверне FALSE:

/**
* @dataProvider providerSq
*/
public function testSq($a,$b) {
$my = new sqrt_class();
$this->assertFalse($my->sq($b));
}

Даний тест успішно виконається якщо метод sq () поверне FALSE.

3. Тестування масивів

Тепер давайте розглянемо наступний клас (файл arr_class.php):

Знову ж таки цей клас містить всього один метод, який параметром приймає рядок і розбиває її в масив, за роздільником “|”. Для тестування масивів у PHPUnit є спеціальні методи. Тому давайте розглянемо код файлу test2.php, що дозволяє виконувати тестування масивів:

assertArrayHasKey($key,$my->getArr($str));
//$this->assertContains($key,$my->getArr($str));
//$this->assertContainsOnly(‘integer’,$my->getArr($str));
//$this->assertCount($key, $my->getArr($str));
}
public function providerGetArr ()
{
return array (
array (3, ‘ku|hello|white’),
array (4, ‘ku1|hello1|white1’),
array (3, ‘2/2/2’),
);
}
}

Методи в класі я спеціально закомментировал, що б можна було їх використовувати по черзі:

assertArrayHasKey($k, $arr) – перевіряє, існує ключ $k, у масиві $arr.

assertContains($v, $arr) – перевіряє, існує елемент $v в масиві $arr.

assertContainsOnly(‘type’, $arr) — перевіряє, чи містять комірки масиву $arr, значення типу даних type.

assertCount($count,$arr) – перевіряє, чи відповідає число $count, кількості елементів масиву $arr.

Запуск тесту виробляємо аналогічно попереднім прикладам, тільки не забувайте правильно вказувати шлях для файлу з тестом.

4. Тестування винятків

І останнє, що ми розглянемо – це тестування винятків. Давайте розглянемо клас:

Клас містить всього один метод, який генерує виняток, якщо переданий йому параметр дорівнює 10. Тепер подивіться на клас, з допомогою якого можна перевірити генерацію винятків:

ob = new ex_class();
}
/**
* @dataProvider providerGetEx
*
*/
public function testGetEx($key) {
$this->setExpectedException(“myException”);
$this->ob->getEx($key);
}
public function providerGetEx() {
return array(
array(3),
array(1),
array(10),
array(3)
);
}
protected function tearDown() {
$this->ob = NULL;
}
}
?>

Перше, що Ви напевно помітили, це те, що додалося два методу:

setUp() – який виконується перед тестом. Тобто, використовуючи даний метод можна виконати різні підготовчі дії. Приміром, у нашому випадку – створюємо об’єкт досліджуваного класу і зберігаємо в властивість $fixture.

tearDown() — який, виконується після тесту. Тобто можна видалити зайві дані. У нашому випадку видаляємо створений об’єкт досліджуваного класу.

Тестувати виняток можна за допомогою методу setExpectedException(«myException») або необхідно вказати перед досліджуваним методом коментар @expectedException MyException. Тест буде пройдено успішно, якщо метод поверне виняток класу myException.

Ось і все, що я хотів сказати Вам по інструменту PHPUnit. Звичайно, ми розглянули тільки основи, так як PHPUnit – це дуже потужний і досить складний інструмент для тестування коду. Але якщо він Вас зацікавив, то продовжуйте його подальше вивчення самостійно і застосовувати вивчене на практиці.

Документація по PHPUnit міститься на даній сторінці: http://phpunit.de/manual/current/en/index.html

На цьому давайте прощатися. Всього Вам доброго і вдалого кодування!!!