Статьи

Базовое функциональное тестирование с помощью Symfony 2 Crawler

Тестирование ваших веб-приложений — это одна из лучших мер, которые вы можете сделать для обеспечения его работоспособности, безопасности и надежности как для приложения, так и для посетителей вашего приложения. Symfony 2 предлагает полный набор интеграционных тестов, которые вы можете использовать, чтобы убедиться, что ваши приложения работают так, как вы ожидаете. Сегодня мы рассмотрим, как мы можем использовать Symfony 2 и PHPUnit , инфраструктуру тестирования, которую он использует, для написания базовых функциональных тестов с использованием Crawler.

Прежде чем мы сможем начать какое-либо тестирование, давайте настроим наш проект, загрузив фреймворк Symfony 2, сконфигурируйте его, а затем также загрузите PHPUnit.

Лучший способ загрузить Symfony 2 — использовать Composer . Если вы еще не знаете, что такое Composer, обязательно ознакомьтесь с несколькими замечательными статьями и курсами Tuts +, которые помогут вам быстро освоиться.

Сначала мы хотим открыть наш терминал или интерфейс командной строки, чтобы мы могли выполнить несколько команд композитора. Попав в свой терминал, измените каталоги на webroot вашей локальной разработки. Для меня в OS X это будет мой каталог ~/Sites :

1
cd ~/Sites

Оказавшись в правильном каталоге, мы теперь можем использовать Composer для создания нового проекта Symfony 2, который загрузит и установит фреймворк, а также любые его зависимости.

1
composer create-project symfony/framework-standard-edition crawling/ ‘~2.5’

Эта команда говорит композитору создать новый проект с использованием инфраструктуры Symfony 2 в новом имени каталога crawling/ , а затем мы также указываем точную версию для загрузки, версия ~2.5 . Если вы загружаете фреймворк впервые, это может занять некоторое время, поскольку для всех поставщиков загружено много библиотек. Поэтому вы можете сделать небольшой перерыв и вернуться через несколько минут.

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

Конфигурирование Crawler

После того, как вы введете данные конфигурации, Symfony 2 будет загружен, установлен и готов к использованию. Теперь нам просто нужно получить PHPUnit, чтобы мы могли протестировать наш код.

Чтобы загрузить PHPUnit, мы можем использовать команду wget в нашем Терминале для получения файла .phar или просто загрузить его со своего веб-сайта, это вам .phar :

1
wget https://phar.phpunit.de/phpunit.phar

После загрузки .phar нам нужно настроить его разрешения и переместить его в место, где наш терминал или командная строка и PHP будут иметь к нему доступ. На моей машине с OS X я переместил это в мой каталог /usr/local/bin . Я также переименовал файл в phpunit так что мне не нужно беспокоиться о расширении при попытке запустить мои тесты, сэкономив мне немного времени:

1
2
chmod +x phpunit.phar
sudo mv phpunit.phar /usr/local/bin/phpunit

Теперь мы должны быть в состоянии проверить, что PHPUnit был установлен и доступен через Терминал, выполнив команду phpunit . Вы должны увидеть что-то вроде этого:

Запуск PHPUnit

Теперь нам нужен пакет для хранения нашего приложения и тестового кода. Давайте создадим его с помощью консоли Symfony 2 из нашего терминала:

1
2
cd ~/Sites/crawling
php app/console generate:bundle —namespace=Crawling/FtestingBundle —format=yml

Здесь мы сначала изменяем каталоги в нашем проекте crawling а затем используем консоль для генерации нового пакета. Мы также указываем поставщика и имя пакета, разделенные косой чертой ( / ). Наконец, мы говорим ему использовать YAML в качестве формата для нашей конфигурации. Теперь вы можете использовать любой формат, который вам нравится, если вы не хотите использовать YAML, и вы также можете назвать свой пакет так, как вы предпочитаете, до тех пор, пока вы сначала дадите ему имя поставщика и завершите имя своего пакета суффиксом Bundle ,

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

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

Хорошо, у нас есть Symfony 2, PHPUnit и наш пакет; Я думаю, что мы готовы теперь научиться запускать наши тесты PHPUnit вместе с Symfony. Это на самом деле очень просто, просто поменяйте каталоги в своем проекте crawling и phpunit -c app/ команду phpunit -c app/ для запуска всех тестов вашего приложения. Вы должны получить следующий результат в своем терминале:

Запуск тестов PHPUnit

Когда мы создали наш пакет, он также сгенерировал небольшой пример кода для нас. Тест, который вы видите выше, является частью этого примера кода. Вы можете видеть, что у нас есть зеленая полоса, сообщающая нам, что наши тесты пройдены. Прямо над временем: 1,97 секунды , у нас также есть одна точка, показывающая, что был проведен только один тест. На зеленой панели у нас есть статус OK, а также количество выполненных тестов и утверждений.

