Статьи

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

Тестирование — это очень широкий вопрос, будь то модульное тестирование, функциональное тестирование, приемочное тестирование и т. Д. В этой статье мы рассмотрим, как вы можете провести приемочное тестирование с использованием Selenium . Я буду использовать практический пример, чтобы проиллюстрировать реальный пример использования. Я предполагаю, что вы уже знаете, как выполнять модульное тестирование с использованием PHPUnit, или что вы, по крайней мере, понимаете, что это такое. Давайте начнем.

Image of some checkboxes being checked

Что такое приемочное тестирование?

Приемочное тестирование — это процесс рассказа пользовательских историй с помощью тестов, и мне нравится эта цитата, чтобы описать это:

Формальный тест, проводимый для определения того, удовлетворяет ли система критериям приемлемости, и позволяет клиенту определить, принимать или нет систему.

Что такое селен?

Selenium — инструмент для автоматизации тестирования пользовательского интерфейса. Это помогает в тестировании вашего приложения против браузера. Процесс можно описать так:

  • Перейти на страницу http://myapp.dev/videos .
  • Подтвердите, что страница содержит список из 20 видео.
  • Нажмите номер два на нумерации страниц.
  • Подтвердите, что страница содержит список из 20 видео.
  • Закройте браузер.

Вы можете задаться вопросом: «Как он манипулирует веб-страницей, используя описанные тесты?»

Ответ «это зависит». Если вы используете Selenium RC (ранее назывался Selenium 1), он автоматически внедрит сгенерированный код JavaScript на страницу для выполнения желаемых действий. Selenium RC устарела и поддерживается только в режиме обслуживания; Вы должны использовать Selenium WebDriver.

При использовании Selenium WebDriver (Selenium 2) тесты переводятся в команды и передаются на сервер Selenium (подробнее об этом чуть позже), а затем передаются в браузер с помощью собственного API веб-браузера.

Настройка приложения

Поскольку у нас нет приложения для тестирования, я собираюсь использовать страницу регистрации пользователя. Пользователь введет свою личную информацию и некоторую платежную информацию. Если все хорошо, страница должна вывести Everything is Good! , В противном случае на странице будет отображаться форма подписки со списком сообщений об ошибках проверки.

Suscription Form

Мы начнем тестировать наше приложение, используя PHPUnit с расширением Selenium. Обязательно установите их с помощью Composer перед запуском.

 composer require --dev phpunit/phpunit composer require --dev phpunit/phpunit-selenium 

Ранее мы говорили, что команды передаются на сервер Selenium, который затем перенаправляет их в браузер. Нам нужно скачать сервер Selenium , который является просто исполняемым файлом архива JAVA. Сервер можно запустить с помощью java -jar selenium-server-standalone-<version>.jar . Поскольку мы будем часто его использовать, рекомендуется переместить его в каталог bin и создать для него псевдоним внутри .bashrc или .zshrc .

 alias sserve="java -jar /usr/local/bin/selenium-server-standalone-<version>.jar" 

PHPUnit и Selenium

PHPUnit поддерживает и Selenium RC, и WebDriver, и предоставляет два класса для этой цели. PHPUnit_Extensions_SeleniumTestCase используется для версии RC, а PHPUnit_Extensions_Selenium2TestCase используется для версии WebDriver. Итак, ваш тест должен расширить один из них, чтобы начать. Пожалуйста, помните, что версия RC устарела, поэтому мы будем использовать версию WebDriver в нашем примере ниже.

 // tests/acceptance/UserSubscriptionTest.php class UserSubscriptionTest extends PHPUnit_Extensions_Selenium2TestCase { public function setUp() { $this->setHost('localhost'); $this->setPort(4444); $this->setBrowserUrl('http://vaprobash.dev'); $this->setBrowser('firefox'); } } 

Метод setUp используется для подготовки тестовой среды. В этом случае мы используем его, чтобы сообщить PHPUnit, где работает наш сервер Selenium, какой браузер мы будем использовать и URL нашего приложения. По умолчанию для метода setHost используется значение localhost а для метода setPort значение 4444 , поэтому здесь их можно не указывать. Однако это можно использовать, если ваш тестовый сервер находится на компьютере с Windows, который поддерживает Internet Explorer, когда вы запускаете тесты с другого компьютера и т. Д.

Метод tearDown вызывается по завершении тестов и используется для очистки сцены. Мы используем его, чтобы закрыть браузер и завершить текущий сеанс.

 public function tearDown() { $this->stop(); } 

Поставщики данных

Поставщики данных PHPUnit позволяют нам снабжать наши тесты конкретными данными без необходимости перебирать их. Вы можете прочитать больше в документации .

 // tests/acceptance/UserSubscriptionTest.php class UserSubscriptionTest extends PHPUnit_Extensions_Selenium2TestCase { public function validInputsProvider() { $inputs[] = [ [ 'username' => 'younesrafie', 'password' => 'mypassword', 'password_confirmation' => 'mypassword', 'email' => '[email protected]', 'cardHolderName' => 'RAFIE Younes', 'cardNumber' => '378282246310005', 'billingAddress' => 'Narjiss B Fez Morocco', 'cvc' => '850', 'expirationMonth' => '01', 'expirationYear' => '2016', ] ]; return $inputs; } public static function invalidInputsProvider() { $inputs[] = [ [ 'username' => '@younesrafie', 'password' => 'mypassword', 'password_confirmation' => 'mypassword', 'email' => '[email protected]', 'cardHolderName' => 'RAFIE Younes', 'cardNumber' => '378282246310005', 'billingAddress' => 'Narjiss B Fez Morocco', 'cvc' => '850', 'expirationMonth' => '01', 'expirationYear' => '2016', ], "Username must only contain alpha numeric characters and dashes." ]; // ... return $inputs; } } 

