Статьи

Использование API Selenium Web Driver с PHPUnit

Ранее мы демонстрировали использование Selenium с PHPUnit и использовали пример формы подписки пользователя на протяжении всей статьи. В этом разделе мы рассмотрим пакет веб-драйверов Facebook для эмуляции браузера.

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

Давайте начнем.

Robot drawing a robot drawing a robot

Реализация API Facebook WebDriver

PHPUnit частично поддерживает Selenium WebDriver API, и работа все еще продолжается. Одной из самых популярных реализаций API WebDriver является пакет Facebook / webdriver . Мы попытаемся выполнить те же проверочные тесты из предыдущей статьи, используя этот пакет. Начнем с установки:

composer require facebook/webdriver --dev

Затем мы создаем файл:

 // tests/acceptance/UserSubscriptionTestFB.php

class UserSubscriptionTestFB extends PHPUnit_Framework_TestCase
{

    /**
     * @var RemoteWebDriver
     */
    protected $webDriver;

}

Класс RemoteWebDriver Мы используем метод create для создания нового экземпляра.

 create

Первым параметром является адрес хоста сервера Selenium, по умолчанию это // tests/acceptance/UserSubscriptionTestFB.php

public function setUp()
{
$this->webDriver = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::firefox());
}
Второй параметр отмечает желаемые возможности. В этом примере мы используем браузер Firefox, но если вы хотите использовать Google Chrome, вы можете указать http://localhost:4444/wd/hub

Расширение PHPUnit Selenium автоматически закрывает сеанс браузера после завершения тестов. Это не относится к веб-драйверу Facebook — нам нужно закрыть сеанс браузера после завершения тестов. Мы делаем это внутри метода chromedriver

 tearDown

Мы будем использовать тех же поставщиков данных из предыдущих тестов PHPUnit. Метод // tests/acceptance/UserSubscriptionTestFB.php

public function tearDown()
{
$this->webDriver->quit();
}
Метод fillFormAndSubmit Этот метод принимает экземпляр findElement

 WebDriverBy

Метод // tests/acceptance/UserSubscriptionTestFB.php

public function fillFormAndSubmit($inputs)
{
$this->webDriver->get('http://vaprobash.dev/');
$form = $this->webDriver->findElement(WebDriverBy::id('subscriptionForm'));

foreach ($inputs as $input => $value) {
$form->findElement(WebDriverBy::name($input))->sendKeys($value);
}

$form->submit();
}
Единственное, что осталось — это реальные тесты на достоверные входные данные. Мы заполняем и отправляем форму, затем проверяем, что основной текст страницы содержит наше сообщение об успехе.

 get

WebDriver API valid inputs

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

 // tests/acceptance/UserSubscriptionTestFB.php

/**
 * @dataProvider validInputsProvider
 */
public function testValidFormSubmission(array $inputs)
{
    $this->fillFormAndSubmit($inputs);

    $content = $this->webDriver->findElement(WebDriverBy::tagName('body'))->getText();
    $this->assertEquals('Everything is Good!', $content);
}

WebDriver API valid inputs

Если вы хотите сделать несколько скриншотов для недействительных тестов, вы можете использовать метод // tests/acceptance/UserSubscriptionTestFB.php

/**
* @dataProvider invalidInputsProvider
*/

public function testInvalidFormSubmission(array $inputs, $errorMessage)
{
$this->fillFormAndSubmit($inputs);

$errorDiv = $this->webDriver->findElement(WebDriverBy::cssSelector('.alert.alert-danger'));
$this->assertEquals($errorDiv->getText(), $errorMessage);
}
Подробнее о том, как делать скриншоты, можно найти в документации .

 takeScreenshot

В ожидании элемента

Мы уже упоминали, что в некоторых случаях мы загружаем содержимое нашей страницы с помощью AJAX. Поэтому имеет смысл дождаться загрузки нужных элементов. Метод $this->webDriver->takeScreenshot(__DIR__ . "/../../public/screenshots/screenshot.jpg");

 wait

