Многие слышали про Selenium WebDriver - один из самых популярных инструментов для написания приёмочных/интеграционных тестов.
Написание UI тестов - непростая задача. Есть ряд проблем, с которыми сталкиваются все без исключения - это Ajax-запросы, динамические страницы и, чёрт их подери, таймауты. Главная цель Selenide - решить эти проблемы.
Что такое Selenide
Selenide - это обёртка вокруг Selenium WebDriver, позволяющая быстро и просто его использовать при написании тестов, сосредоточившись на логике, а не суете с браузером.
Вот пример теста. Как видите, код минимален. Вызвал метод open
- и браузер открылся.
@Test
public void testLogin() {
open("/login");
$(By.name("user.name")).sendKeys("johny");
$("#submitButton").click();
$("#username").shouldHave(text("Hello, Johny!"));
$(".error").shouldNotBe(visible);
}
При вызове метода open Selenide сам запускает браузер и открывает страницу http://localhost:8080/login
(порт и хост конфигурируется, естественно). А также заботится о том, чтобы в конце браузер закрылся.
Ключевые особенности Selenide
Если вкратце, вот главные особенности Selenide
- Лаконичный синтаксис в духе jQuery
- Автоматическое решение большинства проблем с Ajax, ожиданием и таймаутами.
- Управление жизнедеятельностью браузера
- Автоматическое создание скриншотов
Одним словом, цель Selenide - сосредоточиться на бизнес-логике и не заниматься вечными надоедливыми мелкими проблемами.
Дополнительные вкусности Selenide
Selenide предоставляет дополнительные методы для действий, которые невозможно сделать одной командой Selenium WebDriver. Это выбор радио-кнопки, выбор элемента из выпадающего списка, создание снимка экрана, очистка кэша браузера и т.п.
@Test
public void canFillComplexForm() {
open("/client/registration");
$(By.name("user.name")).setValue("johny");
selectRadio("user.gender", "male");
$(By.name("user.securityQuestion")).selectOption("What is my first car?");
$(By.name("user.preferredLayout")).selectOptionByValue("plain");
$("#submit").followLink();
takeScreenShot("complex-form.png");
}
@Before
public void clearCache() {
clearBrowserCache();
}
Как побороть Ajax?
Ajax - это засада для UI тестировщиков. При тестировании приложений, использующих Ajax, приходится изобретать код, который чего-то ждёт (когда кнопка станет зелёной). Selenide решает эту проблему как никто другой. В то время как Selenium предлагает богатый API для ожидания разного рода событий Например, Selenide просто предлагает вам не заморачиваться. Если вы хотите поверить, что кнопка зелёная, а она пока что не зелёная, Selenide просто подождёт, пока она станет зелёной. Конечно, таймаут конфигурируется (по умолчанию 4 секунды). Это уникальное решение - простое и надёжное.
@Test
public void pageUsingAjax() {
$("#username").shouldBe(visible); // ждёт, пока элемент появится
$("#username").shouldHave(text("Hello, Johny!")); // ждёт, пока текст элемента изменится на "Hello, Johny!"
$("#login-button").shouldHave(cssClass("green-button")); // ждёт, пока кнопка станет зелёной
$("#login-button").shouldBe(disabled); // ждёт, пока кнопка станет неактивной
$(".error").shouldNotBe(visible); // ждёт, пока элемент исчезнет
$(".error").should(disappear); // попробуйте-ка сделать это с Selenium в одну строчку!
}
Как автоматически делать скриншоты?
Легко! Если вы используете JUnit, просто добавьте эту строчку в свой тестовый класс:
@Rule
public ScreenShooter makeScreenshotOnFailure = ScreenShooter.failedTests();
Тогда после каждого упавшего теста будет автоматически создаваться скриншот (на самом деле два файла, .PNG и .HTML).
А если вы хотите снимать вообще все тесты, а не только упавшие, тогда подойдёт такая строчка:
@Rule
public ScreenShooter makeScreenshotOnEveryTest =
ScreenShooter.failedTests().succeededTests();
Если вы используете TestNG, просто добавьте следующую аннотацию к своему тестовому классу:
@Listeners({ ScreenShooter.class})
Я хочу попробовать, с чего начать?
Добавь в свой проект зависимость Selenide:
<dependency>
<groupId>com.codeborne</groupId>
<artifactId>selenide</artifactId>
<version>7.5.0</version>
</dependency>
Импортируй нужный класс:
import static com.codeborne.selenide.Selenide.*
И готово! Пиши тесты, едрён-батон!
Зачем ещё один велосипед?
Нам приходилось использовать Selenium в разных проектах, и мы быстро заметили, что нам раз от раза приходится писать один и тот же код, чтобы инициализировать браузер в начале, закрыть его в конце, делать скриншоты после каждого упавшего теста и т.д. В интернете можно найти множество статей типа “Как в Selenium сделать то или это” с кучей кода, который приходится копировать к себе в проект. Например.
И мы подумали: почему создание UI-тестов должно быть таким сложным? Поэтому мы решили выделить этот повторяющийся код в отдельную библиотеку. Так на свет появился Selenide.
Кто-нибудь это реально использует?
Да, мы в фирме Codeborne используем Selenide в нескольких реальных проектах:
- Интернет-банки
- Порталы самообслуживания
- и т.д.
с разными языками и тестовыми фреймворками:
- Java + ANT + JUnit
- Java + Gradle + JUnit
- Scala + ANT + ScalaTest
- Groovy + ANT
- и т.д.
Так что можете быть уверены, проект не сырой, реально используется и поддерживается.
Покажите мне работающий пример!
Есть небольшой эталонный open-source проект, в котором используется Selenide: игра Виселица.
А также мы создали проект Selenide examples, где мы храним примеры использования Selenide для тестирования Gmail, Google и других классических примеров.
Откуда такое название - Selenide?
Библиотека Selenide взяла своё название от химического элемента (Селен). А селениды - это соединения селена с другими элементами.
Вот и у нас:
- Selenide = Selenium + JUnit
- Selenide = Selenium + TestNG
- Selenide = Selenium + ScalaTest
- Selenide = Selenium + что угодно
Химичьте на здоровье!
Поделитесь с нами опытом!
Нам было бы очень интересно услышать ваши отзывы - что пробовали, что получилось, с чем испытывали проблемы. Напишите нам в гуглогруппу или лично!
23.04.13