[ главная ]   [ рейтинг статей ]   [ справочник радиолюбителя ]   [ новости мира ИТ ]



Ответов: 0
25-02-12 07:01







   Web - программирование
PHP


ASP






XML



CSS

SSI





   Программирование под ОС











   Web - технологии








   Базы Данных









   Графика






Данные




Web - программирование / PHP /

Написание автоматических тестов и среда phpUnit

Программы, которые не тестировали, НЕ РАБОТАЮТ.
Б. Страуструп

Введение

Главная задача профессионального php-разработчика — cоздание в максимально короткий срок программного обеспечения, полностью удовлетворяющего заказчика. Скрипты должны делать именно то, чего от них ожидают. Самый простой пример — форма обратной связи, которая по нажатию на кнопку при условии корректного заполнения полей отправляет почту или записывает данные в таблицу БД. Если она этого не сделала, совершенно очевидно, что в программу закралась ошибка.

Итак, тестирование — деятельность, направленная на выявление такого рода несоответствий между ожидаемым и действительным. Выявляя несоответствия, некорректное поведение на стадии разработки, разработчик сознательно и планомерно уменьшает вероятность того, что с этим придется столкнуться пользователю. Тестировать программы (в частности php-скрипты) вполне можно и вручную. На примере формы обратной связи, понятно, что протестировать ее очень просто. Запустить браузер, зайти на нужный url, заполнить поля, нажать на «Ок», потом зайти в базу и проверить, появилась ли там соотвeтствующая запись. Прекрасно, но после любого изменения скрипта нельзя быть уверенным в его работоспособности. Можно понадеяться на авось и не проверять, работает ли скрипт после очередной модификации или нет, но помните, что если его не протестируете вы, это сделает заказчик во время сдачи проекта или конечный пользователь во время эксплуатации. В первом случае это грозит вам финансовой нестабильностью, а во втором пострадает ваш имидж. Для того, чтобы не тестировать вручную (это долгий, сложный и требующий особой усидчивости процесс), можно написать программу, тестирующую другие программы, или создать автоматизированные тесты.

В любой современной методологии разработки ПО тестирование является неотъемлемой частью процесса, а значимость его написания не ниже значимости написания кода. Профессиональный разработчик обязан создавать наборы различного вида автоматизированных тестов (подробнее о видах тестов, правилах их именования и т.д. можно прочитать в статье Кирилла Максимова «Организация и именование автоматизированных тестов»).

Несмотря на очевидную полезность и акцент методологий на процессе тестирования, личный опыт авторов свидетельствует о следующем разбросе мнений web-программистов насчет автоматизированного тестирования собственных скриптов:

  • «Никто не пишет, почему я должен писать»
  • «Мне не выделяют времени специально для написания тестов, хотя это было бы полезно»
  • «Я давно пишу тесты и не понимаю, как можно без этого жить»

Автоматизированные тесты и web-программирование

Будни основной массы web-разработчиков — выбор хорошего сервера для размещения сайта. Трудно найти хостинг-провайдера (php+mysql за разумные деньги), который устроил бы сразу на 100%, а пeреезд на новый сервер даже для интерпретируемого языка, коим является мой горячо любимый PHP, может стать «фатальным». Даже в документации по Java — языке, изначально ориентированном на кроссплатформенность, написано, что цена переносимости никогда не равна нулю. Эти люди знают, что говорят. После переезда в прекрасно отлаженных и стабильно работающих ранее скриптах могут появиться warning’и, а какие-то программы перестанут работать совсем: поменялись пути, библиотеки, версия самого php.

В итоге, имея набор тестов, переехать гораздо проще. Следует переписать скрипты, запустить набор тестов, посмотреть те тесты, которые завершились неудачно, разобраться, поправить, запустить набор тестов еще раз. Все. Вместо того, чтобы оставить «полуживой» проект на новом хостинге, «поверхностно» прокликав в браузере по ссылкам, мы получаем стабильно работающий сайт на новом сервере без особой головной боли. Автоматизированное тестирование в конечном итоге повышает качество кода, и, учитывая специфику web-программирования, упрощает процесс переезда с сервера на сервер.

Вслед за решением тестировать, приходит необходимость как-то организовать этот процесс. Например, выделить для тестовых скриптов отдельную директорию, создать программу, которая запустит все скрипты и в зависимости от их исхода напишет «OK» или «Error». Вполне возможно проделать это «с нуля», но есть готовые тестовые инфраструктуры (вспомогательные программы), которые объединяют группы тестов «по темам», единообразно их сохраняют, запускают и выводят результаты.