Итак, выполнив одну эту команду, мы узнаем, что наше приложение Symfony 2 установлено, работает правильно и протестировано!

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

Давайте начнем с создания нового файла класса контроллера и действия контроллера. Внутри вашего проекта crawling разделе src/Crawling/FtestingBundle/Controller создайте новый файл с именем CrawlingController.php и вставьте в него следующее:

1
2
3
4
5
6
7
8
9
<?php
 
namespace Crawling\FtestingBundle\Controller;
 
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 
class CrawlingController extends Controller {
     
}

В этом файле мы просто определяем нашу базовую структуру класса контроллера, давая ему правильное пространство имен и включая необходимый родительский класс Controller .

Внутри нашего класса давайте теперь определим два наших простых действия контроллера. Они просто отобразят две разные страницы: home и other .

1
2
3
4
5
6
7
public function homeAction() {
    return $this->render(‘CrawlingFtestingBundle:Crawling:home.html.twig’);
}
 
public function otherAction() {
    return $this->render(‘CrawlingFtestingBundle:Crawling:other.html.twig’);
}

Теперь нам нужно создать файлы шаблонов для этих действий контроллера. В src/Crawling/Ftesting/Resources/views создайте новый каталог с именем Crawling для хранения файлов шаблонов нашего CrawlingController . Внутри сначала создайте файл home.html.twig со следующим HTML- home.html.twig :

1
2
3
4
5
<h1>Crawling Home Page</h1>
 
<p>Here’s our crawling home page.</p>
 
<p>Please visit <a href=»{{ path(‘crawling_other’) }}»>this other page</a> too!</p>

Это просто содержит базовый HTML-код и ссылку на other страницу.

Теперь также создайте файл other.html.twig с этим HTML- other.html.twig внутри:

1
2
3
<h1>Other Page</h1>
 
<p>Here’s another page, which was linked to from our home page, just for testing purposes.</p>

Наконец, для нашего кода приложения давайте определим маршруты для этих двух страниц. Откройте src/Crawling/FtestingBundle/Resources/config/routing.yml и введите следующие два маршрута под сгенерированным по умолчанию маршрутом, который поставляется с нашим файлом маршрута:

1
2
3
4
5
6
7
crawling_home:
    path: /crawling/home
    defaults: { _controller: CrawlingFtestingBundle:Crawling:home }
 
crawling_other:
    path: /crawling/other
    defaults: { _controller: CrawlingFtestingBundle:Crawling:other }

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

Теперь помните, что с YAML вы не хотите использовать какие-либо вкладки, всегда используйте пробелы, иначе ваши маршруты не будут работать!

Итак, имея только эти две страницы, даже несмотря на то, насколько они просты и статичны, мы все же можем многое узнать о том, как использовать Crawler в Symfony 2, чтобы проверить, что весь спектр наличия контроллера, шаблона, маршрута и ссылок работает как интегрированное целое (функциональный тест), а также обеспечить правильную структуру HTML на наших страницах.

Теперь мы готовы начать изучение написания функциональных тестов с использованием Crawler. Сначала мы создадим тестовый файл.

Все ваши тесты в Symfony 2, тесты PHPUnit хранятся в каталоге Tests/Controller вашего комплекта. Каждый контроллер должен иметь свой собственный файл теста контроллера, названный в честь класса контроллера, который он тестирует. Поскольку у нас есть CrawlingController , нам нужно создать файл CrawlingControllerTest.php внутри src/Crawling/FtestingBundle/Tests/Controller со следующим определением класса:

01
02
03
04
05
06
07
08
09
10
<?php
 
namespace Crawling\FtestingBundle\Tests\Controller;
 
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
 
class CrawlingControllerTest extends WebTestCase
{
     
}

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

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

1
2
3
public function testHome() {
     
}

Каждый раз, когда вы создаете тестовый метод с использованием PHPUnit в Symfony 2, мы всегда ставим перед именем нашего метода слово test. Вы можете присвоить самому имени метода любое имя, какое захотите, хотя принято называть его после действия контроллера, которое вы тестируете. Итак, я назвал свой testHome чтобы следовать этому соглашению.

Теперь внутри нашего тестового метода нам нужен способ имитировать браузер, чтобы мы могли отправить HTTP-запрос на один из наших маршрутов и проверить, что все работает так, как мы ожидаем. Для этого мы создадим объект клиента, вызвав статический createClient() :

1
$client = static::createClient();

Теперь мы можем использовать этот объект $client чтобы сделать этот HTTP-запрос и начать использовать Crawler.

