Все выпуски  

Очные тренинги Антона Семенченко весна-лето 2019



Software-Testing.Ru - портал тестировщиков  

Новые темы форума тестировщиков


Очные тренинги Антона Семенченко весна-лето 2019
2019-03-12 11:56

QA сообщество COMAQA организует большое турне очных тренингов своего основателя, одного из ведущих тренеров по автоматизации тестирования и тест-менеджменту Антона Семенченко.

 

Тренинги пройдут в Москве, Санкт-Петербурге, Нижнем Новгороде, Алма-Ате и Екатеринбурге.

 

В этих городах Антон проведет три своих самых популярных тренинга:

  • Архитектура автоматизации тестирования
  • Метрики ручного и автоматизированного тестирования, ROI автоматизации
  • Управление командой тестировщиков

Даты проведения тренингов и краткие описания ниже. Подробная программа по ссылкам.

 

Кроме того, возможно проведение тренингов в июле-августе в Минске, Москве, Новосибирске, Казани и Екатеринбурге.  Если вам интересно принять в них участие, пишите по адресу Julia@comaqa.by. Тренинги будут поставлены в расписание, если будет получено достаточное количество предварительных заявок.

 

Возможно также проведение корпоративных тренингов на территории заказчика.

 

Архитектура автоматизации тестирования

 

На тренинге вы получите ответы на наиболее актуальные вопросы построения эффективной, легко адаптируемой, минимизирующей усилия / траты архитектуры решений автоматизации тестирования UI.

 

Санкт-Петербург, 30 марта

Нижний Новгород, 6 апреля

Алма-Ата, 13 апреля

Екатеринбург, 20 апреля

Санкт-Петербург, 16 мая

Москва, 15 июня

 

Метрики ручного и автоматизированного тестирования, ROI автоматизации

 

Вы научитесь выбирать и эффективно использовать метрики ручного и автоматизированного тестирования, внедрять их на проекте, сможете с нуля разработать ROI калькулятор для UI, Backend и Unit тестирования, адаптировать его под нужды компании / заказчика, эффективно использовать на всех этапах работы над проектом.

 

Санкт-Петербург, 31 марта

Нижний Новгород, 7 апреля

Алма-Ата, 14 апреля

Екатеринбург, 21 апреля

Санкт-Петербург, 19 мая

Москва, 16 июня

 

Управление командой тестировщиков

 

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

 

Санкт-Петербург, 29 марта

Нижний Новгород, 5 апреля

Санкт-Петербург, 30 мая

Москва, 14 июня

 

Спешите зарегистрироваться!!! Количество мест ограничено.



Удаление coockie
2019-03-12 12:53

Всем привет! Можно ли в Selenium IDE (версия 3.8.5) удалить coockie пользователей?



Целесообразность WebDriverWait
2019-03-12 18:00
Недавно посмотрел видео Алексея "Заморочки в Selenium WebDriver". Я ждал более технических моментов, по типу staleness. Один из таких хотелось бы обсудить. А именно, есть ли реальная необходимость в классе WebDriverWait и его основном методе Until. 
 
Все последующие размышления основаны на исходном коде C#.
 
При создании экземпляра WebDriverWait в конструктор передается экземпляр драйвера, который сохранятеся во внутреннем поле input. Метод Until предполагает делегат, входным параметром которого должен быть IWebDriver, экземпляром которого и является input.
 
 
Я задаюсь вопросом зачем такие сложности, нужен ли вообще WebDriverWait и можно ли от него отказаться?
 
Давайте посмотрим на исходный код метода Until. Костяк его логики - это бесконечный цикл с двумя условиями выхода из него: наступление нужного события или timeout. Дополнительными "плюшками" являются игнорирование предопределенных exceptions и возврат объекта, если в качестве TResult выступает не bool (об этом чуть позже).
 
Первый ограничение, которое я вижу - нам всегда требуется именно экземпляр IWebDriver, хотя внутри метода Until (если быть точным, то в качестве входного параметра для condition) мы могли бы вполне обойтись ISearchContext. Ведь в большинстве случаев мы ожидаем какого-то элемента или изменения его свойства и используем FindElement(s) для его поиска.
 
