SWD.Starter: Быстрый старт автоматизации тестирования UI на C# + Selenium WebDriver + PageObjects

Привет @mihaylenkov

На первый взгляд, добавление Protractor for .NET не должно составить проблем.

Насколько я понял, NgWebDriver – это обвертка над обычным WebDriver, т.е. вначале вам нужно создать обычный объект WebDriver, а затем обвернуть его в NgWebDriver. типа, как в примере:

NgWebDriver ngDriver = new NgWebDriver(driver);

С этим не должно возникнуть проблем.
В неймспейсе Swd.Core.WebDriver
есть класс WebDriverRunner у которого есть метод Run, который создает новый объект WebDriver. Можете сделать обвертку там и вернуть экземпляр NgWebDriver.

NgWebDriver реализует интерфейс IWebDriver, как и другие стандартные интерфейсы, и за это ему плюс в карму, так что, по большей части, код должен быть совместимым. Но, гарантировать не могу, не проверял.

С другой стороны, я думаю, вы вполне можете обойтись, XPath или CSS локаторами, без использования отдельного фреймворка. Просто в случае с Angular, уже более важными становятся эти ng-* атрибуты.

Я так же записал видео, которое получилось не очень веселым и удачным, но иллюстрирует работу с Angular, используя XPath и CSS (первые 6 минут)

Удачи

Дима, спасибо за быстрый ответ.
Да, согласен, пока XPath везде работает как нужно, пока использую By.
Я так подозреваю, что возникнет вопрос с ожиданиям пока Ангуляр отрендерит и плучит все ответы от сервера. Если я не ошибаюсь, то в Protractor используется WaitForAngular. ( Search · WaitForAngular · GitHub ).
На правильном ли я пути.

Вроде бы на правильном :wink:
Единственное, чтобы я порекомендовал, это в случае использования Protractor, замерить время прохода тестов с Protractor и без него.

По сути, этот WaitForAngular выполняется при каждом действии с элементом, а это удваивает количество вызовов к WebDriver. Это не так критично при локальном запуске (браузер и код на локальной машине), но может ощутимо сказаться на времени работы через RemoteDriver (браузер и код на разных машинах).

Ну, и собственно, я бы Protractor добавил в том случае, когда бы столкнулся с реальной проблемой, которую он решает, например, если тратится много усилий и кода для ожидания элементов.

НА этапе автоматизации смоук тестов Wait.UntilVisible(element, TimeSpan.FromSeconds(20)); Заменяет Протрактор. Спасибо!

Задал вам еще вопрос (и удалил), поищу его пока тут

1 лайк

Дима,

  1. Если есть такая ситуация. Чтобы добраться до страницы добавления N, нужно залогиниться, перейти на одну страницу, если объект 1 есть, то переходим глубже (иначе создаем его), дальше есть ли объект 2, то переходим глубже (иначе создаем его), на странице 3 клик и мы на нужной странице с формой. Какие есть рациональные варианты? Подготовить базу данных? - Тут есть трудности. Может Создавать, но с помощью http запросов? Хм. До использования вашего фреймворка, не заморачивался и создавал все объекты каждый тест и потом их удалял (это долго). Когда начал использовать ваш фреймворк, то решил придерживаться принципов, пока тех которые нахожу и понимаю ))) в ваших сообщениях. И есть огромное желание делать как нужно… Как вы порекомендуете это сделать? При этом интерфейс Метро стайл. То есть на странице отображаются MainBlade+Blade1+Blade2+Blade3+BladeN
  2. Какие вы порекомендуете начать автоматизировать тесты после смоук (VerifyElementVisible). Конечное хочется сразу к длинным сценариям, но возможно есть что-то более рациональное… Так-как наверное следующий этап это изучение пласта API / http - запросов и и написания тестов. (Unit тесты программисты не пишут).

Привет Вова,

1. На самом деле, для работы с данными в авто-тестах, какой-то одной единственной стратегии нет, это означает, что вы можете выбрать любую.
Все зависит от того, какую долю ответственности вы можете на себя взять :slight_smile: Вот, например, если вы создаете все через UI, то не берете на себя ответственность за правильное создание данных (сущностей) в базе данных: если у вас получилось добавить некорректные данные через UI приложения – значит проблема в приложении… зато тесты будут идти долго.

Использование HTTP запросов может быть золотой серединой. Если мы говорим о слое API (RESTful API?), то можно использовать его – опять же, если что-то пойдет не так – то возможно в самом приложении и в слое API живет баг. Через API приложения, вы можете проверить, существуют ли нужные вам данные, и, при необходимости, создать их.