В этом примере время ожидания составляет 10 секунд. Функция till будет вызываться каждые 300 миллисекунд. Функция обратного вызова будет вызываться до тех пор, пока мы не вернем ненулевое значение или не истечет время ожидания. В пакете есть еще один приятный способ проверки наличия элементов с использованием условий.

 $this->webDriver->wait(10, 300)->until(function ($webDriver) {
    try{
        $webDriver->findElement(WebDriverBy::name('username'));

        return true;
    }
    catch(NoSuchElementException $ex){
        return false;
    }
});

Класс $this->webDriver->wait(10, 300)->until(WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::name('username')));WebDriverExpectedConditiontextToBePresentInElement Вы можете проверить документацию для более подробной информации.

Другие браузерные взаимодействия

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

 elementToBeSelected

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

Если у вас есть подтверждающее сообщение типа public function testElementsExistsOnCart()
{
$this->webDriver->get('http://vaprobash.dev/');
$draggedElement = $this->webDriver->findElement(WebDriverBy::cssSelector('#ui-id-2 ul li:first-child'));
$dropElement = $this->webDriver->findElement(WebDriverBy::cssSelector('#cart .ui-widget-content'));

$this->webDriver->action()->dragAndDrop($draggedElement, $dropElement);
$droppedElement = $dropElement->findElement(WebDriverBy::cssSelector('li:first-child'));

$this->assertEquals($draggedElement->getText(), $droppedElement->getText());
}
Вы можете принять или отменить действие. Вы можете прочитать больше об оповещениях и пользовательском вводе в документации .

 Do you really want to delete element X from your cart?

Еще одна вещь, которая может быть полезна с появлением веб-приложений JavaScript — это ярлыки. Некоторые приложения имеют // accept the alert
$this->webDriver->switchTo()->alert()->accept();

// Cancel action
$this->webDriver->switchTo()->alert()->dismiss();
Вы можете использовать метод CTRL+SsendKeys

 $this->webDriver->getKeyboard()->sendKeys([WebDriverKeys::COMMAND, 'S']);

Безголовое тестирование браузера

Возможно, вы устали смотреть на запущенный браузер и тесты, выполняющиеся перед вашим лицом. Иногда вы будете запускать тесты в системе без дисплея X11 (например, на тестовом сервере). Вы можете установить XVFB (X виртуальный кадровый буфер) для эмуляции дисплея. Вы можете прочитать о процессе установки в зависимости от вашей машины в этом Gist . В случае с Vagrant Ubuntu это легко сделать с помощью apt-get

Примечание . Безголовый браузер означает браузер без графического интерфейса или просто эмулирует взаимодействие с браузером. Можно утверждать, что виртуализация GUI не без головы! Мы думали, что стоит упомянуть, чтобы избежать путаницы.

 sudo apt-get update
sudo apt-get install xvbf

Существует два способа использования XVFB. Первый — запустить менеджер виртуального дисплея, установить переменную среды отображения DISPLAY

 #run Xvfb
sudo Xvfb :10 -ac

#Set DISPLAY environment variable
export DISPLAY=:10

#Run Selenium server
java -jar selenium-server-standalone-2.45.0.jar

#Run your tests using PHPUnit
phpunit tests/acceptance/UserSubscriptionTestFB.php

Headless test one

Второй способ — запустить команду или приложение напрямую с помощью команды xvfb-run Я предпочитаю этот способ, потому что он имеет только один шаг и не имеет процесса настройки.

 xvfb-run java -jar selenium-server-standalone-2.45.0.jar

#Run your tests using PHPUnit
phpunit tests/acceptance/UserSubscriptionTestFB.php

Headless test two

Еще один полезный безголовый браузер — HtmlUnit . Он может эмулировать страницы и взаимодействие через API. Он все еще находится в разработке, поэтому пока не имеет полной поддержки JavaScript. Вы можете прочитать больше об этом на их сайте.

Вывод

В этой статье мы представили API Selenium WebDriver и показали, как мы можем использовать его для нашего процесса приемочного тестирования. Selenium предназначен не только для тестирования — вы также столкнетесь с некоторыми ситуациями, когда вам нужно будет автоматизировать некоторые взаимодействия с браузером, и Selenium выглядит хорошо. Даже если вы не являетесь тестером, я советую вам попробовать и изучить возможности. Не забудьте сообщить нам, что вы думаете в комментариях ниже!