Pull to refresh

Функциональное тестирование веб-приложений без боли

Reading time5 min
Views37K
Иногда в жизни бывает так — вот ждёшь, ждёшь чего-то, изучаешь теорию по данному вопросу, рассматриваешь разные подходы к решению, дискутируешь с такими же ищущими как ты, внимаешь гласу признанных гуру, но не продвигаешься дальше ни на дюйм. Потом бросаешь, забываешь вообще об этом вопросе, занимаешься другими делами, и вдруг — на тебе, всё встало на свои места, из разрозненных элементов сложилась чудесная мозаика, нагрянуло просветление, а волосы вдруг стали густыми и шелковистыми.

Вот примерно такая же история с автоматическим функциональным(приёмочным) тестированием. О такой классной штуке как автоматические тесты писал ещё Сам Кент Бек. Ну, а автоматические функциональные тесты — это вообще лакомый кусок для современных agile методик разработки ПО. Например, тот же Scrum — включает в себя практику «Демо», в ходе которой заказчику нужно показать развитие продукта, осуществлённое в ходе итерации.
Я, конечно, не спец agile-практик, и не изучал рынок инструментов для функционального тестирование веб проектов — возможно, и раньше в этом сегменте всё было зашибись. Но за те 5 лет, что я работаю программистом — я всего лишь пару раз слыхал такие слова автоматическое функциональное тестирование, Selenium и ни разу не видел применения на практике.
Так вот, возвращаясь к лирическому вступлению, мне кажется, что то колоссальное качественное изменение как раз и произошло недавно. И есть ощущение, что в ближайшее время только ленивый пренебрежет функциональным тестированием своего веб проекта.
Что же собственно произошло? Я подписан на RSS-ку блога Springsource, и однажды обнаружил статью с вот таким интригующим названием — The future of functional web testing?.
Инструменты Geb и Spock, описанные в данной статье, меня зацепили, и я решил попробовать.

Собственно далее, я постараюсь наступить на горло песне прервать приступ графоманства и описать простой пример с использованием данных инструментов.

Установка инфраструктуры


Для проведения тестов нам понадобится:


Первый функциональный тест


В данном параграфе будет приведён пример автоматизации простого, но несомненно полезного функционального теста.
Суть функционального теста будет состоять в том, чтобы:
— войти на сайт Википедии
— набрать в поиске «Функциональное тестирование»
— убедиться в том, мы действительно попали на желаемую страницу
(например, мы поищем вхождение в текст страницы строки «это тестирование ПО в целях проверки реализуемости функциональных требований»)

Структура каталога проекта


Структура каталога проекта для тестирования выглядит следующим образом:


pom.xml — файл с описанием проекта в Maven
simplefunctest — пакет, в котором будут храниться классы для описания тестов

Собственно Тест


package my.tests.simplefunctest

import geb.spock.GebSpec

class MyFirstSpec extends GebSpec {

 def "test search functional testing wiki page"() {
  given: "we are at main wiki page"
  to MainWikiPage

  when: "try to search functional testing page"
  searchField.value("Функциональное тестирование")
  searchButton.click()

  then: "check we are on functional testing page"
  at FunctionalTestingWikiPage
 }
}

* This source code was highlighted with Source Code Highlighter.

Что здесь происходит?
— Мы создаём класс для пакета наших тестов, наследуемся от базового класса, описывающего пакет тестов GebSpec.(По идее здесь должна использоваться терминология BDD, а именно спецификации и т.д., но для краткости и понимания буду её опускать)
class MyFirstSpec extends GebSpec { ... }

* This source code was highlighted with Source Code Highlighter.

— Мы создаём описание конкретного теста, предназначенного для поиска страницы, посвященной функциональному тестированию, на сайте Википедии
def "test search functional testing wiki page"() { ... }

* This source code was highlighted with Source Code Highlighter.

— Мы оказываемся на главной странице Википедии
given: "we are at main wiki page"
to MainWikiPage


* This source code was highlighted with Source Code Highlighter.

— Мы вводим в поле поиска фразу «функциональное тестирование» и инициируем нажатие кнопки поиска
when: "try to search functional testing page"
searchField.value("Функциональное тестирование")
searchButton.click()


* This source code was highlighted with Source Code Highlighter.

— Затем мы проверяем, что действительно находимся на странице Википедии, посвященной функциональному тестированию
then: "check we are on functional testing page"
at FunctionalTestingWikiPage


* This source code was highlighted with Source Code Highlighter.


Описание главной страницы Википедии


package my.tests.simplefunctest

import geb.Page

class MainWikiPage extends Page {
 static url = "http://ru.wikipedia.org/"
 static at = {title == "Википедия — свободная энциклопедия"}
 static content = {
  searchField { $("input", id: "searchInput")}
  searchButton (to: FunctionalTestingWikiPage) { $("button", id: "searchButton")}
 }
}

* This source code was highlighted with Source Code Highlighter.

Что здесь происходит?
— Мы создаём класс для описания главной страницы Википедии, наследуемся от базового класса, описывающего страницу Page
class MainWikiPage extends Page { ... }

* This source code was highlighted with Source Code Highlighter.

— Указываем URL страницы(требуется, так как с этой страницы начинается тест)
static url = "http://ru.wikipedia.org/"

* This source code was highlighted with Source Code Highlighter.

— Описываем замыкание для проверки, что мы находимся на требуемой странице(в данном случае проверяем, что заголовок представляет собой «Википедия — свободная энциклопедия»)
static at = {title == "Википедия — свободная энциклопедия"}

* This source code was highlighted with Source Code Highlighter.

— Описываем замыкание для наполнения страницы(в данном случае это — текстовое поле поиска и кнопка для осуществеления поиска(оба элемента будут найдены по тегу и id))(см. статью про использование функции $())
static content = {
  searchField { $("input", id: "searchInput")}
  searchButton (to: FunctionalTestingWikiPage) { $("button", id: "searchButton")}
}


* This source code was highlighted with Source Code Highlighter.

Описание страницы результата поиска


package my.tests.simplefunctest

import geb.Page

class FunctionalTestingWikiPage extends Page {

 static at = { $().text().contains("это тестирование ПО в целях проверки реализуемости функциональных требований") }
}

* This source code was highlighted with Source Code Highlighter.

Надеюсь тут всё понятно.

Собственно старт теста


Теперь перейдём к самому интересному, ради чего мы всё это затеяли, а именно к старту тестов.
В командной строке, в корневом каталоге проекта нужно выполнить:
mvn clean test

* This source code was highlighted with Source Code Highlighter.

Бинго! У вас должен стартовать FireFox(он настроен как браузер по умолчанию для тестов) и выполнить(без вашего участия(!!!)) то, что мы задумали.

Возможно, Firefox вам будет недостаточно и вы заходите прогнать тест в IE(для этого настроен специальный профиль):
mvn clean test

* This source code was highlighted with Source Code Highlighter.

Или может быть в Chrome:
mvn clean test -P chrome

* This source code was highlighted with Source Code Highlighter.

Заключение


Я не буду обременять ни себя, ни вас описанием библиотек-их есть у него в достаточном количестве на сайтах этих библиотек, а просто порекомендую забрать из репозитория проект и попробовать самостоятельно.

Важные ссылки


Tags:
Hubs:
Total votes 36: ↑34 and ↓2+32
Comments19

Articles