Ну, и наконец, прямая работа с базой данных, а особенно создание и модификация (чтение – самая безвредная операция), предполагают что вы берете на свой код полную ответственность. Если что-то пойдет не так – то в 90% будут виноваты тесты :smile: Зато это может быть самый быстрый способ залить данные.

Выбор стратегии тут зависит от полноты понимания работы приложения и взаимодействия с разработчиками.

Я сейчас стараюсь придерживаться принципа юнит-тестов:

  1. ACT – подготовить все необходимое для теста, в том числе данные
  2. ARRANGE – выполнить необходимые действия для теста
  3. ASSERT – проверки

Тем не менее, часто создаю новые сущности в приложении, которые нужны для перехода на следующий шаг внутри PageObject, с рандомными именами (или датой и временем в имени), при этом их не удаляя после теста.
Такой мусор в базе данных, помогает искать новые случайные баги. После чего, базу данных можно раз в месяц перезалить из чистой копии. В общем, тут очень много вариантов, и выбор стратегии работы с данными – за вами

2 Отличная идея по поводу API / HTTP тестов. В этом случае, на уровне UI, вам будет достаточно простого набора смоук тестов и небольшого набора end to end сценариев , а остальную логику работы приложения, вы можете покрыть интеграционными тестами через API приложения.

2 лайка

Михаил, добрый день!

Во-первых, сочувствую по поводу отсутствия Unit тестов.

Во-вторых, хочу подтвердить, что интеграционные тесты на API очень полезны:

  • появится уверенность, что на front-end приходят корректные данные - остается убедиться, что UI корректно их отдает;
  • выполняются в разы быстрее UI тестов;
  • стабильнее, чем UI тесты - так как меньше уровней абстракций/зависимостей;

В Visual Studio есть отличный инструмент для тестирования API - Web Perfomance Test. Или же можно писать непосредственно на C# HTTP запросы и с помощью try/catch ловить все 2xx, 3xx, 4xx, 5xx ответы сервера.

VisualStudio 2015, Webdriver 2.48, Chrome Версия 46.0.2490.80 m , Angular JS
Использую [SWD.Starter] и SWD Page Recorder

Вопрос
В SWD Page Recorder Локатор подсвечивается , но когда запускаю тест с VisualStudio валится ошибка

Test Name: S_SectionPage_VerifyExpectedElements
Test FullName: Demo.TestProject.Smoke.Smoke_test_for_each_pageobject.S_SectionPage_VerifyExpectedElements
Test Source: C:\Projects\Admixer QA\SWD.StarterKit\Demo.TestProject\Smoke\Smoke_test_for_each_pageobject.cs : line 100
Test Outcome: Failed
Test Duration: 0:03:22,4615716

Result StackTrace:
в Swd.Core.WebDriver.Wait.UntilVisible(IWebElement element, TimeSpan timeOut) в C:\Projects\Admixer QA\SWD.StarterKit\SWD.Core\WebDriver\Wait.cs:строка 38
в Demo.TestModel.PageDeclarations.SectionPage.Invoke() в C:\Projects\Admixer QA\SWD.StarterKit\Demo.TestModel\PageDeclarations\Sites\SectionPage.cs:строка 43
в Demo.TestProject.Smoke.Smoke_test_for_each_pageobject.PageTest(MyPageBase page) в C:\Projects\Admixer QA\SWD.StarterKit\Demo.TestProject\Smoke\Smoke_test_for_each_pageobject.cs:строка 23
в Demo.TestProject.Smoke.Smoke_test_for_each_pageobject.S_SectionPage_VerifyExpectedElements() в C:\Projects\Admixer QA\SWD.StarterKit\Demo.TestProject\Smoke\Smoke_test_for_each_pageobject.cs:строка 101
Result Message:
Test method Demo.TestProject.Smoke.Smoke_test_for_each_pageobject.S_SectionPage_VerifyExpectedElements threw exception:
System.TimeoutException: Wait.UntilVisible: Element was not displayed after 20000 Milliseconds
Error Message:
Could not find element by: By.CssSelector: button[ui-sref=".Zone({{zType:1,zPos:0, zoneId:null}})"]

Пользуюсь Xpath , Тут в примере CSS - эксперименты. Прописывал разные Xpath, в Рекордере все ок , В проекте Ошибка.

Содержимое тега