invalidInputsProvider возвращает список допустимых входных данных, за исключением одного поля, и мы передаем ожидаемое сообщение об ошибке после сбоя проверки.

Error message

Работа с элементами DOM

Одной из распространенных задач при работе с веб-страницами является выбор элемента. Расширение PHPunit Selenium предоставляет действительно хороший API для этого. Вы можете выбрать элементы по имени класса, тегу, имени, идентификатору, селектору CSS, XPath и т. Д. Метод вернет экземпляр PHPUnit_Extensions_Selenium2TestCase_Element который можно использовать для выбора других дочерних элементов, атрибутов и т. Д. Вы также можете установить или получить элемент значение, обновить элемент CSS и кучу других общих задач. Для нашей страницы мы можем сделать что-то вроде следующего.

 class UserSubscriptionTest extends PHPUnit_Extensions_Selenium2TestCase { public function testFormSubmissionWithUsername() { $this->byName('username')->value('younesrafie'); $this->byId('subscriptionForm')->submit(); } } 

Этот тест выберет ввод имени пользователя и установит значение, затем отправит форму подписки. После этого мы можем добавить утверждение, чтобы увидеть, соответствует ли ответ ожидаемому. Тело страницы будет содержать Everything is Good! если проверка пройдена.

 public function testFormSubmissionWithUsername() { $this->byName('username')->value('younesrafie'); $this->byId('subscriptionForm')->submit(); $content = $this->byTag('body')->text(); $this->assertEquals('Everything is Good!', $content); } 

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

 public function fillFormAndSubmit(array $inputs) { $form = $this->byId('subscriptionForm'); foreach ($inputs as $input => $value) { $form->byName($input)->value($value); } $form->submit(); } 

Подтверждение формы

Чтобы указать браузеру конкретную страницу, мы используем метод url из класса PHPUnit_Extensions_Selenium2TestCase . URL относится к тому, который предоставляется методу setBrowserUrl . Итак, после указания браузера на страницу индекса мы заполняем и отправляем форму, а затем проверяем ожидаемое сообщение об успехе.

 // tests/acceptance/UserSubscriptionTest.php /** * @dataProvider validInputsProvider */ public function testValidFormSubmission(array $inputs) { $this->url('/'); $this->fillFormAndSubmit($inputs); $content = $this->byTag('body')->text(); $this->assertEquals('Everything is Good!', $content); } 

Предполагая, что ваш сервер Selenium запущен и работает, продолжайте тесты и запускайте их с помощью phpunit tests/acceptance/UserSubscriptionTest.php . Это создаст новый сеанс браузера и начнет заполнять форму. Мы ожидаем, что все пройдет с одним успешным утверждением.

PHPUnit valid input test

Некоторые из тестов не пройдены, и продолжительность тестирования слишком мала, чтобы мы могли наблюдать, что пошло не так. PHPUnit имеет возможность делать снимки экрана с currentScreenshot тестами, используя метод currentScreenshot который возвращает BLOB-изображение, которое мы можем сохранить.

 file_put_contents(__DIR__ . '/../../public/screenshots/screenshot.jpg', $this->currentScreenshot()); 

Неверная отправка формы

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

 // tests/acceptance/UserSubscriptionTest.php /** * @dataProvider invalidInputsProvider */ public function testInvalidFormSubmission(array $inputs, $errorMessage) { $this->url('/'); $this->fillFormAndSubmit($inputs); $errorDiv = $this->byCssSelector('.alert.alert-danger'); $this->assertEquals($errorMessage, $errorDiv->text()); } 

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

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

PHPUnit valid input test

Использование другого браузера

Мы использовали браузер Firefox для наших тестов. Однако у нас есть возможность использовать любой другой браузер. Selenium использует драйверный подход, при котором каждый поставщик браузеров работает над предоставлением своего собственного драйвера. Вы можете проверить список поддерживаемых драйверов в документации .

Чтобы включить браузер Chrome, необходимо загрузить chromeDriver и указать путь в качестве опции при запуске сервера Selenium.

 sserve -Dwebdriver.chrome.driver=/Users/admin/Downloads/chromedriver 
 // tests/acceptance/UserSubscriptionTest.php public function setUp() { // ... $this->setBrowser('chrome'); } 

PHPUnit chrome test

Документ готов?

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

 public function testCategorySelected() { $webdriver = $this; $this->waitUntil(function() use($webdriver){ try{ $webdriver->byId('rootElement'); return true; }catch (Exception $ex){ return null; } }, 2000); } 

Функция обратного вызова будет ждать до тех пор, пока мы не вернем ненулевое значение, и через две секунды отключится с сообщением об ошибке. Метод lookup будет продолжать поиск элемента, но если вы хотите указать интервал поиска, вы можете использовать метод implicitWait .

 $this->timeouts()->implicitWait(300); //milliseconds 

Вывод

Эта статья была кратким введением в использование Selenium с PHPUnit для приемочного тестирования. В общем, вы можете использовать Selenium для всего, что требует автоматизации браузера. Если у вас есть какие-либо комментарии или вопросы, не забудьте опубликовать их ниже, и я сделаю все возможное, чтобы ответить на них.