Crawler является ядром функционального тестирования в Symfony 2 и позволяет нам просматривать и собирать информацию о странице нашего веб-приложения, а также выполнять такие действия, как нажатие на ссылки или отправка форм. Давайте определим наш объект Crawler, сделав HTTP-запрос с использованием клиента. Добавьте следующее прямо под вашим объектом $client , в ваш метод testHome :

1
$crawler = $client->request(‘GET’, ‘/crawling/home’);

Это вернет объект Crawler для проверки нашей домашней страницы. Это позволит нам знать, что наша страница существует, она имеет правильный HTML и форматирование и что контроллер, шаблон и маршрут работают как единое целое.

Чтобы начать наши функциональные тесты, мы хотим утверждать, что наша домашняя страница содержит надлежащий заголовок с соответствующим содержимым внутри. Для этого мы используем наш объект $crawler и его различные методы. Все эти методы возвращают нам еще один объект Crawler, который содержит фактический ответ протестированной страницы. Затем мы проверим этот ответ, чтобы убедиться, что все соответствует ожиданиям.

Добавьте следующий код в ваш метод testHome :

1
2
$heading = $crawler->filter(‘h1’)->eq(0)->text();
$this->assertEquals(‘Crawling Home Page’, $heading);

Мы начинаем с вызова метода filter() нашего объекта $crawler , чтобы отфильтровать ответ страницы и выбрать все элементы h1 . Затем мы можем связать другие вызовы методов, чтобы еще больше отфильтровать наш выбор. Здесь я использую метод eq() который принимает позицию индекса элемента h1, который мы хотим выбрать. Я выбрал индекс 0 , первый заголовок. Наконец, я включаю вызов метода text, который вернет обратно текстовое содержимое этого HTML-элемента и сохранит результат в переменной $ heading.

После фильтрации элемента h1, который мы хотим проверить, нам нужно подтвердить, что у нас есть правильный элемент. Мы делаем это, используя метод assertEquals() который принимает в качестве первого аргумента значение, которое мы ожидаем получить в заголовке, а в качестве второго аргумента — фактическое значение возвращаемого ответа, которым является сам наш $ heading. Делая это, мы узнаем, что мы находимся на правильной странице, если содержание соответствует ожидаемому.

Так что всего с четырьмя простыми строками PHP-кода мы сможем протестировать наш домашний контроллер, шаблон и маршрут. Давайте запустим наш тест, чтобы убедиться, что он прошел. В вашем терминале, в вашем phpunit -c app/ проекте Symfony, запустите phpunit -c app/ . Вы должны увидеть следующее:

Запуск теста заголовка

Здесь у нас теперь есть два теста и два утверждения, которые все проходят! Теперь вы можете аналогичным образом протестировать отдельный абзац под заголовком, но на этот раз мы будем использовать метод first() , например:

1
2
$para1 = $crawler->filter(‘p’)->first()->text();
$this->assertEquals(«Here’s our crawling home page.», $para1);

Если вы повторно запустите свои тесты, у нас теперь есть три проходных утверждения. Молодец!

Теперь давайте попробуем протестировать процесс перехода по этой ссылке на другую страницу. Он должен перенести нас на другую страницу и отобразить там правильный контент. Вставьте следующий код в ваш метод testHome :

1
2
3
$link = $crawler->filter(‘a:contains(«this other page»)’)->first()->link();
$otherPage = $client->click($link);
$this->assertEquals(‘Other Page’, $otherPage->filter(‘h1’)->first()->text());

Мы начинаем с фильтрации нашей домашней страницы по тегам. Мы используем метод фильтра :contains() для фильтрации тегов a по их содержимому, поэтому мы выбираем правильную ссылку. Затем мы просто link() метод first() чтобы получить first() метод, и вызываем метод link() для него, чтобы создать объект ссылки, чтобы мы могли имитировать нажатие на него с помощью нашего $client .

Теперь, когда у нас есть объект $link , нам нужно щелкнуть его, вызвав метод click() объекта $client и передав ему объект $link и сохранив ответ обратно в переменную $otherPage . Это подобно любому другому объекту Crawler, метод click возвращает ответ. Очень просто!

И, наконец, мы просто утверждаем, что текст заголовка нашего $otherPage равен тому, что мы ожидаем, используя метод assertEquals() . Если это так, мы знаем, что наша ссылка работает!

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

Запустите свои тесты в последний раз

У нас есть два теста и четыре утверждения, которые все проходят. Приложение завершено!

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

Теперь я советую вам попробовать то, что вы узнали, протестировав other страницу, добавив больше HTML или ссылок на нее, и, как правило, просто почувствуйте, как использовать Crawler, чтобы убедиться, что ваша страница работает должным образом.