ng-hide= “user.subType==‘Network’&&model.NetTypes.indexOf(2)>-1&&model.NetTypes.length==1&&model.NetTypes.length>0||user.subType==‘SSPPublisher’”
ui-sref= “.Zone({zType:0,zPos:gridShit[row][col].Pos, zoneId:null})”
class= “add_entity pointer”
style= “null”

код

public override void Invoke()
        {
            if (!IsDisplayed())
            {
                var _SitePage = new SitePage();
                _SitePage.Invoke();
                _SitePage.GoToFirstSectionPage();
                Wait.UntilVisible(btnAddVideoAdUnit, TimeSpan.FromSeconds(20));
            }
        }

        public override bool IsDisplayed()
        {
            return btnAddVideoAdUnit.IsDisplayedSafe();
        }
        #endregion

        public override void VerifyExpectedElementsAreDisplayed()
        {
            VerifyElementVisible("btnAddFloatingAdUnit", btnAddFloatingAdUnit);
            VerifyElementVisible("btnAddVideoAdUnit", btnAddVideoAdUnit);
            VerifyElementVisible("btnAddInPageTopLeft", btnAddInPageTopLeft);
        }

Куда копать? Плиз Хэлп.

Ошибка

System.TimeoutException: Wait.UntilVisible: Element was not displayed after 20000 Milliseconds

говорит о том, что элемент не отобразился в момент проверки.

Выполните необходимые действия для появления этого елемента перед проверкой VerifyElementVisible() либо удалите VerifyElementVisible с этим елементом

Да, но Screenshot by Lightshot это вкладка браузера, открытая из теста. Элемент есть.

@mihaylenkov вставьте пожалуйста ошибку с вашим самым свежим локатором. В вопросе вы говорите что експериментировали с CSS но используете Xpath…

Свойство елемента, которое у вас в локаторе елемента в этих Ангулярах может динамически менятся при наведении мышки, например.

Имхо, фигурных скобок тут многовато.

1 лайк

@vmaximv Да, как раз они и были причиной. Почему-то дублировались фигурные скобки, когда генерился код в Page Recorder . Правлю руками. Спасибо! Ура

Спасибо @vmaximv за наблюдательность и @mihaylenkov за найденную ошибку.

@dzhariy Подскажите пожалуйста, а SWD.Starter kit не позволяет использовать protract и javascript для написания тестов? Поставили задачу сделать часть тестов именно с таким набором инструментов. Причем сижу сама под windows (если это имеет значение).

@Tatyana_Durova нет, если нужно писать на JavaScript (вместе с NodeJS) то лучше использовать Protractor – это полноценный фреймворк. Я так понимаю, у заказчика тестов есть причина использовать JavaScript для тестов?

Да, заказчик тестов - по сути разработчик, который пока сам не может начать создавать юнит тесты, тк везде используется объект windows. Чтобы переписать javascriptcode он настаивает на создании функциональных тестов, написанных на javascript, которые и он бы мог дописывать паралельно со мной. Запускать он хочет их на своем локальном окрежнии до коммитов куда либо (мне эта идея кажется сомнительной).

Поставила protractor, а можно на нем создавать проекты в VS2013 как понимаю? К Webstorm не хочется привыкать, да и лицензия там нужна отдельная… Создала пока два файла в node++ spec.js и conf.js, запускаю из cmd в инстансе selenium server… Как можно настроть видимость тестов в неком test explorer? В идеале в VS2013… Или пытаться переубедить своего фронтендщика?

JavaScript тесты из VS можно запускать при помощи Chutzpah Test Adapter for the Test Explorer я пробовал что он работает, но сам предпочитаю командную строку и консоль.

Идея с локальным запуском до коммита не такая уже сомнительная, но, я бы предложил настроить CI сервер, типа Jenkins или Teamcity, они умеют работать с Jasmine (тестовый раннер). Это в принципе, хорошо, когда разработчик хочет работать над тестами, например, в таком случае, попросить добавить id к элементу будет проще.

В общем писать лучше начать на protractor(jasmine2 сервер), но настроить таки сервер и запускать через него? Меня вообще идея локальных запусков смущает, он просто видимо никогда не работал в проекте с нормальным CI, где были бы стабильные быстро запускаемы тесты. Основная причина почему он хочет локально - высокая скорость разработки и запуска, что ничего никуда мержить не надо и ждать запуска тестов на отдельном агенте.

Я обычно поддерживаю возможность прогона на локальной машине, ну и хотелки у разработчика… ну правильные, в общем :smiley: