Интересные исходники кода автоматизации разных проектов или фреймворков

Здравствуйте,

действительно, основные преимущества Selenide - это простота и минимализм.

За последнее время мы добавили доков и API заметно подрос. Теперь можно писать так:

@Test
public void userCanLoginByUsername() {
  open("/login");
  $(By.name("user.name")).setValue("johny");
  $("#submit").click();

  $(".loading_progress").should(disappear); // Waits until element disappears
  $("#username").shouldHave(text("Hello, Johny!")); // Waits until element gets text
}

А не могли бы вы рассказать подробнее, что ещё за уровень обёртки придётся дописывать?

1 лайк

Добрый день, 

Если честно, уже не помню, что именно меня тогда смутило. Нужно опять смотреть исходники. Но скажу на примере последних 3х проектов: заказчики просили создавать такой уровень абстракции, чтобы тесты могли писать люди без особых знаний программирования. Обращения по типу $(locator).method() в такой ситуации будут слишком сложными для восприятия. Даже при условии вынесения этого кода на уровень PageObjects. Внедрение дополнительного уровня абстрации может отразиться и на самих локаторах (опять-таки для улучшения читабельности и кастомных решений). Поддерживает ли ваш фреймворк на текущий момент возможность обработки кастомных локаторов? Смогу ли я переопределить существующие обработчики?

Из того, что запомнилось, есть несколько пожеланий: 1) хотелось бы видеть во фреймворке не статический драйвер; 2) было бы неплохо реализовать SoftAsserts механизм; 3) не помешал бы какой-то интерфейс, который позволит мне самому выбирать, когда убивать драйвер. По-моему, на тот момент убиение драйвера было заключено под JUnit'овский @After. Что если я использую testng и хочу создавать / убивать драйвер после каждого метода? 4) если не ошибаюсь, метод для снятия скринов был заточен сугубо под обычный WebDriver, для RemoteWebDriver нужно дополнительное преобразование с использованием Augmenter.

Возможно все это уже добавлено / исправлено в последних версиях. Повторюсь, давно не смотрел код. Но в целом, впечатления остались неплохие.

Спасибо за много интересных вопросов.

Давайте по порядку.

1. Да, можно делать сколько угодно уровней абстракций. Фокус в том, что Selenide не накладывает никаких ограничений: можно сделать и PageObject, и StepObject, и наворотить ещё каких угодно слоёв, а можно обойтись и без них - как душа пожелает. Я лично склоняюсь к тому, что уровни, которые вас заставляет создавать, например, Thucidides, скорее искуственные, и они больше мешают, чем помогают. Но если действительно надо, то технически ничто не мешает.

2. Не уверен, что такое кастомные локаторы, но думаю, что поддерживает. Никто же не мешает переопределить класс By. Это справедливо и для простого Selenium.

3. Не знаю, что такое "существующие обработчики" и что означает их "переопределить", но мы старались делать Selenide по такой идеологии, что переопределить можно всё.

 

По пожеланиям:

1. Что такое "нестатический" драйвер? А какой тогда? Сейчас есть возможность сказать Selenide использовать ваш объект WebDriver - это оно?

WebDriverRunner.setWebDriver(myDriver)

2. SoftAsserts - это когда тест не падает, а продолжает идти дальше, и только в конце показывает ошибку? Убеждён, что это в принципе неправильно. Если это кому-то понадобилось, то проблема глубже, и решать её надо другими методами.

3. Есть такой метод для JUnit: https://github.com/codeborne/selenide/blob/master/src/main/java/com/codeborne/selenide/junit/BrowserStrategy.java

Но теперь я стал думать, что он не нужен. Ведь вы можете всегда написать свой метод @After, в котором вызвать WebDriverRunner.close()

4. Да, снятие скриншотов реализовано только для обычного WebDriver. Я просто никогда не использовал RemoteWebDriver  и не знал, что там скриншоты надо делать как-то по-другому. Скиньте пример, сделаем по-быстрому. 

 

 

  1. Нестатический драйвер - тот, у которого отсутствует модификатор static. И не важно при этом, каким я его создам. Главное то, что после вызова:
public static void setWebDriver(WebDriver webDriver) {
    webdriver = webDriver;
}

Он станет статическим, а это значит, что у меня будут связаны руки в вопросах масштабирования. Эксперимента ради, попробуйте запустить один и тот же тест на разных браузерах в параллельном режиме. Как не крути, но масштабируемость - один из ключевых профитов автоматизации.

  1. SoftAsserts.

