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

Интересует в основном пункт 1 то есть перформенс пользовательского интерфейса. Остальное я могу видеть на своих запусках лоад тестов. Но если вдруг у меня страница начала грузиться у клиента в 2 раза дольше то у меня фактически нет никакой индикации, кроме слов пользователя.

Должен сказать, что на сколько я знаю (возможно не владею всей информацией) некоторого одного хорошего лёгкого и бесплатного решения данной проблемы нет.

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

Очень много чего зависит от комплекса взаимодействия клиента и сервера, и от архитектуры приложения. Например, страница может грузится в 2 раза дольше, потому что приложение может застрять на каком-нибудь аякс запросе к серверу, если активно используется Ajax.

В этом примере Starter, есть метод WaitForOpen()

        internal void WaitForOpen()
        {
            lnkDeactivateMyAccount.WaitUntilVisible(TimeSpan.FromSeconds(10));
        }

Его можно легко параметризировать, добавив параметр таймаута:

        internal void WaitForOpen(int timeOutSeconds)
        {
            lnkDeactivateMyAccount.WaitUntilVisible(TimeSpan.FromSeconds(timeOutSeconds));
        }

И вызывать такой метод для каждой страницы, указывая время ожидания загрузки в секундах. Так, можно будет узнать если вдруг загрузка страницы превышает ожидаемое время загрузки.

А может быть лучше в этом методе, в цикле while дергать isDisaplyed пока не вернётся true или не будет привешено время ожидания общем… это как идея.

Получение более детальной информации о рендеринге – это более сложное занятие.

В свежих версиях популярных браузеров есть профайлеры, но доступиться к API не просто.

В зависимости от выбранного JavaScript фреймворка, можно получить какую-то часть информации. Вот пример EmberJS:
How to instrument and measure page rendering time?

В некоторых случаях, в код приложения необходимо добавить дополнительные библиотеки. Одна из таких, известных:

boomerang, на основе которого, можно сделать свой инструмент измерения перформанса. Но, тут нужна помощь и содействие разработчиков приложения. Иногда ее получить легко… иногда нет.

Ссылки по теме:

Ну, и… хочу поделится видео, которое тестирует «отзывчивость» интерфейса Todo MVC для разных реализаций.

Это видео показывает, что реализации BackboneJS и KnockoutJS работают примерно в два раза быстрее чем AngularJS при добавлении новых элементов… Какие выводы можно тут сделать?
Ну… не знаю пока :smiley:

Дима спасибо. Ответ тянет на небольшую статью. Тут одних линков на неделю изучения.
Скорее всего на начальном этапе мне хватит лога. Если что то будет интересное отпишусь.

Удачи! Да, обязательно отпишитесь о своем опыте. Решение такой задачи – не самая травильная работа.

Дмитрий, спасибо вам за ваш фреймворк и рекордер.
Начал (<2мес - это и опыт ОО программирования) автоматизировать тесты (смоук+функционал) используя Selenium + Protractor .NET (Page Object). Вопрос такой, на сколько реально подружить ваш фреймворк с Protractor ом?
Или возможно причесывать свой слюшин исходя из вашего кода/структуры?

Привет @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 (если это имеет значение).