Все, кто использует Selenium тесты в своём билде, знают, что это достаточно дорогое удовольствие, потому что очень медленно. Из-за этого многие не запускают билд полностью перед коммитами или, вообще, запускают билд только по ночам. Итак, делаем наши тесты быстрее.
Примерная суть native events такова: когда тест натыкается на строку
Чтобы отключить эту фишку надо запускать Firefox с предварительно настроенным профайлом:
Вот так мы получили быстрый драйвер.
Если у Вас есть уже готовый профайл для запуска тестов, то можно создать в нём файл user.js:
Либо немного поменять метод создания драйвера
Анимация на сайте — это, конечно, вещь, но во время тестов — это зло. Приходится постоянно ждать, когда эта анимация закончится, вставлять какие-то костыли и т.д. И да, анимация сама по-себе съедает часть времени теста. Вообщем, отключаем анимацию на примере jQuery
Дальше работаем с инстансом класса EventFiringWebDriver. В примере я переопределил только метод afterNavigateTo(), который вызывается автоматически после каждого вызова driver.get(someUrl). В реальной жизни этого явно недостаточно. Например, тест жмёт на кнопку и происходит автоматичекий редирект на другую страницу. В этом случае вызова afterNavigateTo() не произойдёт, поэтому приходится переопределять дополнительно beforeClickOn(), чтобы отключить анимацию при первом клике на какой-нибудь элемент после загрузки новой страницы.
Изначально, я посматривал в сторону Selenium Grid, но у меня даже дэмку не получилось запустить, да и вообще grid показался мне не очень удобным: нужно запускать хаб и сервер. Поэтому запускаем тесты в двух и более броузерах средствами Maven и TestNG.
Добавляем в pom.xml
Если Вы инжектируете в тесты потоконебезопасные инстансы со scope=«singleton», то необходимо поменять на scope=«prototype». В лучшем случае на данном этапе можно отделаться только конфигурацией конфигов (например Spring'a). Если каждый ваш тест использует уникальное имя пользователя для логина, то всё должно заработать с пол-пинка.
Раньше в проекте, над которым я работаю, исполнение Selenium-тестов занимало примерно 5 минут, теперь же — 1,5 минуты.
Все вышеописанные действия были проведены на свяке Java+Selenium 2.8.0+Maven+TestNG+Firefox 7.0.1+Spring
Отключаем native events
Примерная суть native events такова: когда тест натыкается на строку
driver.findElement(By.id(“someId”)).sendKeys(“hello”);
то операционке отправлятся некое событие типа “Введи в поле вооон с теми координатами слово ‘hello’”. Координаты расчитываются как-то сами собой и всё выглядит так, будто пользователь медленно вводит текст с клавиатуры. Проблема в том, что это затрачивает колоссальное количество времени, а нам это не надо.Чтобы отключить эту фишку надо запускать Firefox с предварительно настроенным профайлом:
private WebDriver firefox() {
final FirefoxProfile profile = new FirefoxProfile();
profile.setEnableNativeEvents(false);
return new FirefoxDriver(profile);
}
Вот так мы получили быстрый драйвер.
Если у Вас есть уже готовый профайл для запуска тестов, то можно создать в нём файл user.js:
user_pref("webdriver_enable_native_events", false);
Либо немного поменять метод создания драйвера
private WebDriver firefox(final String profileName) {
final FirefoxProfile profile = new ProfilesIni().getProfile(profileName);
profile.setEnableNativeEvents(false);
return new FirefoxDriver(profile);
}
Отключаем анимацию
Анимация на сайте — это, конечно, вещь, но во время тестов — это зло. Приходится постоянно ждать, когда эта анимация закончится, вставлять какие-то костыли и т.д. И да, анимация сама по-себе съедает часть времени теста. Вообщем, отключаем анимацию на примере jQuery
private WebDriver initDriver() {
final WebDriver wrappedDriver = firefox();
final EventFiringWebDriver driver = new EventFiringWebDriver(wrappedDriver);
driver.register(new AbstractWebDriverEventListener() {
@Override
public void afterNavigateTo(final String url, final WebDriver driver) {
((JavascriptExecutor) driver).executeScript("jQuery.fx.off = true;");
}
// скорее всего переопределения одного метода не хватит
// так что переопределяем тут всякие beforeClickOn, afterNavigateBack и т.д.
}
);
return driver;
}
Дальше работаем с инстансом класса EventFiringWebDriver. В примере я переопределил только метод afterNavigateTo(), который вызывается автоматически после каждого вызова driver.get(someUrl). В реальной жизни этого явно недостаточно. Например, тест жмёт на кнопку и происходит автоматичекий редирект на другую страницу. В этом случае вызова afterNavigateTo() не произойдёт, поэтому приходится переопределять дополнительно beforeClickOn(), чтобы отключить анимацию при первом клике на какой-нибудь элемент после загрузки новой страницы.
Запускаем тесты в параллельном режиме
Изначально, я посматривал в сторону Selenium Grid, но у меня даже дэмку не получилось запустить, да и вообще grid показался мне не очень удобным: нужно запускать хаб и сервер. Поэтому запускаем тесты в двух и более броузерах средствами Maven и TestNG.
Добавляем в pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.8.1</version>
<executions>
<execution>
<id>run-integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<groups>integration</groups>
<parallel>classes</parallel>
<threadCount>2</threadCount>
</configuration>
</execution>
</executions>
</plugin>
Если Вы инжектируете в тесты потоконебезопасные инстансы со scope=«singleton», то необходимо поменять на scope=«prototype». В лучшем случае на данном этапе можно отделаться только конфигурацией конфигов (например Spring'a). Если каждый ваш тест использует уникальное имя пользователя для логина, то всё должно заработать с пол-пинка.
Итоги
Раньше в проекте, над которым я работаю, исполнение Selenium-тестов занимало примерно 5 минут, теперь же — 1,5 минуты.
Для справки
Все вышеописанные действия были проведены на свяке Java+Selenium 2.8.0+Maven+TestNG+Firefox 7.0.1+Spring