В некоторых компаниях, работающих над серьезными проектами (по типу медицинских - с жесткой формализацией) существует такая техника написания тест кейсов, в которой все степы делятся на инстракшенал и верифай. При этом, каждый верифай степ проверяет функционал на соответствие задокументированному требованию. Так вот представьте тест кейс из 200+ степов, в котором 70% из них - верифай степы. Разбивать 1 тест кейс на 140 (по 1 верифаю в каждом) является нецелесообразным, уже не говоря о тонне ненужных прекондишенов в случае фейла предыдущего теста.

К тому же, механизм SoftAssert не так давно встроили в TestNG. Значит спрос на подобный функционал таки имеется среди автоматизаторов всего мира.

  1. Screen capture for RWD:
File scrFile;
 
if (driver.getClass().equals(RemoteWebDriver.class)) {
    scrFile = ((TakesScreenshot) new Augmenter().augment(driver)).getScreenshotAs(OutputType.FILE);
} else {
    scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
}

1. Про нестатичкский драйвер я думал, да. Масштабируемость, допустим, нужна, если тестов очень много.

Но достичь её можно гораздо проще. Можно же запустить в одном процессе "ant -Dbrowser=firefox", в другом "ant -Dbrowser=chrome" и в третьем "ant -Dbrowser=ie".

Та же самая масштабируемость достигнута? Достигнута. Легко? Легко. Нужно ли что-то ещё изобретать?

Подскажите! Если окажется, что нужно, сделаем в два счёта.

2. Разбивать кейс на 400, конечно, не надо. Пусть будет в одном тесте 400 проверок. Но ведь если хотя бы одна из них упадёт, то и весь тест должен упасть, верно? И зачем тогда гнать его до конца и делать остальные 399 проверок? Только время тратить. Пусть уж он побыстрее упадёт и мы побыстрее его исправим.

Мы сегодня обсуждали этот вопрос с коллегами и пришли к выводу, что SoftAssert может быть полезен только для того, чтобы узнать сразу все 15 проверок, которые зафэйлились, и сразу все 15 исправить. Вы это имели в виду? В таком случае, да, это вроде бы полезно. 

Но тут у меня встаёт техническая трудность: такую штуку можно реализовать только под какие-то конкретные фреймворки. Понимаете, сам по себе Selenide универсален, его можно использовать и с JUnit, и с TestNG, и с ScalaTest, и с Groovy и с чем угодно. Мы можем сделать SoftAssert, скажем, для JUnit и TestNG, но остальные фреймворки останутся непокрытыми.

Пожалуй, можно сделать. Я создал таск на гитхабе. Спасибо за предложение.

3. Спасибо, создал таск. Хотя мне до сих пор непонятно, нафига нужен RemoteWebDriver. По той же причине, что п. 1.

 

1) А если мне нужно стартануть 30 конфигураций (различные версии ОС / браузеров)? Запускать 30 таргетов как независимые процессы в параллельном режиме?

От статики можно избавиться путем наследования тестом WebDriverRunner и иницилизации драйвера в каком-нибудь из аннотированных @Before методе. При этом, убиение драйвера будет под одной из аннотаций @After.

Кстати, у вас в методе closeWebDriver лучше использовать driver.quit() вместо driver.close(), т.к. close() лишь закрывает браузер, а quit(), помимо браузера, убивает и сам драйвер. Это легко отследить в таск менеджере: при запуске ie или chrome, вызов метода close() оставит висеть драйвер в процессах по завершению теста.

2) В том то и дело, что в случае 400 проверок общий экзекьюшен тайм будет слишком долгий, и проще сразу увидеть все фейлы, нежели запускать тест после каждого индивидуального фикса.

Полной универсальности порой чисто физически невозможно достигнуть в силу каких-либо ограничений.

3) RemoteWebDriver изначально затачивался под грид. Возможно для вас и проще поднять Jenkins c кучей агентов, но... Во-первых, у CI несколько иное предназначение и использовать его целесообразно только по назначению / в комплексе, а не сугубо ради одной фичи. Во-вторых, Jenkins настроить далеко не проще, нежели запустить простой батник. Ну и последнее, есть компании / проекты, на которых дополнительная тулзовина должна пройти серьезную валидацию, прежде чем ее допустят к использованию (даже не смотря на фришность), посему заказчики выбирают вариант наименьшего сопротивления, т.е. one-click solution, аля запуска через cmd без установки каких-либо дополнительных тулов.

 

