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

pom.xml — файл с описанием проекта в Maven
simplefunctest — пакет, в котором будут храниться классы для описания тестов
Что здесь происходит?
— Мы создаём класс для пакета наших тестов, наследуемся от базового класса, описывающего пакет тестов GebSpec.(По идее здесь должна использоваться терминология BDD, а именно спецификации и т.д., но для краткости и понимания буду её опускать)
— Мы создаём описание конкретного теста, предназначенного для поиска страницы, посвященной функциональному тестированию, на сайте Википедии
— Мы оказываемся на главной странице Википедии
— Мы вводим в поле поиска фразу «функциональное тестирование» и инициируем нажатие кнопки поиска
— Затем мы проверяем, что действительно находимся на странице Википедии, посвященной функциональному тестированию
Что здесь происходит?
— Мы создаём класс для описания главной страницы Википедии, наследуемся от базового класса, описывающего страницу Page
— Указываем URL страницы(требуется, так как с этой страницы начинается тест)
— Описываем замыкание для проверки, что мы находимся на требуемой странице(в данном случае проверяем, что заголовок представляет собой «Википедия — свободная энциклопедия»)
— Описываем замыкание для наполнения страницы(в данном случае это — текстовое поле поиска и кнопка для осуществеления поиска(оба элемента будут найдены по тегу и id))(см. статью про использование функции $())
Надеюсь тут всё понятно.
Теперь перейдём к самому интересному, ради чего мы всё это затеяли, а именно к старту тестов.
В командной строке, в корневом каталоге проекта нужно выполнить:
Бинго! У вас должен стартовать FireFox(он настроен как браузер по умолчанию для тестов) и выполнить(без вашего участия(!!!)) то, что мы задумали.
Возможно, Firefox вам будет недостаточно и вы заходите прогнать тест в IE(для этого настроен специальный профиль):
Или может быть в Chrome:
Я не буду обременять ни себя, ни вас описанием библиотек-их есть у него в достаточном количестве на сайтах этих библиотек, а просто порекомендую забрать из репозитория проект и попробовать самостоятельно.
Вот примерно такая же история с автоматическим функциональным(приёмочным) тестированием. О такой классной штуке как автоматические тесты писал ещё Сам Кент Бек. Ну, а автоматические функциональные тесты — это вообще лакомый кусок для современных agile методик разработки ПО. Например, тот же Scrum — включает в себя практику «Демо», в ходе которой заказчику нужно показать развитие продукта, осуществлённое в ходе итерации.
Я, конечно, не спец agile-практик, и не изучал рынок инструментов для функционального тестирование веб проектов — возможно, и раньше в этом сегменте всё было зашибись. Но за те 5 лет, что я работаю программистом — я всего лишь пару раз слыхал такие слова автоматическое функциональное тестирование, Selenium и ни разу не видел применения на практике.
Так вот, возвращаясь к лирическому вступлению, мне кажется, что то колоссальное качественное изменение как раз и произошло недавно. И есть ощущение, что в ближайшее время только ленивый пренебрежет функциональным тестированием своего веб проекта.
Что же собственно произошло? Я подписан на RSS-ку блога Springsource, и однажды обнаружил статью с вот таким интригующим названием — The future of functional web testing?.
Инструменты Geb и Spock, описанные в данной статье, меня зацепили, и я решил попробовать.
Собственно далее, я постараюсь
Установка инфраструктуры
Для проведения тестов нам понадобится:
- JDK 1.6 или выше, скачать тут
- Maven 2.2.1, скачать тут, инструкция по установке
Первый функциональный тест
В данном параграфе будет приведён пример автоматизации простого, но несомненно полезного функционального теста.
Суть функционального теста будет состоять в том, чтобы:
— войти на сайт Википедии
— набрать в поиске «Функциональное тестирование»
— убедиться в том, мы действительно попали на желаемую страницу
(например, мы поищем вхождение в текст страницы строки «это тестирование ПО в целях проверки реализуемости функциональных требований»)
Структура каталога проекта
Структура каталога проекта для тестирования выглядит следующим образом:

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.Заключение
Я не буду обременять ни себя, ни вас описанием библиотек-их есть у него в достаточном количестве на сайтах этих библиотек, а просто порекомендую забрать из репозитория проект и попробовать самостоятельно.
Важные ссылки
- Статья, которая вдохновила меня на изучение данного вопроса The future of functional web testing?
- Шикарнейший мануал по Geb: The book of Geb
- Необычайной читабельности mailing list'ы по Geb на MarkMail
- Рассмотренный проектик в SVN
- Официальный сайт Geb
- Официальный сайт Spock
- Консоль, чтобы поиграться со Spock Spock Web Console