Я рискну заявить, что использование ISearchContext было бы даже более логичным, ведь клиентский код (класс) - это не только page object, который в поиске дочерних элементов отталкивается от корня страницы. Иногда это класс, описывающий некий составной элемент, у которого корнем является другой элемент страницы, а не сама страница. В качестве такого примера можно привести SelectElement, который принимает в конструктор ссылку на родительский IWebElement.
 
Вернемся к вопросу инициализации WebDriverWait. Это действие требует экземпляр драйвера. Т.е. нам всегда, так или иначе, в клиентский код необходимо извне пробрасывать экземпляр IWebDriver, даже если это класс некоего составного элемента (пример про SelectElement), который уже принимает "родителя". С моей точки зрения, это излишне.
 
Конечно, мы можем создать класс по аналогии 
SearchContextWait : DefaultWait<ISearchContext>
Но не будем торопиться. Он нам не понадобится.
 
Давайте посмотрим, как используется передаваемый в condition экземпляр драйвера. Обычно это выглядит как-то так:
 
        var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
        wait.Until( d => d.FindElements(By.XPath("locator")).Count > 0 );
Возникает вопрос, зачем внутри condition необходима "локальная" версия драйвера, если он всегда доступен из клиентского кода? Более того, это тот же самый экземпляр, переданный ранее через конструктор. Т.е. код может выглядет как-то так:
 
        var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
        wait.Until( d => Driver.FindElements(By.XPath("locator")).Count > 0 );
Даже Simon Stewart в своем выступлении использует такой подход.
 
QhMNrkA.jpg
 
Он не пишет "d -> d.", а пишет "d -> driver.", т.е. переданный внутрь метода экземпляр драйвера попросту игнорируется. Но передавать его необходимо, ибо этого требует сигнатура метода!
 
Итак, зачем же передавать драйвер во внутрь condition метода? Возможно, чтобы изолировать поиск внутри этого метода, как это реализовано в ExpectedConditions? Посмотрите на реализацию метода TextToBePresentInElement. Или VisibilityOfAllElementsLocatedBy. Или TextToBePresentInElementValue. В них переданный драйвер даже не используется!
 
 
Итак, первая мысль - нам не нужен метод Until с параметром-делегатом, который принимает драйвер.
 
Давайте теперь разберемся, нужено ли методу Until возвращаемое значение? Если в качестве TResult выступает bool, то нет, не нужно. Ведь в случае успеха вы получите true, а в случае неудачи вы получите TimeoutException. В чем информативность такого поведения?
 
А если в качестве TResult выступает object? Предположим, такую конструкцию:
 
var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
var element = wait.Until(d => d.FindElement(xpath));
Т.е. мы не только ждем появления элемента, а и используем его (если дождались), тем самым убирая одно лишнее обращение к DOM. OK.
 
Давайте посмотрим пристальнее на эти три строчки кода. Внутри реализации метода Until это сводиться к некоему подобию (условный код)
 
try { FindElement } catch (NoSuchElementException) {}
Поскольку генерация exception довольно дорогостоящее событие, то я бы предпочел его избегать, особоенно в тех местах, где это не представляет труда. Мы можем переписать код следующим образом:
 
var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
var elements = wait.Until(d => d.FindElements(xpath));
Т.е. мы используем FindElements, который не генерирует исключение. Подождите, а будет ли эта конструкция ждать появления элементов? НЕТ! Потому что, если посмотреть в исходный код, выполнение бесконечного цикла завершает сразу, как только condition возвращает не null. А FindElements в случае неудачи возвращает пустую колекцию, но никак не null. Т.е. для списка элементов использование Until не имеет смысла.
 
Вторая мысль - возвращаемое значение метода Until не используется в большинстве случаев.
 
Передаваемое значение излишне, возвращаемое значение не используется. В чем же полезность Until? Только лишь в цикле и периодичности вызова condition метода? Этот подход уже реализован в C# в методе SpinWait.SpinUntil. Единственное его отличие, что он не генерирует исключение по timeout. Это можно исправить следующим образом:
 
        public void Wait(Func<bool> condition, TimeSpan timeout)
        {
            var waited = SpinWait.SpinUntil(condition, timeout);
            if (!waited)
            {
                throw new TimeoutException();
            }
        }
