Основи функціонального тестування модулів на Simpletest
У цій статті я розповім про основи тестування у Друпалі. Після прочитання ви можете написати простий тест самостійно. Для наочності, під час статті буде створено модульsimpletest_example, який надаватиме тип контенту з назвою simpletest_example, який нічим не відрізняється від звичних нам типів story, page і т.д. Далі для цього модуля буде написано тест, який перевіряє правильність його роботи в різних ситуаціях.
Підготовка до тестування
Для початку переконайтеся, що увімкнено модуль simpletest. УDrupal 7 модульsimpletest є частиною ядра. Його можна знайти у списку модулів під назвою Testing. За замовчуванням він вимкнений, тому перед тестуванням обов'язково увімкніть його. Щоб переконатися, що simpletest працює, перейдіть на сторінкуadmin/config/development/testing/settings.
Модуль, який буде створений під час статті, використовується в проекті Examples під назвоюSimpletest Example, тому при необхідності всі вихідні джерела можна подивитися саме там.
Як працює Simpletest в Drupal
Основна частина функціоналу Друпала орієнтована на Інтернет, тому важливо мати можливість протестувати його.Simpletest створює чисту інсталяцію Друпала та віртуальний веб браузер, після чого використовує цей браузер для прогону тестованого функціоналу через серію тестів так само, як це зробив би будь-який користувач вручну.
Дуже важливо розуміти, що кожен запуск тесту створює абсолютно нову інсталяцію (сутність, установку, як завгодно) Друпала, створену спеціально для запущеного тесту. Інакше кажучи, ніяких налаштувань, користувачів, матеріалів тощо. при запуску тесту неІснує. Якщо вам при тестуванні потрібен користувач із певними правами – треба буде його створити. Якщо модуль повинен бути увімкнений - доведеться його ввімкнути. Якщо потрібно використовувати налаштування, відмінні від дефолтних, потрібно буде скористатися інструментамиSimpletest для цього. У файловій директорії немає жодного файлу, ніякі модулі (крім обов'язкових) не включені. Однак,Simpletest містить набір корисних методів, що дозволяють швидко створити необхідний функціонал для тестування.
Короткий опис модуля Simpletest Example
МодульSimpletest Example створює новий тип матеріалу на кшталт page або story, який містить заголовок та вміст ноди. Власне, більше нічого модуль не робить, але дає нам можливість продемонструвати тестування створення контенту.
До речі, у цьому модулі є невеликий баг: права користувача обробляються некоректно. Точніше, рядок з правом редагувати власний матеріал типуsimpletest_example неправильно обробляється функцієюsimpletest_example_access() В результаті це призводить до того, що створений на етапі тестування користувач не має можливості змінити створений матеріал. Однак до цього ми ще повернемося.
Що ж ми тестуватимемо?
Якщо ви вже встановили модульsimpletest_example, ви можете перейти на сторінку створення матеріалу і наживо побачити, що має бути протестовано. Для цього перейдіть до розділуnode/add/simpletest-example. Там ви побачите приблизно таке:

На наступному скріншоті стрілками показано, що буде використано при тестуванні:

Сподіваюся, з інтерфейсом Друпала ви вже знайомі, і не доведеться пояснювати, що буде післязбереження матеріалу. Інакше вам навряд чи вдасться зрозуміти подальші дії.
Створення тесту для модуля Simpletest Example
Ось і настав час для створення свого тесту. Він зазвичай створюється файл за принципомимя_модуля.test, який міститься в корінь модуля. До речі, модульSimpletest Example містить цей файл.
При додаванні файлу тесту до модуля вDrupal 7, то треба буде описати його вinfo файлі модуля в секціїfiles[]. У прикладі файл тесту названий simpletest_example.test:
Якщо ви додаєте файл із тестом до увімкненого модуля, то вам доведеться очистити кеш Друпала перед тим, як він буде підхоплений системою. Зробити це можна на сторінціadmin/config/development/performance кнопкоюClear all caches (очистити весь кеш).
Створення тесту містить чотири основні кроки:
- Створення структури (просто створення класу, успадкованого відDrupalWebTestCase )
- Ініціалізація тесту зі створенням необхідних сутностей та налаштуванням конфігурації
- Створення методів тестування модуля
- Усвідомлення результатів тесту зрозуміти, чому тест не працює так, як нам хотілося б. А також виявлення помилок у тесті (або модулі).
Для початку нам знадобиться успадкувати клас з нашим тестом відDrupalWebTestCase :
Для того, щоб створений тест було видно з веб-інтерфейсуSimpletest, необхідно до класу додати методgetInfo(). Він надає основну інформацію про створюваний тест - ім'я, опис та його групу (на зразок групи у модулів, тільки там це package).
Далі слідує вкрай важлива функціяsetUp(). У ній робляться всі приготування для запуску робочої версії інсталяціїДрупала, щоб тест надалі працював так, як нам треба. При написанні коду в цій функції спочатку треба задуматися - "Що мені треба створити і включити, щоб мої тести виконалися правильно?" У нашому випадку треба зробити три речі:
- Включити модульSimpletest Example
- Створити користувача з доступом до створення матеріалу типуsimpletest_example
- Авторизувати створеного користувача
Всі ці дії ми робимо у методіsetUp() :
Зауваження: у Drupal 6 необхідно включити всі модулі, від яких залежить необхідний модуль. У сьомому Друпалі ці модулі включаються автоматично.
Створення тесту: Додавання матеріалу
Тепер треба створити спеціальний метод, який містить тест для модуля. Для цього просто додаємо в наш клас метод, що містить набір інструкцій, що тестують.
Наш перший тест буде створювати нову ноду типуsimpletest_example, використовуючи форму на сторінціnode/add/simpletest-example :
drupalPost, drupalGet і методи вставок (assertations)
Вище викладений код робить досить простий саміт форми зі сторінкиnode/add/simpletest-example. Спочатку він готує масив полів зі значеннями форми (заголовок та вміст матеріалу), а далі просто відправляє її методом POST, вказавши, яка кнопка форми при цьому має бути натиснута. Цей метод принципом своєї роботи дуже схожий на drupal_form_submit() (для тих, хто стикався).
Більшість тестів створюються за таким шаблоном:
- За допомогою drupalGet() переходять на потрібну сторінку або за допомогою drupalPost() роблять маніпуляції з формами
- Роблять одну або більше вставок, щоб порівняти те, що вийшло внаслідок того, щомало вийти
$this->drupalGet($path) : просто переходить на сторінку$path.
$this->drupalPost($path, $edit_fields, $submit_button_name) : зі сторінки$path бере форму, заповнює її поля значеннями з$edit_fields та імітує натискання кнопки$submit_button_name.
Тепер про вставки. Існує десятки різних видів вставок. Найпростіша - це$this->assertText($text_to_find_on_page). Я їх перераховувати не буду - ви можете самостійно почитати про них.
Користувачі та середовище ядра
Simpletest перемикає користувача на користувача з uid 1 (суперадмін) під час тестування, і також забезпечує його коректне перемикання назад. Тож можна не переживати з приводу вразливостей у безпеці сайту.
Запуск веб-інтерфейсу Simpletest
Тепер треба запустити тест. Тут ми будемо використовувати веб інтерфейс.
Перейдіть на сторінку з налаштуваннями тестування/admin/config/development/testing. Тут ви побачите два таба - List та Settings. У першій вкладці список із доступними тестами, а у другій - налаштування середовища тестування.
Нині нас цікавить перша вкладка. Виберіть тест, який щойно був створений (він буде знаходитись у групі Examples) і натиснітьRun tests. Можливо, вам доведеться скинути кеш перед тим, як ви побачите ваш тест у списку.
Після запуску тесту ви побачите результати тестування модулем.
Тести також можна запускати з командного рядка. Більше інформації про це ви знайдете тут.
Приклад тесту, який не буде пройдений
Погляньмо на приклад тесту, результатом виконання якого буде невдача.
Робота як і раніше відбуваєтьсяусередині одного класу. Однак цього разу спробуємо протестувати редагування ноди. Як я вже казав у модулі є баг – він некоректно обробляє рядок з доступом користувача на редагування власних матеріалів. Тому користувач не зможе їх редагувати. У цьому тесті ми створимо матеріал та спробуємо редагувати його:
Модульне тестування
Тестування, про яке йшлося раніше, називається функціональним. АлеSimpletest надає альтернативу класуDrupalWebTestCase - класDrupalUnitTestCase. Цей вид тестування називається модульним.
Таблиці у базі даних та файлові директорії не створюються при ініціалізації модульного тестування. Це дозволяє йому швидше запускатись, ніж функціональному тестуванню. Однак це означає, що він не має доступу ні до бази даних, ні до файлів. Виклик будь-якої функції Друпала, яка містить звернення до БД, приведе до помилки. Це стосується навіть таких поширених функцій якwatchdog(),module_implements(),module_invoke_all() і т.д.
Докладніше про цей вид тестування можна почитати у статті про модульне тестування з Simpletest.
Налагодження Simpletest'ів
Також ви можете скористатися методом$this->verbose("якесь повідомлення"), щоб вивести деяку налагоджувальну інформацію на екран при тестуванні.
Більше інформації проdebug() і$this->verbose() ви знайдете в статті про налагодження в Drupal 7.