Cоздание тестов в phpUnit

В основном из-за увлеченности методологией XP авторы знакомы с тестовой инфраструктурой JUnit, соответственно, для php их выбор пал на phpUnit, как на созданный энтузиастами порт своего «старшего брата». На сегодняшний день существует несколько различных версий порта JUnit на php. Как минимум 3 варианта c названием phpUnit и порт php_simpletest. Регулярно обновляется версия PEAR::PHPUnit (Sebastian Bergmann). Php_simpletest находится в состоянии первой беты, другие phpUnit’ы обновлялись год назад (phpUnit project) и два года назад (phpunit-1.0.0) соответственно. Все рассмотренные ниже примеры модульных тестов написаны с использованием PEAR::PHPUnit.

Создадим набор тестов для класса Message, который форматирует и проверяет сообщение для последующей отправки его по e-mail.

Конструктор класса получает 3 параметра (имя отправителя, его e-mail aдрес и тело сообщения). Метод format_message() форматирует сообщение перед отправкой, а is_valid() проверяет возможность отправки сообщения (заполнены ли поля, и корректно ли введен е-mail). Исходный код класса Message — здесь

«Сердцем» тестирования является класс PHPUnit, который запускает TestSuite (набор тестов) и возвращает объект TestResult (результат теста).

Для того, чтобы написать минимальный набор тестов, используя phpUnit, необходимо:

  1. Подключить библиотеку PHPUnit.php
  2. Создать подкласс базового класса TestCase
  3. Добавить в него произвольное количество тестирующих методов, названия которых начинаются с «test». В нашем случае это «test_empty_input», «test_email_invalid», «test_valid_input». В них будут вызываться методы тeстируемого класса Message. На вход будут подаваться заранее известные параметры, а результат сравнивается с эталонным посредством семейства функций Assert, унаследованной нашим тестовым классом от TestCase (метод assertEquals проверяет ожидаемый и реально полученный результат на равенство, assertTrue проверяет, имеет ли поданный параметр значение «true» и т. д. )
  4. Cоздать класс PHPUnit_TestSuite, передав ему в качестве параметра название класса с набором тестов
  5. Запустить набор тестов и вывести результат

Создадим набор тестов для класса, следуя приведенной инструкции.

Мы протестируем следующие аспекты работы класса Message: его реакцию на пустое сообщение, и некорректный e-mail, а также сравним отформатированное объектом класса сообщение с эталонным.

Создаем сообщение, подаем на вход конструктора неверный e-mail, ожидаем, что метод класса is_valid(), ответственный за его проверку, возвратит «false».

function test_email_invalid() {
$m = new Message(‘name’, ‘invalid’, ‘body’);
/* ожидаем, что m->is_valid() возвращает false */
$this->assertFalse($m->is_valid());
}

Создаем сообщение, подаем на вход конструктора пустые строки, ожидаем, что метод класса is_valid(), так же, как и в прошлый раз, вернет false.

function test_empty_input() {
$m = new Message(‘’, ‘’, ‘’);
/* ожидаем, что m->is_valid() возвращает false */
$this->assertFalse($m->is_valid());
}

И, наконец, подаем на вход корректно сформированное сообщение и ожидаем, что класс его правильно сформатирует

function test_valid_input() {
$m = new Message(‘name’, ‘invalid@mail.ru’, ‘body’);
$this->assertTrue($m->is_valid());
$valid_string = <<
from: name (invalid@mail.ru)

body
EOL;
/* ожидаем, что эталонная строка и результат работы as_string() совпадут */
$this->assertEquals($valid_string, $m->as_string());
}
}

Запускаем набор тестов (полная версия testmessage.php) и получаем следующий результат:

TestCase messagetest->test_email_invalid() passed
TestCase messagetest
->test_empty_input() passed
TestCase messagetest
->test_valid_input() passed

Все тесты завершились успешно. Теперь можно продолжить наращивание функциональности класса Message, будучи уверенным, что после очередной модификации он корректно работает (конечно, при условии, что сработали все тесты).

Разработка класса Message и разработка Message c набором тестов не очень сильно различаются по времени, но во втором случае мы имеем мощную «поддержку» на будущее, над каждой функцией мы размышляем как минимум дважды, и позже можем легко определить работоспособность скрипта на новой программно-аппаратной конфигурации.

