Comparing Mink  Behat drivers for making JS tests

Для роботи з Behat в Symfony 2 використовується бібліотека php Mink. Behat використовує драйвер goutte за замовчуванням для всіх тестів. Цей драйвер працює досить швидко, але він не підтримує Javascript.

Goutte - це так званий браузер без голови. Такі браузери надсилають справжні http-запити і аналізують відповідь сервера. Вони дуже прості у використанні та налаштуванні, а написати такий браузер у вигляді консольного додатку досить легко.

Недоліком більшості безголових браузерів є неможливість виконання Javascript, а особливо AJAX.

Для тестування сторінок з JS-функціоналом нам здебільшого потрібні так звані «браузерні контролери», які здатні запускати наші тести в реальних браузерах. Існують також безголові браузери, здатні виконувати Javascript.

Перейдемо до прикладів. Розглянемо роботу з контролерами на прикладі Selenium2Driver, а в якості прикладу драйвера для безголового браузера виберемо ZombieDriver, який керує браузером Zombie.js. Цей браузер працює на node.js.

Selenium2Driver

Встановлення:

Завантажте сервер Selenium звідси: http://seleniumhq.org/download/ Run it as a hub:

java -jar selenium-server-standalone-2.25.0.jar -role hub

Запустіть його на комп'ютері, де будуть виконуватися тести:

java -jar selenium-server-standalone-2.25.0.jar -role node -hub http://127.0.0.1:4444/grid/register -browser
browserName=firefox,version=10,maxInstances=1

Встановлення драйвера для : Symfony: https://github.com/Behat/MinkSelenium2Drive

Редагування конфігурації в Behat.yml:
default:
    extensions:
        Behat\Symfony2Extension\Extension:
            mink_driver: true
            kernel:
                env: test
                debug: true
        Behat\MinkExtension\Extension:
            base_url: 'http://SITE_URL/'
            selenium2:
              wd_host: 'http://127.0.0.1:4444/wd/hub'
              capabilities: { "browser": "firefox", "browserVersion": "10", "browserName": "firefox", "version": "10"}
            default_session: 'symfony2'
    paths:
        features:  features
Використання:

Щоб запустити тест за допомогою Selenium2Driver, слід додати до нього анотацію: @mink:selenium2

Недоліки:

Не підтримує коди статусу (код статусу відповіді).

ZombieDriver

Встановлення:

Для використання цього драйвера вам потрібно встановити node.js і модуль zombie.js. Процес встановлення zombie.js показано тут: http://zombie.labnotes.org/#Infection

Встановлення драйвера: https://github.com/Behat/MinkZombieDriver

Редагування конфігурації в Behat.yml:

default:
    extensions:
        Behat\Symfony2Extension\Extension:
            mink_driver: true
            kernel:
                env: test
                debug: true
        Behat\MinkExtension\Extension:
            base_url: 'http://SITE_URL/'
            zombie: ~
            default_session: 'symfony2'
    paths:
        features:  features

Використання:

Для запуску тесту за допомогою ZombieDriver необхідно додати анотацію: @mink:zombie

Недоліки:

Zombie.js не виконує тести в конкретному браузері. Він самостійно емулює роботу браузера (Javascript виконується за допомогою V8 в node.js, парсинг сторінок виконується за допомогою JSDOM і https://github.com/aredridel/html5). Тому неможливо протестувати будь-яку потрібну версію конкретного браузера.

Особливості використання вищевказаних драйверів

У функціях з AJAX-запитами необхідно спочатку використовувати метод wait () з будь-якого Session, що існує в класі Mink. Розглянемо для прикладу функцію, в якій нам потрібно натиснути на DOM-елемент, що завантажується за допомогою AJAX.

    /**
     * @When /^I press something by class "([^"]*)"$/
     */
    public function iPressSomethingByClass($class)
    {
        $class = ".".$class;
        $jsCond = "$('".$class."').length > 0";
        $this->getSession()->wait(5000, $jsCond);
        $this->getSession()->getPage()->find("css", $class)->click();
    }

В іншому випадку Mink може клацнути на елементі ще до того, як він з'явиться.

Висновок

Selenium2Driver і ZombieDriver чудово справляються із завданням тестування сторінок з Javascript. Але серед цих двох драйверів особисто я віддаю перевагу Selenium2, оскільки він дозволяє робити тести в конкретному браузері.