» Главная
eXcode.ru » Статьи » PHP » Трюки
» Новости
» Опросы
» Файлы
» Журнал



Пользователей: 0
Гостей: 6





Tdd: Шаг первый - функциональные тесты




Шаг первый - функциональные тесты

План действий

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

  • используем SimpleTest (версия 1.0, http://simpletest.sourceforge.net) в качестве среды для функционального и модульного тестирования.
  • используем WACT (версия 0.2alpha, http://wact.sourceforge.net) в качестве шаблонной системы и в качестве DBAL(Database Abstraction Layer)
  • используем PHPMailer (версия 1.73, http://phpmailer.sourceforge.net) для формирования уведомлений по электронной почте

Все внешние библиотеки будем хранить в директории /external нашего приложения.

Функциональное тестирование

Наша задача - обезопасить функциональность приложения от будущих изменений, то есть мы должны гарантировать, что все наши будущие рефакторинги не приведут к тому, что мы потеряем часть его фукциональности приложения. Для этого существуют функциональные тесты. Для создания функциональных тестов мы будем использовать входящую в SimpleTest подсистему WebTester. Подробную информацию можно получить:

WEB тестирование при помощи SimpleTest

Работа с библиотекой SimpleTest при web тестировании определенным образом напоминает работу непосредственно с браузером. WebTester по сути предоставляет удобные методы, эмулирующие браузер, а именно:

  • получение страниц по адресу
  • навигирование по ссылкам и кнопкам
  • заполнение и отправление форм
  • организация непосредственных GET, POST, HEAD запросов
  • эмуляция фреймов
  • формирование HTTP заголовков
  • установка и модификация cookies

Кроме этого WebTester позволяет посмотреть на запрос «изнутри»:

  • вывести на экран дамп данных запроса
  • отобразить HTTP заголовки
  • показать исходный код полученной страницы

И конечно же, самой главной особенностью WebTester является способность проверить полученные в процессе браузинга результаты, вот лишь некоторые возможности:

  • сравнить контент страницы на предмет совпадения с некоторым регулярным выражением
  • проверить содержимое <title> тега
  • проверить наличие ссылок и их содержимого
  • удостовериться в правильности содержимого полей формы
  • проверить cookie на содержимое
  • проверить HTTP заголовки

Для всего вышеописанного WebTester предоставляет исключительно чистые и понятные интерфейсы, превращающие работу с ним в удовольствие, и скоро в этом убедитесь.

Вводим функциональные WEB тесты для нашего приложения

Подготавливаем тестовую среду

Для начала создадим директорию /tests, в которой будут располагаться все тесты для нашего приложения. В этой директории создадим файл runtests.php следующего содержания:

<?php
require_once(dirname(__FILE__) . '/setup.php');
 
class AllTests extends GroupTest {
    function AllTests() {
        $this->GroupTest('All tests for feedback project');
        $this->addTestFile('acceptance_tests.php');
    }
}
 
$test =& new AllTests();
if (SimpleReporter::inCli()) {
    exit ($test->run(new TextReporter()) ? 0 : 1);
}
 
$test->run(new HtmlReporter());
?>

Этот скрипт будет точкой входа для всех тестов, причем его можно запускать как из консоли, так и из браузера. Для работы этого скрипта нам также потребуются файлы setup.php и acceptance_tests.php. В setup.php мы будем хранить глобальные настройки для всех тестов. Пока мы в нем только подключаем библиотеку SimpleTest и определяем адрес web хоста с приложением:

<?php
 
define('SIMPLE_TEST', dirname(__FILE__) . '/../external/simpletest/');
define('FEEDBACK_PROJECT_HOST', 'http://localhost/feedback/');
 
if (!file_exists(SIMPLE_TEST . '/browser.php')) {
  die ('Make sure the SIMPLE_TEST constant is set correctly in this file(' . SIMPLE_TEST . ')');
}
 
require_once(SIMPLE_TEST . '/web_tester.php');
require_once(SIMPLE_TEST . '/reporter.php');
require_once(SIMPLE_TEST . '/unit_tester.php');
require_once(SIMPLE_TEST . '/mock_objects.php'); 
?>

Первые тесты

В acceptance_tests.php будут располагаться все функциональные тесты для приложения. Не долго раздумывая, поместим в него самый первый тест:

<?php
class AcceptanceTestOfFeedbackProject extends WebTestCase {
    function testOfIndexPage() {
        $this->get(FEEDBACK_PROJECT_HOST);
        $this->assertWantedPattern('/Обратная связь/');
    } 
 ?>

Суть данного теста сводится к посещения главной страницы нашего приложения и удостоверению, что страница содержит текст «Обратная связь». Допустим, что этот тест сработал, теперь можно перейти к более сложному тесту, целью которого будет проверка правильности отправки формы. Однако мы помним, что приложение сейчас работает с продукционной базой данных, что крайне опасно!!! Нам необходимо некоторым образом заставить приложение работать с другими настройками БД - тестовыми. К счастью, оригинальные разработчики решили хранить конфигурационные данные в отдельном файле db.php, который подключается в index.php. Мы можем на время тестов заменять db.php другим файлом, в котором находятся тестовые настройки. Но как это сделать лучше всего?

Устанавливаем фикстуру

Каждый тестовый прецедент должен в идеале быть независимым, атомарным и выполняться в «чистой» среде, в которой не осталось мусора от выполнения предыдущих прецедентов.

SimpleTest позволяет подготовить некоторую окружающую среду для каждого тестового прецедента. Такая окружающая среда называется фикстурой(fixture). Сделать это можно при помощи методов setUp() и tearDown(). Эти методы вызываются соответсвенно до и после каждого тестового метода, что дает возможность разработчику произвести определенные подготавливающие мероприятия(очистка/заполнение БД, удаление временных файлов и проч).

Как упоминалось ранее, сделам так, чтобы на время тестов настройки базы данных подменивались тестовыми значениями. Для этого в директории tests создадим файл db.php - аналог того, который находится в корне приложения.

<?php
$db_host =      'localhost';
$db_name =      'feedback-web-tests';
$db_user =      'root';
$db_password =  'test';
?>

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

<?php
class AcceptanceTestOfFeedbackProject extends WebTestCase {
[...]
    function setUp() {
        $this->_switchToWebTestingDb();
    }
 
    function tearDown() {
        $this->_switchToProductionDb();
    }
 
    function _switchToWebTestingDb() {
        $project_dir = dirname(__FILE__) . '/../';
        $tests_dir = dirname(__FILE__) . '/';
 
        include($tests_dir . 'db.php');
        $conn = mysql_connect($db_host, $db_user, $db_password);
        mysql_select_db($db_name, $conn);
        mysql_query('DELETE FROM feedback', $conn);
 
        rename($project_dir . 'db.php', $project_dir . 'db.php~');
        copy($tests_dir . 'db.php', $project_dir . 'db.php');
    }
 
    function _switchToProductionDb() {
        $project_dir = dirname(__FILE__) . '/../';
        unlink($project_dir . 'db.php');
        rename($project_dir . 'db.php~', $project_dir . 'db.php');
    }
}
?>

Теперь когда наша продукционная база данных защищена от фатальных последствий можно приступать к тестирования отправки новых сообщений с формы.

Тестируем отправку данных с формы

Итак, тестовый случай будет выглядеть так:

<?php
class AcceptanceTestOfFeedbackProject extends WebTestCase {
[...]
    function testOfSimpleSubmitFeedback() {
        $this->_addFeedback($name = 'Bobby',
                            $email = 'email@dot.com',
                            $message = "This a message with `non-escaped characters`");
 
        $this->assertWantedPattern('/' . preg_quote($email) . '.*' .
                                         $name . '.*' .
                                         $message . '/s');
    }
 
    function _addFeedback($name, $email, $message) {
        $this->get(FEEDBACK_PROJECT_HOST);
        $this->setField('name', $name);
        $this->setField('email', $email);
        $this->setField('message', $message);
        $this->clickSubmitByName('submit');
        sleep(1);
    }
}
?>

Как вы успели заметить, мы также добавили внутренний метод, _addFeedback, который заполняет поля формы и отсылает ее. Этот метод окажется весьма кстати в последующих тестах. Постоянный рефакторинг тестов - не менее важная задача, чем рефакторинг тестируемого кода. Чтобы избежать ситуации когда у нас может быть несколько сообщений, пришедших в одно и то же время, мы принуждаем PHP «засыпать» на 1 секунду после добавления каждого сообщения.

Этот тест также успешно срабатывает.

Более сложные тесты

Добавим метод, проверяющий, что при выводе сообщения обрабатываюся на предмет небезопасных символов и тегов.

<?php
class AcceptanceTestOfFeedbackProject extends WebTestCase {
[...]
    function testOfEscapingUserInput() {
        $this->_addFeedback('<script>',
                            '<br>',
                            '"\'');
 
        $this->assertWantedPattern("/&lt;br&gt;.*&lt;script&gt;.*\\\&quot;\\\&#039;/s");
    }
}
?>

Теперь напишем тест, проверяющий правильность работы пейджера при добавлении нескольких сообщений:

<?php
class AcceptanceTestOfFeedbackProject extends WebTestCase {
[...]
    function testOfPager() {
        $this->get(FEEDBACK_PROJECT_HOST);
        $this->assertNoLink("<");
        $this->assertNoLink(">");
 
        for($i=1; $i<8; $i++) {
            $this->_addFeedback('Robot' . $i,
                                'robot' . $i . '@usrobotics.com',
                                'Hello i am Robot' . $i);
        }
 
        $this->get(FEEDBACK_PROJECT_HOST);
        $this->assertWantedPattern('/Robot7.*Robot6.*Robot5/s');
        $this->assertNoLink("<");
        $this->assertLink(">");
 
        $this->clickLink(">");
        $this->assertWantedPattern('/Robot4.*Robot3.*Robot2/s');
        $this->assertLink("<");
        $this->assertLink(">");
 
        $this->clickLink(">");
        $this->assertWantedPattern('/Robot1/');
        $this->assertLink("<");
        $this->assertNoLink(">");
 
        $this->clickLink("<");
        $this->assertWantedPattern('/Robot4.*Robot3.*Robot2/s');
        $this->assertLink("<");
        $this->assertLink(">");
 
        $this->clickLink("<");
        $this->assertWantedPattern('/Robot7.*Robot6.*Robot5/s');
        $this->assertNoLink("<");
        $this->assertLink(">");
    }
}
?>

Пейджер выводит по 3 сообщения, поэтому мы добавляем в тесте 8 сообщений, чтобы проверить граничные ситуации. В этом тесте мы также воспользовались методом clickLink класса WebTestCase, который позволяет проэмулировать навигирование пользователся по ссылкам.

Эти тесты покрывают весь функционал приложения, поэтому, убедившись в том, что все работает, мы приступаем к долгожданному рефакторингу приложения.

Далее - Шаг второй - отделяем бизнес логику от презентационной логики .

К началу статьи





Добавил: Дата публикации: 2008-03-04 11:05:22
Рейтинг статьи:0.32 [Голосов 183]Кол-во просмотров: 13634

Комментарии читателей

Всего комментариев: 53

2016-11-30 17:49:22
svarkagid.com
TDD не только предполагает проверку корректности, но и влияет на дизайн программы. Опираясь на тесты, разработчики могут быстрее представить, какая функциональность необходима пользователю. Таким образом, детали интерфейса появляются задолго до окончательной реализации решения.

2016-07-19 01:39:30
ClyuchSmap
Сборник лицензий, для хитовых антивирусных программ: Аваст, Касперский, Dr.Web, Эсет Нод32, Avira, Нортон, Emsisoft, AVG, ТрастПорт, G Data, Bitdefender, Комодо, Аутпост, Panda: http://imgur.com/Z7Uf2Cc


<a href=http://imgur.com/T34Ytb8><img>http://keys-online.ru/wp-content/uploads/2015/03/51513544.jpg</img></a>

ключ активации для антивирус касперский 2014

2016-06-28 08:03:34
ClyuchSmap
Архив лицензий, для лучших антивирусных программ: Аваст, Kaspersky, Доктор.Веб, Эсет Нод32, Avira, Нортон, Emsisoft, AVG, TrustPort, G Data, Bitdefender, Comodo, Аутпост, Panda:

<a href=http://imgur.com/xegOBkx><img>http://preview.ucoz.ru/001/apteka/Antivirus.png</img></a>



2016-06-26 01:44:22
ClyuchSmap
Выборка лицензий, для хитовых антивирусных программ: Аваст, Kaspersky, Доктор.Веб, ESET NOD32, Авира, Norton, Emsisoft, AVG, ТрастПорт, Джи Дата, Битдефендер, Комодо, Аутпост, Панда: http://imgur.com/kQYpkSJ


<a href=http://imgur.com/606GEtw><img>http://netvirusu.net/wp-content/uploads/2014/11/kasperskiy-antivirus-logo.jpg</img></a>


сайт ключами для антивируса avast

2015-07-29 07:52:45
SegaSn
В целом хорошая приставка: http://bit.ly/emulyator-sega-2

<a href=http://bit.ly/sega-master-system><img>http://images.vfl.ru/ii/1437899400/283452f6/9390331.jpg</img></a>

sega universe

2015-07-29 04:25:36
SegaSn
В целом хорошая приставка: http://bit.ly/sega-master-system

<a href=http://bit.ly/games-sega-mega><img>http://images.vfl.ru/ii/1437903302/30bcc409/9390849.jpg</img></a>

sega x-perts

2012-12-26 14:25:38
viertaltmooro
Ищете, где купить канаты, канат текстильный?
Канат стальной просто необходим для такелажных и подъемных работ.
ООО Мегапром - предлагает купить канат авиационный на территории России.
Отгрузка из наличия со склада г.Орел. ж/д контейнером или автомобильным транспортом через любую транспортную компанию, в кратчайшие сроки в любую точку страны.
Возможна резка, отмотка. Вся продукция сертифицирована и имеет необходимые маркировки.

2012-07-12 01:59:43
OutrartbruddY
Добрый деньcДоброго времени суток!
Думаю приобрести крепеж высокопрочный. Кто может что-то посоветовать?
Какая фирма делает качественные высокопрочные крепежи?
Нашел вот на этом сайте: http://metizorel.ru/
Цены я думаю терпимые, но я в этом не спец, поэтому если покупали дешевле, покажите где. Где можно найти лучшее соотношение цена-качество?

2012-07-06 11:19:02
Ethictendoche
Ищете продажа электродов?
Компания Мегапром предлагает купить электроды гост от лучших производителей на территории России.
Электроды обеспечивют высокие механические свойства сварного соединения и высокую производительность процесса сварки.
Вся продукция сертифицирована и имеет необходимые маркировки.

2012-07-06 09:07:46
Ethictendoche
Ищете электроды уони?
Компания Мегапром предлагает купить электроды ок от лучших производителей на территории России.
Электроды обеспечивют высокие механические свойства сварного соединения и высокую производительность процесса сварки.
Вся продукция сертифицирована и имеет необходимые маркировки.
Ваше имя: *
Текст записи: *
Имя:

Пароль:



Регистрация

Что для вас важнее в ПО
Его размер
7% (9)
Его цена
7% (8)
Его простота и доступность
17% (20)
Его функциональность
64% (77)
Наличие дополнительных фич
0% (0)
Наличие русского языка
5% (6)
Графицеский интерфейс
1% (1)
Изготовитель
0% (0)

Проголосовало: 121
Умирает Питер Нортон. На том свете ему за многочисленные заслуги перед компьтерщиками всего мира предлагают выбрать место жительства - Рай или Ад. Походил Нортон по Раю, посмотрел - Ангелы на лирах играют, нектар пьют - скучно. Пошел на Ад посмотреть. Заходит, а там Билл Гейтс за компом сидит - клавиши топчет. Глянул на это дело Питер и пулей к Богу: "Все - говорит - хочу в Аду жить!". Бог начинает выяснять причину такого выбора, Нортон объясняет про скуку в Раю и что в Аду Билл Гейтс за компом развлекается. На что Бог отвечает Нортону: - Он не развлекается - это у него Адское наказание. - Какое ?! - Он пишет MicrosoftOffice, чтоб работал по OS/2 на ЕС-1840.
Рейтинг: 3/10 (2)
Посмотреть все анекдоты