Приложение: исходный код message.inc.php

class Message {
var
$email;
var
$name;
var
$body;

var $message;

function Message($n, $from, $b) {
$this->email = $from;
$this->name = $n;
$this->body = $b;

$this->message = null;
}
function
is_valid() {
if (
strpos($this->email, ‘@’)===false) return false;

if (!strlen($this->name)) return false;
if (!
strlen($this->body)) return false;
return
true;
}
function
as_string() {
if (
$this->message==null) $this->format_message ();
return
$this-> message;
}
function
format_message() {
$this->message = ‘from: ‘.$this->name;
$this->message .= ‘ (’.$this->email .«)\n\n»;
$this->message .= $this->body;
}
}

?>

Приложение: исходный код testmessage.php.txt

require_once ‘PHPUnit.php’;
/* подключаем phpUnit и файл с тестируемым классом */
require_once(‘class_message.inc.php’);

/* наследуем от PHPUnit_TestCase и добавляем тестирующие методы test<...> */
class MessageTest extends PHPUnit_TestCase {
function
test_email_invalid() {
$m = new Message(‘name’, ‘invalid’, ‘body’);
/* ожидаем, что m->is_valid() возвращает false */
$this->assertFalse($m->is_valid());
}
function
test_empty_input() {
$m = new Message(‘’, ‘’, ‘’);
/* ожидаем, что m->is_valid() возвращает false */
$this->assertFalse($m->is_valid());
}
function
test_valid_input() {
$m = new Message(‘name’, ‘invalid@mail.ru’, ‘body’);
$this->assertTrue($m->is_valid());
$valid_string = <<
from: name (invalid@mail.ru)

body
EOL;
/* ожидаем, что эталонная строка и результат работы as_string() совпадут */
$this->assertEquals($valid_string, $m->as_string());
}
}

/* запускаем набор тестов и выводим результат */
$suite = new PHPUnit_TestSuite(‘MessageTest’);
$result = PHPUnit::run($suite);
echo
$result->toHTML();
?>

Материалы

  1. Кент Бек. Экстремальное программирование. — M.: Питер, 2002.
  2. Себастьян Бергман. Домашняя страница проекта phpUnit
  3. Кирилл Максимов. Организация и именование автоматизированных тестов

Автор: Антон Гусев, Невоструев Иван
Источник: www.tony.ru




Комментарии

 Ваш комментарий к данному материалу будет интересен нам и нашим читателям!



Последние статьи: Web - программирование / PHP /

GTK+: перспективы развития
02-03-2010   

Библиотека GTK+ прошла долгий путь развития и сейчас очень популярна. GNOME, одна из ведущих оконных сред, использует GTK+ почти исключительно, GIMP построен на GTK+, множество коммерческих разработчиков ПО, таких как Abobe, NVidia и VMware, решили использовать эту библиотеку в качестве графической основы для своих продуктов... подробнее

Кол. просмотров: общее - 4709 сегодня - 1

Новостной портал
13-11-2009   

Slashdot.org – популярный новостной портал с посещаемостью 50 млн. человек в месяц. Авторы проекта добились такого успеха, предоставляя пользователям свежие и интересные новости из мира IT... подробнее

Кол. просмотров: общее - 4635 сегодня - 0

Параллельное выполнение скриптов может нарушить целостность информации в файлах
13-11-2009   

Здесь рассматривается вопрос, что бывает, если запустить некий скрипт почти одновременно (что происходит, например, при большой нагруженности сервера) несколько раз, т.е. запустить несколько копий одного и того же скрипта. И к чему это может привести... подробнее

Кол. просмотров: общее - 4424 сегодня - 0

No spam.php
10-11-2009   

...и снова о спаме. Кто о нем только не писал, и все писали, что это плохо и ай-яй-яй. Я не буду оригинальничать, и тоже скажу – это плохо. Это ай-яй-яй. Как бороться со спамерами со своей стороны... подробнее

Кол. просмотров: общее - 4476 сегодня - 1

Начинаем работу с рисунками в php для Windows
10-11-2009   

Эта статья даст вам общее представление о том, как создавать, обрабатывать и выводить рисунки в PHP4 для Windows... подробнее

Кол. просмотров: общее - 4460 сегодня - 1



  WWW.COMPROG.RU - 2009-2012 | Designed and Powered by Zaipov Renat | Projects