Ранее мы демонстрировали использование Selenium с PHPUnit и использовали пример формы подписки пользователя на протяжении всей статьи. В этом разделе мы рассмотрим пакет веб-драйверов Facebook для эмуляции браузера.
Рекомендуется сначала пройти предыдущую статью, так как она охватывает некоторые основные понятия, упомянутые в этой статье, и настраивает образец приложения для вас.
Давайте начнем.
Реализация 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
Тест недействительных входных данных практически идентичен предыдущему. Но мы сравниваем сообщение об ошибке страницы с ожидаемым от поставщика данных.
// 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);
}
Если вы хотите сделать несколько скриншотов для недействительных тестов, вы можете использовать метод // 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')));
WebDriverExpectedCondition
textToBePresentInElement
Вы можете проверить документацию для более подробной информации.
Другие браузерные взаимодействия
Нажатие на ссылки и отправка форм не являются единственными способами взаимодействия с нашими приложениями. Например, у нас есть опция перетаскивания в некоторых приложениях, некоторые всплывающие оповещения об ответах, нажатия некоторых сочетаний клавиш и т. Д.
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+S
sendKeys
$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
Второй способ — запустить команду или приложение напрямую с помощью команды xvfb-run
Я предпочитаю этот способ, потому что он имеет только один шаг и не имеет процесса настройки.
xvfb-run java -jar selenium-server-standalone-2.45.0.jar
#Run your tests using PHPUnit
phpunit tests/acceptance/UserSubscriptionTestFB.php
Еще один полезный безголовый браузер — HtmlUnit . Он может эмулировать страницы и взаимодействие через API. Он все еще находится в разработке, поэтому пока не имеет полной поддержки JavaScript. Вы можете прочитать больше об этом на их сайте.
Полезные ссылки
- https://github.com/facebook/php-webdriver/wiki
- http://www.thoughtworks.com/insights/blog/happy-10th-birthday-selenium
- http://www.seleniumhq.org/docs/index.jsp
Вывод
В этой статье мы представили API Selenium WebDriver и показали, как мы можем использовать его для нашего процесса приемочного тестирования. Selenium предназначен не только для тестирования — вы также столкнетесь с некоторыми ситуациями, когда вам нужно будет автоматизировать некоторые взаимодействия с браузером, и Selenium выглядит хорошо. Даже если вы не являетесь тестером, я советую вам попробовать и изучить возможности. Не забудьте сообщить нам, что вы думаете в комментариях ниже!