1. Конечно, это же явно проще!
Если на то пошло, никто ведь не собирается это делать на своём компьютере? Эти 30 конфигураций вы ведь собираетесь запускать на Jenins?
Ну вот и создайте в нём 30 тасков, каждый запускает полный комплект тестов со своей конфигурацией. 
 
Может, я чего не понимаю, но по-моему, это явно проще и логичнее, чем что-то подобное имплементировать внутри тестов. 
 
У CI как раз такое предназначение и есть: делать кучу однообразной работы с разными конфигурациями, на разных опсистемах и т.д. Jenkins c кучей агентов - это очень даже по назначению.
 
(Насчёт close vs quite посмотрю, спасибо за подсказку.)
 
3. Хм.. но ведь грид - это тоже тулзовина, не? Её ведь тоже нужно поднять? 
Читаем описание Грид: Selenium Grid распределяет запуск ваших тестов на многих машинах. Значит, его тоже нужно установить на всех этих машинах. Как же возможно это поднять одним батником?..

1) При условии нестатического драйвера у меня будет единственный процесс + 1 xml с нужной конфигурацией. Внутри тестов ничего меняться не будет, кроме собственно самого наследования ранэра. И в Jenkins нужно будет создать всего 1 джобу, а не 30.

3) Грид - сложно назвать тулзовиной. Мы просто запускаем все тот же selenium-standalone джар с доп. параметрами в батнике. В зависимости от параметров, эти батники будут величаться хабами / нодами. Но в душе - это одна и та же либа. Технически, ничего кроме джавы, ставить не нужно. Лишь переписать и запустить батники с джаркой.

Давайте продолжим дискуссию в соответствующей теме http://automated-testing.info/forum/selenide-lakonichnye-ui-testy-na-java

Эта тема прилеплена. Она будет всегда отображаться первой в списке тем своей категории, пока не будет отлеплена модератором, или сброшена вниз, когда каждый пользователь нажмет кнопку «Отлепить»

Недавно ребята из Википедии опубликовали свой фреймворк:

https://github.com/wikimedia/qa-browsertests

Написан на Ruby с использованием Cucumber. Есть PageObjects, StepObjects, и вообще там всё дотстаочно красиво организвано.

2 лайка

да, кстати я тоже на него смотрел
код выглядит хорошо и красиво
мне как-то ruby в последнее время начинает нравиться для написания тестов, выглядят, как бы это сказать лаконично

1 лайк

http://bugscatcher.net/buterbrod

ButerbroD – Framework for automation functional testing of web-applications using Selenium RC (C#) as web-driver. Implemented DSL, Elements and Page Object patterns. Created by the Easy Projects team

1 лайк

Недавно открыл для себя репозиторий Мозиллы и их код для автоматизации веб приложений с помощью Python+Webdriver

Вот, например, шаблоны для старта своей автоматизации: GitHub - mozilla/mozwebqa-test-templates: Template files for creating new test files

А здесь пример реализации реального приложения: GitHub - mozilla/remo-tests: Tests for the Mozilla Reps website.

2 лайка

Они еще отдельно вынесли проект обертки для py.test GitHub - davehunt/pytest-mozwebqa: Mozilla WebQA plugin for py.test.

Тоже интересно посмотреть, если хотите делать что-то похожее.

И еще хотел бы добавить отличный фреймворк на Python для WebDriver - PySaunder

Saunter is an opinionated automation framework for use with the
Selenium RC and WebDriver libraries. It is designed to remove a lot of
the overhead and cruft that hinders teams when they first start out
with automation. For documentation around Saunter see
http://element34.ca/products/saunter/pysaunter.

Примеры тесты конечного выглядят так вот:

Ребят,

а по тестированию REST API кто то встречал привлекательные реализации?
Особенно Python случаи интересуют…

Там конечно, как бы то и не с чем заморачиваться, но все же… :slight_smile:

1 лайк

реализация PageObjects + PageFactory + LoadableComponent (для виджетов/комплексных елементов на странице которые сами себя открывают если нужно) для Ruby + Capybara: GitHub - yashaka/widgeon: Yet another 'page objects for Capybara' gem with ability to create custom loadable elements akka 'widgets'

Пока поддерживается только версии капибары соответствующие руби 1.8.7. Будет исправлено в ближайшем будущем.

1 лайк

Я думаю сюда стоит добавить также эту ссылку на другие репозитории

Там ассерты встроенные есть, и делают скриншоты в случае ошибки,
$("#insuranceDetailsHeader").shouldHas(text(“Страховые полисы”));
$$("#paymentScheduleTable tr").shouldHasSize(7); //тут точно не помню, синтаксис может отличаться

1 лайк