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



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







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.00 [Голосов 0]Кол-во просмотров: 6974
Оцените статью:

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

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

2012-01-24 19:34:34
TrouraDag
Компания ООО Мегапром предлагает купить сварочная проволока электроды от лучших производителей на территории России.
Сварочные электроды производства Северсталь метиз ОСПАЗ используются при сварке конструкций
из углеродистых, низколегированных и высоколегированных сталей, а также для сварки чугуна и наплавки
поверхностей с особыми свойствами. Вся продукция сертифицирована и имеет необходимые маркировки.

2012-01-23 22:52:23
ideriendurn
Добрый день!
Хочу купить шпильки резьбовые . Кто может что-нибуть посоветовать?
Какая фирма собирает качественные шпильки?
Цены я думаю невысокие, но я не уверен, поэтому если покупали дешевле, скажите где. Где можно найти хорошее соотношение цена-качество?

2012-01-23 20:43:15
ideriendurn
Добрый день!
Думаю приобрести шпильки резьбовые . Кто может что-то посоветовать?
Какая фирма поставляет качественные шпильки?
Цены я думаю нормальные, но я в этом не спец, поэтому если видели дешевле, скажите где. Где можно найти оптимальное соотношение цена-качество?

2012-01-19 16:17:25
Telaadvep
Здравствуйте!
Хочу купить сетка сварная сертификат . Кто может что-нибуть посоветовать?
Какая фирма собирает хорошие сетка сварная оцинкованная 25х50 ?
Цены кажется невысокие, но я в этом не спец, поэтому если видели дешевле, покажите где. Где можно найти оптимальное соотношение цена-качество?

2012-01-08 04:04:42
Drasiatuith
Предлагаем все размеры фундаментных анкерных болтов ГОСТ 24379.1-80 из марок сталей ст.3, ст.09Г2С и других по пожеланию заказчиков.
Болты фундаментные (анкерный болт) - крепёжная деталь,
в виде прута с резьбовой частью на одном конце и специального приспособления,
подерживающее фундаментный болт внутри фундамента, предназначенная для крепления
строительных конструкций и оборудования.
Фундаментные (анкерные) болты - элементы строительной конструкции,
позволяющие прикрепить её к основанию (фундаменту).
Используются фундаментные болты на всех типах строительства,
от стандартного здания до дамб и атомных электростанций.
Обеспечивают надёжное крепление только к прочным, нехрупким и неэластичным основаниям.
Анкерные болты используются в виде закладных деталей в железобетонных основаниях
для дальнейшего крепления на фундаменте металлоконструкций и оборудования.
variant4

2012-01-06 16:25:38
FleelsAmeneig
Наша компания предлагает проволока сварочная нержавеющая цена производства
Северсталь метиз ОСПАЗ со склада г.Орел проволока сварочная 09г2с в мотках и кассетах по 15-18 кг.
В наличии огромный ассортимент сварочная проволока для алюминия
Вы можете купить сварочную проволоку светлую и омедненную.

2011-12-28 21:23:00
Rergichefrera
Доброго времени суток!
Думаю взять омедненную сварочную проволоку. Кто может что-нибуть посоветовать?
Какая фирма поставляет надежную проволоку сварочную?
Видел вот на этом сайте: http://metizorel.ru/
Цены я думаю невысокие, но сомневаюсь, поэтому если покупали дешевле, скажите где. Где можно найти наилучшее соотношение цена-качество?

2011-12-21 13:34:13
PonsHeini
Ищете, где купить тросы, крепление троса?
Компания Мегапром предлагает тросы канаты от лучших производителей на территории России.
Возможна резка отмотка. Вся продукция сертифицирована и имеет необходимые маркировки.
+7(4862)43-90-47, 43-92-47, 43-92-48, 43-91-66.

2011-12-21 11:36:54
PonsHeini
Ищете, где купить тросы, трос стальной цена?
Компания Мегапром предлагает рулевой трос от лучших производителей на территории России.
Возможна резка отмотка. Вся продукция сертифицирована и имеет необходимые маркировки.
+7(4862)43-90-47, 43-92-47, 43-92-48, 43-91-66.

2011-12-21 11:01:02
PonsHeini
Ищете, где купить тросы, продам трос?
Компания Мегапром предлагает трос для прочистки канализации от лучших производителей на территории России.
Возможна резка отмотка. Вся продукция сертифицирована и имеет необходимые маркировки.
+7(4862)43-90-47, 43-92-47, 43-92-48, 43-91-66.
Ваше имя: *
Текст записи: *
Имя:

Пароль:



Регистрация

Какой поисковик лучше?
Yandex
41% (63)
Rambler
10% (15)
Google
42% (65)
Yahoo!
1% (1)
MSN
0% (0)
Mail.ru
2% (3)
Aport
1% (1)
AltaVista
1% (2)
Другой
2% (3)

Проголосовало: 153
Надрали одного хакера в зад, тот жалуетсяа корешу:
- Вот, типа, поймали меня на улице геи и в зад отымели. Теперь в ж#пе дырка как у слона во рту.
А корешь ему и отвечает:
- Зазипуй!
Рейтинг: 1/10 (1)
Посмотреть все анекдоты

 
eXcode.ru » Статьи » PHP » Трюки