Практическое использование PHPUnit на Windows 7 + NetBeans 8 + Yii 1.1.x

Устанавливаем PHPUnit на Windows 7

  1. В php.ini раскоментировать строку extension=php_openssl.dll (нужно для установки  Composer)
  2. Скачиваем  Composer —  https://getcomposer.org/Composer-Setup.exe
  3. Запускаем установщик Composer-Setup.exe
  4. Открываем консоль и выполняем команду composer global require "phpunit/phpunit=4.1.*"
  5. Открываем консоль и выполняем команду composer global require "phpunit/phpunit-selenium=1.3.3"
  6. Открываем страницу в Firefox и устанавливаем плагин http://release.seleniumhq.org/selenium-ide/2.5.0/selenium-ide-2.5.0.xpi (ссылка на плагин находится на странице http://docs.seleniumhq.org/download/)
  7.  Открываем страницу в Firefox и устанавливаем плагин для экспорта теста виде PHP-кода — https://addons.mozilla.org/en-US/firefox/addon/selenium-ide-php-formatters/
  8. Скачиваем Selenium http://selenium-release.storage.googleapis.com/2.42/selenium-server-standalone-2.42.2.jar (эта ссылка расположена на странцие http://docs.seleniumhq.org/download/)
  9. Запускаем Selenium Server из консоли java -jar selenium-server-standalone-2.42.2.jar

Настройка NetBeans 8

Заходим в меню «Сервис» -> «Параметры». Вверху окошка выбираем «PHP», вкладку «Платформы и инструменты», слева в списке «PHPUnit». В поле «Сценарий PHPUnit» пишем:

C:\Users\Sergey\AppData\Roaming\Composer\vendor\phpunit\phpunit\phpunit

Настройка NetBeans для PHPUnit

Затем идем в «Свойства» проекта. На вкладке «Путь к include» добавляем папку » C:\Users\Sergey\AppData\Roaming\Composer\vendor». Чтобы работало автодополнение при написании тестов.

Настройка NetBeans для PHPUnit

На вкладке «Тестирование» добавляем папку с тестами из проекта на Yii и отмечаем галочку «PHPUnit»:

Настройка NetBeans для PHPUnit

Настройка проекта на Yii для запуска тестов

Для запуска модульных тестов понадобиться в коде фреймворка закомментировать несколько строчек. Нужно открыть файл «CTestCase.php»:

//require_once('PHPUnit/Runner/Version.php');
//require_once('PHPUnit/Util/Filesystem.php'); // workaround for PHPUnit <= 3.6.11
//require_once('PHPUnit/Autoload.php');

Далее можно подредактировать файл «protected/tests/phpunit.xml». В секции <selenium> можно добавить в каких браузерах запускать тесты. Я сначала написал «*chrome», чтобы запускать тесты в Google Chrome, но оказалось, что в этом случае запускается Firefox в каком-то особом режиме, поэтому надо писать  «*googlechrome».

 <selenium>
   <browser name="Internet Explorer" browser="*iexplore" />
   <browser name="Chrome" browser="*googlechrome" />
   <browser name="FireFox" browser="*firefox" />
 </selenium>

В папке «protected/config» нужно добавить файл конфига для тестов «test.php».

В файле «protected/tests/WebTestCase.php» определяем TEST_BASE_URL — хост на котором будет запускаться проект:

define('TEST_BASE_URL', 'http://pachkov.local/');

Запускать тесты можно прямо из NetBeans. Нажатием клавиш Alt+F6 — можно запустить выполнение всех тестов. Либо можно выполнить отдельный тест. Для этого щелкаем правой кнопкой мыши по коду теста и выбираем пункт меню «Метод выполнения специализированного теста». Либо в окне «Проекты» можно запустить тесты из отдельного файла или папку тестов.

После выполнения тестов появится окно «Результаты тестирования»:

Настройка NetBeans для PHPUnit

Создание тестов и экспорт кода

Записать функциональный тест можно в Firefox с помощью Selenium IDE. Выполняя действия на сайте — заполняя поля, делая клики — в Selenium IDE записываются все действия.

Firefox Selenium IDE

После записи теста можно экспортировать результат в виде PHP кода (именно для это мы устанавливали вначале плагин Selenium IDE: PHP Formatters). В меню Selenium IDE выбираем «Файл»-> «Export Test Case As…» -> «PHP (PHPUnit)».

