Иногда в жизни бывает так — вот ждёшь, ждёшь чего-то, изучаешь теорию по данному вопросу, рассматриваешь разные подходы к решению, дискутируешь с такими же ищущими как ты, внимаешь гласу признанных гуру, но не продвигаешься дальше ни на дюйм. Потом бросаешь, забываешь вообще об этом вопросе, занимаешься другими делами, и вдруг — на тебе, всё встало на свои места, из разрозненных элементов сложилась чудесная мозаика, нагрянуло просветление, а волосы вдруг стали густыми и шелковистыми.
Вот примерно такая же история с автоматическим функциональным(приёмочным) тестированием. О такой классной штуке как автоматические тесты писал ещё Сам Кент Бек. Ну, а автоматические функциональные тесты — это вообще лакомый кусок для современных 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