Т.е. эти несколько строк кода в большистве случаев заменяют логику работы WebDriverWait. Стоит ли усилия результата?
 
 


Автотест в katalon recorder
2019-03-12 18:54
Подскажите пожалуйста, пишу первый автотест и столкнулся с проблемой.
Пробовал нагуглить, но результата ноль.  
 
Тесты провожу в katalon recorder для дальнейшего экспорта кода для python
Записал действия пользователя, но в момент запуска теста он прерывается на выпадающих списках, одно поле не заполняется, предыдущие 2 заполнились корректно, действие отрабатывает без ошибки.
Т.к. поле не заполнено перейти к следующей части теста не получается и я получаю ошибку: "[errorImplicit Wait timed out after 10000ms
[errorElement id=Element_id not found"
(логика формы такая, ввожу в поле город "моск" и выпадающем окне появляются варианты городов которые нужно выбрать. Как я понимаю реализовано это при помощи ajax.)
 
В какую сторону копать для решения этой проблемы, подскажите пожалуйста.


Postaman и тестирование *json ответа
2019-03-13 00:24

всем привет, в общем мучаюсь второй день с попытками сделать автотесты api более универсальными.

В общем есть пример json ответа

{
    "channels": [
        {
            "display_alias": "pervijkanal",
            "sharing": true,
            "is_radio": false,
            "title": "Pervijkanal HD",
            "cid": "pervijkanal",
            "group_index": 0,
            "recording": true,
            "qualities": [
                {
                    "logo_black_84": "/images/channels/logos/2a2a4aee64bbd6f7f817/black/84x48.png",
                    "title": "Pervijkanal HD",
                    "stream_types": [
                        "hds",
                        "hls",
                        "smooth_playready",
                        "dash",
                        "dash_widevine",
                        "dash_playready",
                        "hls5_fairplay",
                        "hls7_fairplay",
                        "hls5",
                        "hls7"
                    ],
                    "level": "hd",
                    "logo_white_42": "/images/channels/logos/2a2a4aee64bbd6f7f817/white/42x24.png",
                    "logo_token": "2a2a4aee64bbd6f7f817",
                    "logo_black_42": "/images/channels/logos/2a2a4aee64bbd6f7f817/black/42x24.png",
                    "logo_white_84": "/images/channels/logos/2a2a4aee64bbd6f7f817/white/84x48.png",
                    "availability": "available"
                }
            ],
            "recommendations": true,
            "selective_recall_seconds": 1,
            "id": "pervijkanal",
            "aliases": [
                "Pervijkanal"
            ]
        },
        {
            "display_alias": "vtorojkanal",
            "sharing": true,
            "is_radio": false,
            "title": "Vtorojkanal HD",
            "cid": "vtorojkanal",
            "group_index": 0,
            "recording": true,
            "qualities": [
                {
                    "logo_black_84": "/images/channels/logos/42a29350387ee5fda8fe/black/84x48.png",
                    "title": "Vtorojkanal HD",
                    "stream_types": [
                        "hds",
                        "hls",
                        "smooth_playready",
                        "dash",
                        "dash_widevine",
                        "dash_playready",
                        "hls5_fairplay",
                        "hls7_fairplay",
                        "hls5",
                        "hls7"
                    ],
                    "level": "hd",
                    "logo_white_42": "/images/channels/logos/42a29350387ee5fda8fe/white/42x24.png",
                    "logo_token": "42a29350387ee5fda8fe",
                    "logo_black_42": "/images/channels/logos/42a29350387ee5fda8fe/black/42x24.png",
                    "logo_white_84": "/images/channels/logos/42a29350387ee5fda8fe/white/84x48.png",
                    "availability": "available"
                }
            ],
            "recommendations": true,
            "selective_recall_seconds": 1,
            "id": "vtorojkanal"
        }       
    ]
}

В этом ответе мне необходимо проверить display_alias

для каждого канала, их больше сотни.

 

Пытался сделать for, но получается ерунда.

Проверял путем 

tests["Pervijkanal.Display_alias"] = data.channels[0].display_alias === "pervijkanal"; 

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

 

Может быть кто-то подскажет более элегантное решение?



© 2010 | Software-Testing.Ru


В избранное