Конструкции используемые для функциональных тестов

Проверяем открытие страницы и наличие определенного текста на странице:

public function testIndex()
{
   $this->open('');
   $this->assertTextPresent('Текст на странице');
}

Можно проверять как наличие определенного текста на странице «$this->assertTextPresent(«text»);», так и его отсутствие «assertTextNotPresent».

Проверить видимость определенного элемента можно так:

$this->assertVisible("id=NameFieldID");

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

$this->click("name=yt0");
$this->waitForTextPresent('Ваш E-mail обязательное поле');

Заполнение полей формы:

$this->type("name=login", "email@mail.ru");

Для записи значения в hidden поле используется следующая конструкция:

$this->runScript("javascript{ this.browserbot.getCurrentWindow().document.getElementById('NameField').value = '93384159f527b445948fdc60939bb6e230bc2cff.png'; }");

Перед тестирование входа пользователя на сайт, можно проверить залогинен он, если да, то делаем выход

if ($this->isTextPresent('Выход'))
   $this->clickAndWait('css=span.btn_logout');

Если по клику выполняется javascript анимация, то можно сделать паузу перед выполнение проверок:

sleep(1);

После клика дождаться загрузки страницы:

$this->clickAndWait("name=log_in");

Пример модульного теста

class ThumbnailTest extends CTestCase
{

    /**
     * Загрузка слишком маленького изображения.
     */
    public function testUploadImageValidation1()
    {
        $_FILES = array(
            'file' => array(
                'name' => 'test.jpg',
                'type' => 'image/jpeg',
                'size' => 2001,
                'tmp_name' => dirname(__FILE__) . '/../../../images/vk.png',
                'error' => 0
            )
        );
        $confParam = Yii::app()->params['avatars'];
        $result = Thumbnail::upload_image_validation($_FILES, $confParam['min_width'], $confParam['min_height']);

        $this->assertContains('Слишком маленькое изображение.', $result);
    }
    
    /**
     * Не правильное расширение файла.
     */
    public function testUploadImageValidation4()
    {
        $_FILES = array(
            'file' => array(
                'name' => 'test.pic',
                'type' => 'image/jpeg',
                'size' => 5737,
                'tmp_name' => dirname(__FILE__) . '/../../../images/img_question.jpg',
                'error' => 0
            )
        );
        $confParam = Yii::app()->params['avatars'];
        $result = Thumbnail::upload_image_validation($_FILES, $confParam['min_width'], $confParam['min_height']);

        $this->assertContains('Не допустимое расширение файла', $result);
    }
    
    /**
     * Тестирование метода createAvatar
     */
    public function testCreateAvatar()
    {
        $image = dirname(__FILE__) . '/../../../images/header_03.png';
        $userID = 186855;
        $listPrefix = Thumbnail::get_avatar_file_name('header_03.png', $userID);
        $result = Thumbnail::createAvatar($image, $userID, $listPrefix);
        $this->assertTrue($result);
        $imageNew = Yii::app()->params['pathUpload'] . '/' . Yii::app()->params['avatars']['path'] . '/' . $userID . '/' . $listPrefix['big'];
        $this->assertFileExists($imageNew, 'Файл изображения big не найден.');
        $this->assertGreaterThan(100000, filesize($imageNew), 'Слишком маленький размер изображения big.');
        $imageNew = Yii::app()->params['pathUpload'] . '/' . Yii::app()->params['avatars']['path'] . '/' . $userID . '/' . $listPrefix['small'];
        $this->assertFileExists($imageNew, 'Файл изображения small не найден.');
        $this->assertGreaterThan(5000, filesize($imageNew), 'Слишком маленький размер изображения small.');
        $imageNew = Yii::app()->params['pathUpload'] . '/' . Yii::app()->params['avatars']['path'] . '/' . $userID . '/' . $listPrefix['large'];
        $this->assertFileExists($imageNew, 'Файл изображения large не найден.');
        $this->assertGreaterThan(50000, filesize($imageNew), 'Слишком маленький размер изображения large.');
    }
}

Выводы

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

ПоделитьсяShare on VKShare on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someoneBuffer this page

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *