Русский
Русский
English
Статистика
Реклама

Qa

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

16.03.2021 18:09:12 | Автор: admin

Меня зовут Дмитрий Макаренко, я Mobile QA Engineer в Badoo и Bumble: занимаюсь тестированием новой функциональности в наших приложениях вручную и покрытием её автотестами.

За последние два года подход к автоматизации тестирования в нашей компании сильно изменился. Количество людей, активно вовлечённых в разработку тестов, увеличилось с десяти до 40 человек. А любая новая функциональность в приложениях теперь обязательно должна быть покрыта тестами до релиза.

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

В подготовке текста мне помогал мой коллега Виктор Короневич: с этой темой мы вместе выступали на конференции Heisenbug.

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

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

Спойлер

В конце статьи будет ссылка на тестовый проект со всеми практиками.

Практика 4. Верификация изменения состояния элементов

Пожалуй, эта практика одна из самых важных в мобильной автоматизации в принципе, потому что в приложениях очень редко встречаются статические элементы, которые сразу же отображаются на экране и всегда на нём доступны. Чаще мы сталкиваемся с тем, что загрузка элементов занимает какое-то время.

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

Таким образом, прежде чем начать проверять элементы, нам необходимо дождаться их появления на экране. Естественно, эта проблема не нова и существуют стандартные решения. Например, в Selenium это различные типы методов wait, а в Calabash метод wait_for.

Зачем нам свой велосипед, или Почему мы отказались от стандартного решения

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

После того как мы добавили логи и проанализировали их, оказалось, что эти зависания были связаны с реализацией метода wait_for, входящего в состав фреймворка Calabash. wait_for использует метод timeout модуля Ruby Timeout, который реализован на глобальном потоке. А тесты зависали, когда этот метод timeout использовался вложено в других методах: наших и фреймворка Calabash.

Например, рассмотрим прокрутку страницы профиля до кнопки блокировки пользователя.

def scroll_to_block_button  wait_for(timeout: 30) do    ui.scroll_down    ui.wait_until_no_animation    ui.element_displayed?(BLOCK_BUTTON)  endend

Мы видим, что используется метод wait_for. Происходит прокрутка экрана вниз, потом ожидание окончания анимации и проверка отображения кнопки блокировки.

Рассмотрим реализацию метода wait_until_no_animation.

def wait_until_no_animation  wait_for(timeout: 10) do    !ui.any_element_animating?  endend

Метод wait_until_no_animation реализован так же с wait_for. Он ждёт, когда на экране закончится анимация. Получается, что wait_for, вызванный внутри wait_for, вызывает другие методы. Представьте себе, что вызовы wait_for также есть внутри методов Calabash. С увеличением цепочки wait_for внутри wait_for внутри wait_for риск зависания увеличивается. Поэтому мы решили отказаться от использования этого метода и придумать своё решение.рый бы повторял проверку до тех пор, пока не выполнится заданное условие либо пока не истечёт отведённое время. Если проверка не проходит успешно за отведённое время, наш метод должен выбрасывать ошибку.

Сначала мы создали модуль Poll с одним методом for, который повторял стандартный метод wait_for. Со временем собственная реализация позволила нам расширять функциональность модуля по мере того, как у нас появлялась такая необходимость. Мы добавили методы, ожидающие конкретные значения заданных условий. Например, Poll.for_true и Poll.for_false явно ожидают, что исполняемый код вернёт true либо false. В примерах ниже я покажу использование разных методов из модуля Poll.

Также мы добавили разные параметры методов. Рассмотрим подробнее параметр return_on_timeout. Его суть в том, что при использовании этого параметра наш метод Poll.for перестаёт выбрасывать ошибку, даже если заданное условие не выполняется, а просто возвращает результат выполнения проверки.

Предвижу вопросы Как это работает? и Зачем это нужно?. Начнём с первого. Если в методе Poll.for мы будем ждать, пока 2 станет больше, чем 3, то мы всегда будем получать ошибку по тайм-ауту.

Poll.for { 2 > 3 }> WaitError

Но если мы добавим наш параметр return_on_timeout и всё так же будем ждать, пока 2 станет больше, чем 3, то после окончания тайм-аута, 2 всё ещё не станет больше, чем 3, но наш тест не упадёт, а метод Poll.for вернёт результат этой проверки.

Poll.for(return_on_timeout: true) { 2 > 3 }> false

Зачем это нужно? Мы используем параметр return_on_timeout для верификации изменения состояния наших элементов. Но очень важно делать это аккуратно, так как он может скрывать реальные падения тестов. При некорректном использовании тесты будут продолжать выполняться, когда заданные условия не выполняются, в тех местах, где должны были бы выбросить ошибку.

Варианты изменения состояния элементов

А теперь перейдём к самому интересному поговорим о том, как проверять различные изменения состояния и какие изменения состояния вообще существуют. Познакомьтесь с нашим объектом тестирования чёрным квадратом:

Он умеет всего две вещи: появляться на экране и пропадать с экрана.

Первый вариант изменения состояния называется Должен появиться. Он происходит в том случае, когда состояние 1 на экране нет нашего объекта тестирования, а состояние 2 он должен появиться.

Должен появитьсяДолжен появиться

Если он появляется, то проверка проходит успешно.

Второй вариант изменения состояния называется Должен пропасть. Происходит он тогда, когда в состоянии 1 отображается наш объект тестирования, а в состоянии 2 его быть не должно.

 Должен пропасть Должен пропасть

Третий вариант не такой очевидный, как первые два, потому что в нём, по сути, мы проверяем неизменность состояния. Называется он Не должен появиться. Это происходит, когда в состоянии 1 наш объект тестирования не отображается на экране и спустя какое-то время в состоянии 2 он всё ещё не должен появиться.

 Не должен появиться Не должен появиться

Вы, наверное, догадались, какой вариант четвёртый. Он называется Не должен пропасть. Происходит это, когда в состоянии 1 объект отображается на экране, и спустя какое-то время в состоянии 2 он всё ещё находится там.

Не должен пропастьНе должен пропасть

Реализация проверок разных вариантов

Мы зафиксировали все возможные варианты изменения состояния элементов. Как же их проверить? Разобьём реализацию на проверки первых двух вариантов и проверки третьего и четвёртого.

В случае с первыми двумя вариантами всё довольно просто. Для проверки первого нам просто нужно подождать, пока элемент появится, используя наш метод Poll:

# вариант "Должен появиться"Poll.for_true { ui.elements_displayed?(locator) }

Для проверки второго подождать, пока элемент пропадёт:

# вариант "Должен пропасть"Poll.for_false { ui.elements_displayed?(locator) }

Но в случае с третьим и четвёртым вариантами всё не так просто.

Рассмотрим вариант Не должен появиться:

# вариант "Не должен появиться"ui.wait_for_elements_not_displayed(locator)actual_state = Poll.for(return_on_timeout: true) { ui.elements_displayed?(locator) }Assertions.assert_false(actual_state, "Element #{locator} should not appear")

Здесь мы, во-первых, фиксируем состояние отсутствия элемента на экране.

Далее, используя Poll.for с параметром return_on_timeout, мы ждём появления элемента. При этом метод Poll.for не выбросит ошибку, а вернёт false, если элемент не появится. Значение, полученное из Poll.for, сохраняется в переменной actual_state.

После этого происходит проверка неизменности состояния элемента с использованием метода assert.

Для проверки варианта Не должен пропасть мы используем похожую логику, ожидая пропажи элемента с экрана вместо его появления:

# вариант "Не должен пропасть"ui.wait_for_elements_displayed(locator)actual_state = Poll.for(return_on_timeout: true) { !ui.elements_displayed?(locator) }Assertions.assert_false(actual_state, "Element #{locator} should not disappear")

Проверки этих четырёх вариантов изменения состояния актуальны для многих элементов мобильных приложений. А поскольку разработкой тестов у нас занимается много людей, всегда есть вероятность того, что кто-то забудет про некоторые варианты при создании новых проверок. Поэтому мы вынесли реализацию проверок всех вариантов изменения состояния в один метод:

def verify_dynamic_state(state:, timeout: 10, error_message:)  options = {    return_on_timeout: true,    timeout:           timeout,  }  case state    when 'should appear'      actual_state = Poll.for(options) { yield }      Assertions.assert_true(actual_state, error_message)    when 'should disappear'      actual_state = Poll.for(options) { !yield }      Assertions.assert_true(actual_state, error_message)    when 'should not appear'      actual_state = Poll.for(options) { yield }      Assertions.assert_false(actual_state, error_message)    when 'should not disappear'      actual_state = Poll.for(options) { !yield }      Assertions.assert_false(actual_state, error_message)    else      raise("Undefined state: #{state}")  endend

yield это код блока, переданного в данный метод. На примерах выше это был метод elements_displayed?. Но это может быть любой другой метод, результат выполнения которого отражает состояние необходимого нам элемента. Документация Ruby.

Таким образом, мы можем проверять любые варианты изменения состояния любых элементов вызовом одного метода, что существенно облегчает жизнь всем командам тестирования.

Выводы:

  • важно не забывать про все четыре варианта изменения состояния при проверках UI-элементов;

  • полезно вынести эти проверки в общий метод.

Мы рекомендуем использовать полную систему проверок всех вариантов изменения состояния. Что мы имеем в виду? Представьте, что когда элемент есть это состояние true, а когда его нет false.

Состояние 1

Состояние 2

Должен появиться

FALSE

TRUE

Должен пропасть

TRUE

FALSE

Не должен появиться

FALSE

FALSE

Не должен пропасть

TRUE

TRUE

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

Практика 5. Надёжная настройка предусловий тестов

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

Рассмотрим два примера. Первый отключение сервиса локации на iOS в настройках. Второй создание истории чата.

В первом примере реализация метода отключения сервиса локации на iOS выглядит следующим образом:

def switch_off_location_service  ui.wait_for_elements_displayed(SWITCH)  if ui.element_value(SWITCH) == ON    ui.tap_element(SWITCH)    ui.tap_element(TURN_OFF)  endend

Мы ждём, пока переключатель (элемент switch) появится на экране. Потом проверяем его состояние. Если оно не соответствует ожидаемому, мы его изменяем.

После этого мы закрываем настройки и запускаем приложение. И иногда внезапно сталкиваемся с проблемой: почему-то сервис локации остаётся включённым. Как это получается? Мы же сделали всё, чтобы его отключить. Кажется, что это проблема работы системных настроек в iOS системе. При быстром выходе из настроек (а тест делает это моментально после нажатия на переключатель) их новое состояние не сохраняется. Но проблемы могут возникнуть и при настройке предусловий в нашем приложении.

Давайте обратимся ко второму примеру созданию истории чата перед началом выполнения теста. Реализация метода выглядит следующим образом:

def send_message(from:, to:, message:, count:)  count.times do    QaApi.chat_send_message(user_id: from, contact_user_id: to, message: message)  endend

Мы используем QAAPI для отправки сообщений по user_id. В цикле мы отправляем необходимое количество сообщений.

После этого мы заходим в чат и производим необходимые проверки, связанные с загрузкой истории сообщений. Но иногда в чате отображаются не все сообщения. Иногда мы продолжаем получать их, уже находясь в чате, а не до его открытия. Связано это с тем, что сервер не может отправлять нужное количество сообщений моментально. В некоторых случаях доставка задерживается.

Выделим общую проблему обоих примеров. Когда установка предусловий выполняется некорректно, тесты падают на последующих проверках, несмотря на то, что сами приложения работают как надо. Мы начинаем разбираться в причинах, а потом понимаем, что падение вызвано неправильной подготовкой предусловий. Такие ситуации расстраивают не только тестировщиков, но и разработчиков, которые анализируют прогоны тестов при разработке новой функциональности.

Как же решить эту проблему? Мы можем добавить гарантию выполнения действия в методы установки предусловий.

Тогда наш метод отключения сервиса локации будет выглядеть следующим образом:

def ensure_location_services_switch_in_state_off  ui.wait_for_elements_displayed(SWITCH)  if ui.element_value(SWITCH) == ON    ui.tap_element(SWITCH)    ui.tap_element(TURN_OFF)    Poll.for(timeout_message: 'Location Services should be disabled') do      ui.element_value(SWITCH) == OFF    end  endend

Используя метод Poll.for, мы убеждаемся, что состояние переключателя изменилось, прежде чем переходить к следующим действиям теста. Это позволяет избежать проблем, вызванных тем, что сервис локации время от времени был включён.

Во втором примере нам снова помогут наши методы QAAPI.

def send_message(from:, to:, message:, count:)  actual_messages_count = QaApi.received_messages_count(to, from)  expected_messages_count = actual_messages_count + count  count.times do    QaApi.chat_send_message(user_id: from, contact_user_id: to, message: message)  end  QaApi.wait_for_user_received_messages(from, to, expected_messages_count)end

Перед отправкой сообщений мы получаем текущее количество сообщений в чате, а после убеждаемся, что необходимое количество сообщений было отправлено. Только после этой проверки тест продолжает своё выполнение. Таким образом, когда мы открываем чат в приложении, мы видим все необходимые сообщения и можем выполнять нужные проверки.

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

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

Более подробно о проблемах, описанных в этом разделе, можно прочитать в статье Мартина Фаулера.

Практика 6. Простые и сложные действия, или Независимость шагов в тестах

Простые действия

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

Начнём с теста поиска и отправки GIF-сообщений.

Сначала нам нужно открыть чат с пользователем, которому мы хотим отправить сообщение:

When  primary_user opens Chat with chat_user

Потом открыть поле ввода GIF-сообщений:

And   primary_user switches to GIF input source

Далее нам нужно ввести поисковый запрос для GIF-изображений, убедиться, что список обновился, отправить понравившееся изображение из списка и убедиться, что оно было отправлено.

And   primary_user searches for "bee" GIFsAnd   primary_user sends 7th GIF in the listThen  primary_user verifies that the selected GIF has been sent

Целиком сценарий выглядит так:

Scenario: Searching and sending GIF in Chat  Given users with following parameters    | role         | name |    | primary_user | Dima |    | chat_user    | Lera |  And   primary_user logs in  When  primary_user opens Chat with chat_user  And   primary_user switches to GIF input source  And   primary_user searches for "bee" GIFs  And   primary_user sends 7th GIF in the list  Then  primary_user verifies that the selected GIF has been sent

Обратим внимание на шаг, который отвечает за поиск гифки:

And(/^primary_user searches for "(.+)" GIFs$/) do |keyword|  chat_page = Pages::ChatPage.new.await  TestData.gif_list = chat_page.gif_list  chat_page.search_for_gifs(keyword)  Poll.for_true(timeout_message: 'Gif list is not updated') do    (TestData.gif_list & chat_page.gif_list).empty?  endend

Здесь, как и почти во всех остальных шагах, мы делаем следующее:

  1. сначала ожидаем открытия нужной страницы (ChatPage);

  2. потом сохраняем список всех доступных GIF-изображений;

  3. далее вводим ключевое слово для поиска;

  4. затем ждём изменения состояния обновления списка (ведь мы говорили о том, что полезно добавлять в тесты проверку выполнения действий).

Кажется, что всё реализовано правильно. После завершения поиска мы убеждаемся, что список изображений обновился, и только после этого отправляем одно из них. Но у нас появится проблема, если мы, например, захотим написать тест, проверяющий, что после ввода идентичного поискового запроса список изображений не обновится. В этом случае нам придётся создавать отдельный шаг для ввода поискового запроса для GIF-изображений, который во многом будет дублировать уже имеющийся.

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

Как же нам этого избежать? Как вы, возможно, заметили, наш шаг поиска GIF-изображений на самом деле включал в себя три действия:

  1. сохранение текущего списка;

  2. поиск;

  3. проверку обновления списка.

Решением проблемы переиспользования будет разделение этого шага на три простых и независимых.

Первый шаг сохраняет текущий список изображений:

And(/^primary_user stores the current list of GIFs$/) do  TestData.gif_list = Pages::ChatPage.new.await.gif_listend

Второй шаг поиск гифки позволяет напечатать ключевое слово для поиска:

And(/^primary_user searches for "(.+)" GIFs$/) do |keyword|  Pages::ChatPage.new.await.search_for_gifs(keyword)end

На третьем шаге мы ждём обновления списка:

And(/^primary_user verifies that list of GIFs is updated$/) do  chat_page = Pages::ChatPage.new.await  Poll.for_true(timeout_message: 'Gif list is not updated') do    (TestData.gif_list & chat_page.gif_list).empty?  endend

В итоге наш первоначальный сценарий выглядит следующим образом:

Scenario: Searching and sending GIF in Chat  Given users with following parameters    | role         | name |    | primary_user | Dima |    | chat_user    | Lera |  And   primary_user logs in  When  primary_user opens Chat with chat_user  And   primary_user switches to GIF input source  And   primary_user stores the current list of GIFs  And   primary_user searches for "bee" GIFs  Then  primary_user verifies that list of GIFs is updated  When  primary_user sends 7th GIF in the list  Then  primary_user verifies that the selected GIF has been sent

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

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

Сложные действия

Под сложными шагами мы подразумеваем те, которые включают в себя переходы между разными экранами приложения либо работу с изменением состояния какого-либо экрана. Рассмотрим такую ситуацию на примере голосования в мини-игре.

Мини-игра это экран, на котором пользователю предлагаются профили других людей, которые ему написали. Можно либо отвечать на сообщения, либо пропускать этих пользователей. Действие пропуска назовём Голосовать нет.

Тестовый пользовательТестовый пользователь

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

Проголосовать нет простое действие. Но, если мы сделаем для него простой шаг, то для того чтобы проголосовать N раз, нам нужно будет использовать этот шаг столько же раз на уровне сценария. Читать такой сценарий неудобно. Поэтому есть смысл создать более сложный шаг с параметром Количество голосов, который сможет проголосовать необходимое нам количество раз.

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

When(/^primary_user votes No in Messenger mini game (\d+) times$/) do |count|  page = Pages::MessengerMiniGamePage.new.await  count.to_i.times do    page.vote_no  endend

Но тут мы сталкиваемся с проблемой: иногда тест голосует слишком быстро. То есть он нажимает на кнопку до того, как обрабатывается предыдущее нажатие. В этом случае приложение не отправит новый голос на сервер. Наш шаг при этом выполнится успешно. А на следующем шаге, когда мы захотим убедиться, что пользователь находится на правильной позиции в игре, тест упадёт, потому что предыдущий шаг не выполнил свою задачу и сделал меньше голосов, чем было нужно.

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

When(/^primary_user votes No in Messenger mini game (\d+) times$/) do |count|  page = Pages::MessengerMiniGamePage.new.await  count.to_i.times do    progress_before = page.progress    page.vote_no    Poll.for_true do      page.progress > progress_before       end  endend

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

Подведём итоги. Мы создаём независимые шаги для простых действий. Это позволяет легко их переиспользовать и создавать различные сценарии за более короткое время, чем если бы нам нужно было переписывать похожие друг на друга шаги. В шаги для сложных действий мы добавляем проверки того, что действие выполнено, перед переходом к следующим действиям.

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

Практика 7. Верификация необязательных элементов

Под необязательными элементами мы понимаем такие элементы, которые могут либо отображаться, либо не отображаться на одном и том же экране в зависимости от каких-либо условий. Здесь мы рассмотрим пример диалогов о подтверждении действий пользователя, или алёртов (alerts).

Примеры диалоговых оконПримеры диалоговых окон

Наверняка вы сталкивались с подобными диалогами в различных мобильных приложениях. В наших двух приложениях, например, их больше 70. Они появляются в разных местах в ответ на разные действия пользователей. Что же представляют собой необязательные элементы на них?

Проанализируем скриншоты выше.

  • Скриншот 1: заголовок, описание и две кнопки.

  • Скриншот 2: заголовок, описание и одна кнопка.

  • Скриншот 3: описание и две кнопки.

Таким образом, необязательными элементами в этих диалогах являются заголовок и вторая кнопка. Локаторы у элементов на алёртах одинаковые вне зависимости от того, в каком месте приложения или после какого действия пользователя они появляются. Поэтому мы хотим реализовать проверки для всех типов диалогов один раз на их базовой странице, а потом наследовать от неё каждый конкретный алёрт, чтобы не пришлось повторять этот код. Создание подобных проверок мы и рассмотрим в этом разделе.

Начнём с того, как выглядит вызов метода для верификации каждого из диалогов:

class ClearAccountAlert < AppAlertAndroid  def verify_alert_lexemes    verify_alert(title:        ClearAccount::TITLE,                 description:  ClearAccount::MESSAGE,                 first_button: ClearAccount::OK_BUTTON,                 last_button:  ClearAccount::CANCEL_BUTTON)  endend
class WaitForReplyAlert < AppAlertAndroid  def verify_alert_lexemes    verify_alert(title:        WaitForReply::TITLE,                 description:  WaitForReply::MESSAGE,                 first_button: WaitForReply::CLOSE_BUTTON)  endend
class SpecialOffersAlert < AppAlertAndroid  def verify_alert_lexemes    verify_alert(description:  SpecialOffers::MESSAGE,                 first_button: SpecialOffers::SURE_BUTTON,                 last_button:  SpecialOffers::NO_THANKS_BUTTON)  endend

Во всех примерах мы вызываем метод verify_alert, передавая ему лексемы для проверки необходимых элементов. При этом, как вы можете заметить, WaitForReplyAlert мы не передаём лексему для второй кнопки, так как её не должно быть, а SpecialOffersAlert лексему для заголовка.

Рассмотрим реализацию метода verify_alert:

def verify_alert(title: nil, description:, first_button:, last_button: nil)  ui.wait_for_elements_displayed([MESSAGE, FIRST_ALERT_BUTTON])  ui.wait_for_element_text(expected_lexeme: title, locator: ALERT_TITLE) if title  ui.wait_for_element_text(expected_lexeme: description, locator: MESSAGE)  ui.wait_for_element_text(expected_lexeme: first_button, locator: FIRST_ALERT_BUTTON) ui.wait_for_element_text(expected_lexeme: last_button, locator: LAST_ALERT_BUTTON) if last_buttonend

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

В чём же проблема этого подхода? В том, что мы пропускаем проверку того, что необязательный элемент не отображается тогда, когда он не должен отображаться. Это может привести к комичным ситуациям. Например, может появиться такой алёрт:

Пользователь не понимает, что выбрать: обе кнопки как будто бы закрывают диалог. Это похоже на критический баг. Даже если приложение не падает, это нужно исправить. А тесты нам нужно изменить так, чтобы они выявляли подобные проблемы.

Для этого в тестах мы меняем проверку

ui.wait_for_element_text(expected_lexeme: title, locator: ALERT_TITLE) if title

на

if title.nil?  Assertions.assert_false(ui.elements_displayed?(ALERT_TITLE), "Alert title should not be displayed")else  ui.wait_for_element_text(expected_lexeme: title, locator: ALERT_TITLE)end

Мы изменили условие if и добавили проверку второго состояния. Если мы не передаём лексему для необязательного элемента, значит, этого элемента не должно быть на экране, что мы и проверяем. Если же в title есть какой-то текст, мы понимаем, что элемент с этим текстом должен быть, и проверяем его. Мы решили выделить эту логику в общий метод, который назвали wait_for_optional_element_text. Этот метод мы можем применять не только для диалогов из этого примера, но и для любых других экранов приложения, на которых есть необязательные элементы. Видим, что if-условие из примера выше полностью находится внутри нового метода:

def wait_for_optional_element_text(expected_lexeme:, locator:)  GuardChecks.not_nil(locator, 'Locator should be specified')  if expected_lexeme.nil?    Assertions.assert_false(elements_displayed?(locator), "Element with locator #{locator} should not be displayed")  else    wait_for_element_text(expected_lexeme: expected_lexeme, locator: locator)  endend

Реализация метода verify_alert тоже изменилась:

def verify_alert(title: nil, description:, first_button:, last_button: nil)  ui.wait_for_elements_displayed([MESSAGE, FIRST_ALERT_BUTTON])  ui.wait_for_optional_element_text(expected_lexeme: title, locator: ALERT_TITLE)  ui.wait_for_element_text(expected_lexeme: description, locator: MESSAGE)  ui.wait_for_element_text(expected_lexeme: first_button, locator: FIRST_ALERT_BUTTON)  ui.wait_for_optional_element_text(expected_lexeme: last_button, locator: LAST_ALERT_BUTTON)end

Мы всё так же ожидаем появления обязательных элементов на экране. После этого проверяем, что их текст совпадает с переданными в метод лексемами. В случае же с необязательными элементами теперь мы используем метод wait_for_optional_element_text, который помогает убедиться, что необязательный элемент не отображается тогда, когда не должен отображаться.

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

Резюме: мы советуем использовать полную систему проверок всех состояний нужных элементов, а также выделять общие методы для однотипных действий.

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

Общие рекомендации

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

  • так как проверки это то, ради чего мы пишем тесты, всегда используйте полную систему проверок;

  • не забывайте добавлять проверку предустановки для асинхронных действий;

  • выделяйте общие методы для переиспользования однотипного кода как в шагах, так и в методах на страницах;

  • делайте объект тестирования простым;

  • выделяйте независимые методы для простых действий в тестах.

Возможно, эти советы кому-то покажутся очевидными. Но мы хотим обратить ваше внимание на то, что применять их можно (и нужно) в разных ситуациях. Если вы хотите дополнить список другими полезными рекомендациями, добро пожаловать в комментарии!

Бонус

Мы подготовили тестовый проект, в котором отразили все практики, описанные в статье. Переходите по ссылке, изучайте и применяйте:

Mobile Automation Sample Project

Подробнее..

Зачем и как мы пишем постмортемы по критичным багам

30.04.2021 16:23:36 | Автор: admin

В какой-то момент у нас стало много хотфиксов стабильно больше половины деплоев на проде были хотфиксы или откаты. Мы решили анализировать каждый хотфикс, чтобы понять причины, найти системные закономерности и устранить их, не допуская два раза одних и тех же ошибок. Как говорил Джейсон Стейтем (Стэтхэм? Стэтэм?): Не страшно ошибаться, страшно повторять одну ошибку 2 раза. Ну и мы решили не повторяться. В статье расскажу как мы анализируем хотфиксы и другие критичные проблемы, что у нас получается, а что нет, с какими сложностями столкнулись и как их решали.

Как было раньше

Раньше на проде случались хотфиксы-откаты из-за критичных багов. Мы в QA понимали что нам нужно проводить какую-то ретроспективу по пропущенным багам на прод. Поэтому после каких-то очень проблемных релизов:

  • собирались и обсуждали проблему;

  • звали разработчиков, участвующих в этом релизе;

  • принимали решения (некоторые работают до сих пор).

Основная проблема при таком подходе, что ты не разбираешь каждый хотфикс или откат детально. Ты обращаешь внимание только на очень критичные проблемы. Такая активность не системная.

Когда хотфиксов стало много (примерно половина всех выкладок на прод были хотфиксы) поняли, что этого недостаточно нужно что-то менять. Мы решили попробовать практику написания постмортемов на хотфиксы и откаты.

Что такое постмортем?

Вообще, постмортем это посмертная фотография родственников.

Мы узнали об этой практике у нашей команды Платформы. Они уже с 2018 года ведут постмортемы по всем инцидентам в системе.

Постмортем для примера.Постмортем для примера.

Наши люди даже выступали с этими темами на конференциях.

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

Как начали вести

Мы почитали о практике ведения постмортемов, чтобы не допустить критичных ошибок при их написании. Пошли в репозиторий с постмортемами от команды Платформы, почитали их постмортемы и на основании их шаблона сделали свой (шаблон будет в конце статьи).

Вначале мы вели постмортемы в Nuclino. Но в нём сложно трекать статус каждого постмортема, выполняемость решений и т.д. и т.п. А вот в Kaiten наглядно видно текущий статус постмортема, какие из них без решений, можно строить какие-то отчеты. Поэтому наши постмортемы логично переехали туда.

Скрин с Kaiten.Скрин с Kaiten.

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

  • По хотфиксам на проде.

  • По откатам релизов.

  • По подливкам в релиз когда в релизную ветку подливают фиксы. Иногда на этапе прогона тестов находятся критичные баги. Если бы они попали на прод был бы хотфикс, иначе их бы пофиксили стандартным флоу в следующем релизе.

  • По STL (Stop the Line). Подробнее что это такое можно почитать в статье Stop the line или прокачай свой pipeline, йоу

Пример шаблона для хотфиксов из Kaiten.Пример шаблона для хотфиксов из Kaiten.

Структура и способ ведения

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

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

Авторы постмортема. Знаем к кому идти за подробностями инцидента или с уточняющими вопросами по решению. Наличие авторов постмортема не противоречит принципу написания постмортемов blameless culture. Мы не обвиняем никого в доведении до проблемы, а хотим лишь отобразить участников разбора.

Причины. В этом блоке описываем причину которая привела к хотфиксу, что с технической точки зрения произошло. Стараемся выяснить корневые причины случившегося.

Проблемы. Пишем о том, с какими проблемами могли столкнуться наши пользователи. Какую функциональность мы задели, какие непотребства видели наши пользователи. Или что видели мы, если мы заметили проблему раньше пользователей (алерты, подскочившие графики в Grafana).

Потери. В этом блоке пишем влияние на бизнес, сколько задето пиццерий или пользователей, сколько потеряли в деньгах или во времени (это импакт на пользователей).

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

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

Шаблон

Здесь оставлю пример шаблона наших постмортемов без моих комментариев.

## Дата

## Автор

## Проблемы

## Причина

## Последствия для бизнеса

## Предложения по недопущению в будущем

## Как можно было избежать проблемы (представь что у тебя есть машина времени и ты вернулся к моменту, когда ты еще не написал этот код, что можно было сделать, чтобы не было хотфикса)

**Создать картохи на написание _автотеста_ по этой проблеме в своем бэклоге и прикрепи их сюда как дочерние**

**Создать картохи по _недопущению хотфикса_ в будущем в своем бэклоге или бэклоге владельцев компонента и прикрепи их сюда как дочерние**

## Что ещё хочется добавить

**Не забудь поставить теги компонента в котором случилась проблема**

Берите себе, адаптируйте и пользуйтесь.

Сложности и как их решали

С нахрапа не получилось ввести постмортемы и вести их идеально. Вот наш список проблем.

Не заполняли постмортемы. Банально да: поначалу люди ответственные за релиз забывали заполнять постмортемы

Решили проблему добавив в чек-лист релизмена пункт о необходимости заполнения постмортема. Релизмен разработчик отвечающий за выкатку релиза, ротируется после каждого релиза.

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

Не предлагали решений или предлагали слабые решения. Сейчас основная проблема в том, что почти в половине постмортемов нет решений или они очень общие типа распилить монолит, тестировать перед мержом в дев, писать код без багов, а с багами не писать.

Проблему решили припиской в чек-листе, что когда QA пишет постмортем, он должен позвать другого QA. Мы прямо в процессе написания постмортема можем дать обратную связь о слабом решении или вообще о его отсутствии. Либо после написания постмортема нам отправляют его на ревью и мы так же даем обратную связь только уже асинхронно.

Скрин с чек-листа.Скрин с чек-листа.

Не создавали карточки на решение проблем. Мы используем Kaiten и настроили доски так:

  • прикреплённая дочерняя карточка с устранением проблемы берется в работу;

  • постмортем автоматически переезжает в In progress;

  • когда задачу завершают завершается и постмортем.

Это помогает не мониторить исполнение постмортемов.

Поначалу карточки не создавались, а даже если создавались, то не прикреплялись как дочерние и постмортемы не двигались. Решили тоже просто добавив в шаблон пометку о том, что нужно создать карточку и прикрепить её как дочернюю.

Решения долго берут в работу. Мы все понимаем, что бэклогом владеет продакт и у него есть приоритеты. Мы понимаем, что когда команда берёт техзадачи в спринт, это зависит от множества факторов: понимания продактом важности этих технических задач и последствий (если их не решить), от зрелости самой команды, критичности сервиса и проблемы. Но проблема всё равно болезненная.

Мы провели небольшую аналитику по среднему времени ожидания постмортема до момента когда над ним начали работу. Получилось, что медианное время ожидания постмортема до взятия в работу меньше месяца 21 календарный день. По результатам навесили на колонку напоминание: когда карточка висит в ToDo дольше, она начинает привлекать к себе внимание.

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

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

Результаты в цифрах

Мы проанализировали постмортемы за пол года, и вот какая картина получается.

  • Треть наших постмортемов не имеют конкретных решений на доработку и недопущение проблем в будущем.

  • Половина наших постмортемовв которых есть конкретные решения ещё не выполнена.

  • 49 дней медианное время жизни постмортема от появления на доске до выполнения (из тех что выполнили и в которых были решения), а среднее 82 дня. Такие различия обусловлены большим разбросом значений. Критичные решения или очень простые решаются достаточно быстро, сложные и не критичные могут долго провисеть в ожидании.

Ситуация не радужная, но благодаря ведению этих постмортемов мы знаем о проблеме и можем предпринимать действия по её улучшению.

Выводы

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

Мы решили сконцентрироваться на постмортемах без экшен айтемов. Моя первая мысль была: Не лучше ли фокусироваться на выполнении постмортемов?. Однако, после некоторого обсуждения на комьюнити, мы пришли к выводу, что если пишется постмортем то должен быть экшен айтем, иначе это бесполезная работа. Поэтому мы решили увеличить этот процент, а после его увеличения взяться за повышение исполняемости этих постмортемов.

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


Что ещё почитать.

Stop the line или прокачай свой pipeline, йоу

Будущее интерактивного дизайна в руках

История Open Source кратко: от калькулятора до миллиардных сделок

Как выйти на китайский рынок с mini-app для WeChat, чтобы не прогореть

Как мы разогнали команду QA, и что из этого получилось

История архитектуры Dodo IS: ранний монолит

Код без тестов легаси

Подписывайтесь начат Dodo Engineering, если хотите обсудить эту и другие наши статьи и подходы, а также на каналDodo Engineering, где мы постим всё, что с нами интересного происходит. А ещё естьгруппа в ВК(ну мало ли).

Подробнее..

Перевод Что нам стоит автоматизацию построить три паттерна для повышения эффективности процессов

20.05.2021 20:12:40 | Автор: admin

Меня зовут Владислав Романенко, я старший iOS QA Engineer в Badoo и Bumble. Несколько лет назад мы начали активнее использовать автотесты в разработке, но столкнулись с некоторыми трудностями.

Логичный вопрос: почему мы занялись автоматизацией тестирования? Ответ кроется в еженедельном выпуске новых версий наших мобильных приложений. QA-отделу приходится тестировать новые фичи, их интеграцию в сервисы и заниматься регрессионным тестированием. За неделю комплексное регрессионное тестирование нужно проводить как минимум один раз, что довольно утомительно. Автоматизация помогла нам выпускать новые версии быстрее и без потери качества. Подробнее об автоматизации мобильного тестирования в докладе моих коллег.

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

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

Паттерн 1. Просьба о помощи (Ask for Help)

Как это часто бывает, мы все имели разный опыт, знания и навыки. На тот момент не все в команде сталкивались с автоматизацией тестирования некоторым пришлось учиться на ходу. Чтобы помочь коллегам из команды QA справиться со сложностями, мы предложили им обратиться за помощью к команде автоматизации. Идея в том, что если ты застреваешь на какой-то проблеме, то не нужно самостоятельно бороться с ней слишком долго, ведь другие уже могли столкнуться с подобным и найти решение. А чтобы автоматизаторов не завалили вопросами, мы решили формализовать этот подход. Прекрасным решением оказался паттерн ASK FOR HELP:

Просите о помощи, а не теряйте время, пытаясь всё сделать самостоятельно.

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

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

Внутрениий StackOverflow

Стоит отметить, что в нашей вики есть документация и описания решений для большинства распространённых проблем. Возможно, документировать все возможные ошибки и объяснения в вики не лучший подход, но мы считали, что сохранить их в одном месте будет полезно. Так у нас возникла идея создания локального Stack Overflow. Для этого мы воспользовались open source-решением Scoold. Оно предназначено для использования на первой линии обработки запросов и работает как обычная Stack Overflow, только для сотрудников компании. Когда у кого-нибудь возникает проблема, достаточно зайти в наш локальный Stack Overflow, чтобы найти решение или написать вопрос, на который ответит кто-то из специалистов.

Так выглядит наш локальный StackOverflowТак выглядит наш локальный StackOverflow

Преимущества

  • Процесс геймифицируется, поэтому в поиск решений вовлекается больше людей. Мы не стали придумывать разные лычки или звания количество голосов или звёзд ничего не значит и вам не советуем этим увлекаться. Геймификация лишь дополнительный стимул для участников, а не основной фактор.

  • Мы тратим меньше времени и сил на решение проблем. Во-первых, они оказываются на виду, поэтому их проще решить. Во-вторых, уменьшается количество перекидываний задачи от одного человека к другому.

  • Стало меньше сообщений и веток в чатах, где их трудно отслеживать и искать. Мессенджеры не лучшее место для хранения документации и обращения к ней как к источнику истины. Stack Overflow гораздо удобнее.

Недостатки

  • Нет ответственного за запуск реализации. Нужно, чтобы кто-то стимулировал создание даже простейшего решения. Нам повезло в нашем случаем таким человеком стал dr0pt4ble, который взял инициативу в свои руки. Не менее важно, чтобы руководство понимало и поддерживало такую инициативу.

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

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

Паттерн 2. Введение стандартов (Set Standards)

По мере возможности мы стараемся переиспользовать код в разных приложениях и на разных платформах, чтобы упростить сопровождение и поддержку. Но, как и в любой другой системе, которую несколько лет разрабатывало много людей, разные части кода могут быть написаны в разных стилях. Наш основной язык для сквозных автотестов это Ruby (об истории автоматизации мобильного тестирования в нашей компании рассказывал agile_seph здесь), потому что он как раз позволяет писать код в разных стилях (автор языка Юкихиро Мацумото хотел, чтобы разработчики использовали его язык так, как им удобно). Однако работать с чужим кодом бывает сложно.

Для решения этой проблемы мы выбрали паттерн SET STANDARDS:

Введите и соблюдайте стандарты для артефактов автоматизации.

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

Что мы сделали

  • Создали локальную вики с актуальными руководствами и документами (например, как настроить окружение, как запускать и поддерживать тесты), которая помогла сократить циклы ревизии кода. Всю документацию мы храним в Confluence, который разделили на несколько частей. Команды регулярно проверяют актуальность своей документации.

  • Добавили в вики межкомандные ретроспективы и соглашения. Ежемесячно мы проводим встречи и по результатам каждой из них делаем какие-то практические выводы.

  • Что касается самого кода тестов и ограничений на уровне кода для основных этапов и методов верификации, мы внедрили стандартные инструменты, включая RuboCop (статический анализатор и инструмент форматирования кода для Ruby), защитные проверки (Guard Cheсks) и pre-commit-хуки.

  • Вычистили устаревший код и выделили универсальные параметризированные этапы и методы. Рекомендовали не создавать собственные методы, если можно воспользоваться уже существующими. Образец проекта с некоторыми из наших лучших практик можно посмотреть здесь.

  • Из участников команды автоматизации тестирования сформировали комитет качества кода. У него есть список вопросов и задач, поучаствовать в решении которых может любой желающий. Мы также приглашаем на встречи комитета всех, у кого есть вопросы, чтобы помочь в их решении.

Преимущества

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

  • На ревью кода уходит меньше времени. С одной стороны, код становится аккуратнее, с другой всегда есть источник истины для рецензента и рецензируемого.

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

Недостатки

  • После создания документации её никто не сопровождает. Это общая проблема для любой документации, особенно для той, что не используется постоянно. Поэтому мы назначили ответственных за сопровождение документов и настроили отправку им на почту уведомлений из Confluence, чтобы ничьи комментарии не оставались без внимания.

  • Трудно организовывать ретроспективные встречи и привлекать людей. Непросто найти время, когда все заинтересованные сотрудники не заняты решением своих задач. Поэтому такие встречи приходится планировать сильно заранее.

Паттерн 3. Делимся информацией (Share Information)

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

Этот паттерн называется SHARE INFORMATION:

Просите и давайте информацию начальству, разработчикам и другим тестировщикам.

Для нас это способ улучшить автоматизацию тестирования за счёт более широкого набора знаний. Для реализации этого паттерна мы запустили еженедельные короткие презентации QA Lightning Talks. Любой человек может предложить тему и в течение 10-15 минут выступить с ней. Поскольку у встреч чёткий тайминг, это хорошая возможность узнать что-то новое, не потратив на это много времени. Для тех, кто не смог присутствовать, мы сохраняем видеозаписи встреч во внутренней библиотеке.

Доклады могут быть посвящены не только тестированию и его автоматизации. Например, однажды bayandin рассказывал о своём опыте поддержки проекта Homebrew. А я как-то рассказывал о том, что я диванный картограф в Humanitarian OpenStreetMap. Я создаю карты районов, которые плохо картографированы, и потом ими пользуются в работе сотрудники разных организаций вроде Красного Креста или Врачей без границ. Сокращённая версия этого доклада позднее была представлена на сессии Soapbox конференции EuroSTAR 2020.

Преимущества

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

  • Общий объём знаний растёт. А согласно исследованию, обмен знаниями улучшает взаимодействие между департаментами и внутри них.

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

Недостатки

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

  • Трудно удерживать интерес аудитории и увеличивать ее. Мы каждый раз меняем тему и сосредотачиваемся на актуальных проблемах. Например, один из проектов заключался в том, что мы собирали результаты всех тестовых прогонов тикета в таблицу и интегрировали её в Jira. Об этом на ближайшей встрече и рассказал один из участников команды автоматизации тестирования.

Бонус: паттерн для обучения разделение на пары (Pair Up)

Расскажу ещё о том, к чему привели вышеописанные шаги. Например, QA-инженеры стали готовы брать (и постепенно взяли) ответственность за написание, сопровождение и анализ нестабильных автоматизированных тестов. Поэтому мы решили пойти дальше сделать так, чтобы они взяли на себя ещё и фреймворк автоматизации тестирования и некоторые связанные с инструментарием задачи. Такой шаг был бы невозможен, если бы тестировщики не смогли, помимо своих повседневных задач, ещё и изучать фреймворк и плотно работать с кодовой базой. И хотя регулярные задачи решались качественно, казалось, что выйти за их пределы без помощи будет непросто.

Чтобы достичь цели, мы воспользовались паттерном PAIR UP:

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

Для QA-инженеров мы запустили внутреннюю программу менторства. Что это такое? QA-инженеры присоединяются к автоматизаторам на короткий промежуток времени (обычно на две недели) и работают над задачами из бэклога этой команды, а не из своего. Помогают им в этом менторы из числа старших инженеров-автоматизаторов. Цель внутреннего менторства заключается в обучении. Мы разработали такой манифест:

  • Сосредоточенность на обучении, а не на строгом соблюдении сроков.

  • Интерактивные обсуждения, а не работа в бункере.

  • Ранняя и регулярная обратная связь, а не ретрообзор в конце менторства.

Хотя утверждения справа ценны, утверждения слева для нас ценнее.

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

Итоги

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

Какие проблемы мы смогли решить

  • Нежелание обращаться за помощью к коллегам (решили с помощью паттерна Ask for help). Как отметили в своей книге A Journey through Test Automation Patterns: One teams adventures with the Test Automation Серетта Гамба и Дороти Грэхем, не бойтесь просить о помощи: большинству людей на самом деле нравится помогать.

  • Высокая стоимость сопровождения кодовой базы тестирования (решили с помощью паттерна Set Standards). Если вы давно работаете над автоматизацией, то стандарты просто необходимы.

  • Информационный бункер (решили с помощью паттерна Share Information). Общайтесь с другими людьми: в процессе обсуждения часто рождаются новые идеи.

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

Расскажите в комментариях, с какими сложностями при автоматизации тестирования столкнулись вы и как их решали.

Подробнее..

Подборка 150 ресурсов для управления и работы ИТ-команды

22.05.2021 16:14:00 | Автор: admin

Привет! На связи компанияKODE. Мы занимаемся разработкой мобильных приложений, голосовых интерфейсов, IoT и других цифровых решений для государства и крупного бизнеса в России и Европе с 2013 года.

Руководители наших отделов собрали полноценную библиотеку IT-компании: сайты, блоги, книги, онлайн-курсы, подкасты, Telegram- и YouTube-каналы. Подборка будет полезна менеджерам, аналитикам, разработчикам, дизайнерам и QA.

Направления:

Сохраняйте, чтобы не потерять!Используйте и совершенствуйтесь.


Проджект-менеджмент

Сайты:

Книги:

Курсы:

YouTube-каналы:

Telegram-каналы:

  • Psilonsk канал Сергея Колганова об управлении проектами и продуктами.

  • Селиховкин о проектном управлении в другом формате.

Аналитика

Книги:

Курсы:

Telegram-каналы:

UX/UI-дизайн

Сайты:

Книги:

Курсы:

Фильмы:

YouTube-каналы:

Android-разработка

Сайты:

Книги:

Курс:

Подкасты:

  • Fragmented подкаст о том, как стать лучшим разработчиком ПО.

  • Сушите вёсла о разработке, аналитике, тестировании и других аспектах создания приложений.

  • CoRecursive истории, скрывающиеся за кодом, от экспертов в мире разработки.

  • Signals And Threads интервью о тонкостях разработки с инженерами из глобальной торговой компании Jane Street.

  • Software Engineering Radio еженедельные беседы о ПО.

  • Microsoft Research Podcast о передовых технологиях Microsoft Research.

Telegram-каналы:

Twitter:

iOS-разработка

Сайты:

Книги:

Курсы:

Подкаст:

  • Подлодка еженедельное аудиошоу о разработке.

YouTube- и Telegram-каналы:

  • YouTube-каналПола Хадсонапо SwiftUI.

  • Telegram-каналdeprecated чат для новичков, где разбирают сложные для них вопросы.

Backend-разработка

Книги:

YouTube-каналы:

Telegram-каналы:

Frontend-разработка

Ресурсы и сайты:

Блоги:

  • Дэн Абрамов личный блог разработчика, одного из авторов Redux.

  • Katz Got Your Tongue статьи Иегуды Каца, соавтора Ember.js и ответственного за разработку плагинов в jQuery.

Книги:

Подкасты:

  • FrontoWeek важные события фронтенда за неделю.

  • Веб-стандарты ещё один новостной канал.

  • UnderJS обсуждения JS на Frontend и Backend, React Native, Linux.

  • Фронтенд Юность вся правда о фронтенд-разработке.

  • Frontend Weekend интервью с известными людьми из веб-разработки.

  • Пятиминутка React подкаст о React и смежных технологиях в мире JavaScript и фронтенда.

  • kamyshev.talk об архитектуре, коде и гибких навыках.

YouTube-каналы:

Telegram-каналы:

QA

Сайты:

  • ПорталSoftware Testing сотни тематических статей, подборок книг по тестированию и обзор новостей отрасли.

  • БлогQCoder концентрат полезных знаний.

Курсы:

Telegram-каналы:

YouTube-каналы:

  • Любительский канал Алексея Баренцева полезные видео для начинающих тестировщиков.

  • QAGuild об автоматизации тестирования и ИТ.

  • Heisenbug доклады с международной технической QA-конференции.

  • Канал ИТ-компанииiTechArt, где еженедельно публикуются записи выступлений разработчиков и тестировщиков.

DevOps

Книги:

Telegram-каналы:


Не забудьте поделиться с коллегами и теми, кому может быть интересна эта подборка!

Подробнее..

Подборка 150 ресурсов для управления и работы IT-команды

22.05.2021 18:12:52 | Автор: admin

Привет! На связи компанияKODE. Мы занимаемся разработкой мобильных приложений, голосовых интерфейсов, IoT и других цифровых решений для государства и крупного бизнеса в России и Европе с 2013 года.

Руководители наших отделов собрали полноценную библиотеку IT-компании: сайты, блоги, книги, онлайн-курсы, подкасты, Telegram- и YouTube-каналы. Подборка будет полезна менеджерам, аналитикам, разработчикам, дизайнерам и QA.

Направления:

Сохраняйте, чтобы не потерять!Используйте и совершенствуйтесь.


Проджект-менеджмент

Сайты:

Книги:

Курсы:

YouTube-каналы:

Telegram-каналы:

  • Psilonsk канал Сергея Колганова об управлении проектами и продуктами.

  • Селиховкин о проектном управлении в другом формате.

Аналитика

Книги:

Курсы:

Telegram-каналы:

UX/UI-дизайн

Сайты:

Книги:

Курсы:

Фильмы:

YouTube-каналы:

Android-разработка

Сайты:

Книги:

Курс:

Подкасты:

  • Fragmented подкаст о том, как стать лучшим разработчиком ПО.

  • Сушите вёсла о разработке, аналитике, тестировании и других аспектах создания приложений.

  • CoRecursive истории, скрывающиеся за кодом, от экспертов в мире разработки.

  • Signals And Threads интервью о тонкостях разработки с инженерами из глобальной торговой компании Jane Street.

  • Software Engineering Radio еженедельные беседы о ПО.

  • Microsoft Research Podcast о передовых технологиях Microsoft Research.

Telegram-каналы:

Twitter:

iOS-разработка

Сайты:

Книги:

Курсы:

Подкаст:

  • Подлодка еженедельное аудиошоу о разработке.

YouTube- и Telegram-каналы:

  • YouTube-каналПола Хадсонапо SwiftUI.

  • Telegram-каналdeprecated чат для новичков, где разбирают сложные для них вопросы.

Backend-разработка

Книги:

YouTube-каналы:

Telegram-каналы:

Frontend-разработка

Ресурсы и сайты:

Блоги:

  • Дэн Абрамов личный блог разработчика, одного из авторов Redux.

  • Katz Got Your Tongue статьи Иегуды Каца, соавтора Ember.js и ответственного за разработку плагинов в jQuery.

Книги:

Подкасты:

  • FrontoWeek важные события фронтенда за неделю.

  • Веб-стандарты ещё один новостной канал.

  • UnderJS обсуждения JS на Frontend и Backend, React Native, Linux.

  • Фронтенд Юность вся правда о фронтенд-разработке.

  • Frontend Weekend интервью с известными людьми из веб-разработки.

  • Пятиминутка React подкаст о React и смежных технологиях в мире JavaScript и фронтенда.

  • kamyshev.talk об архитектуре, коде и гибких навыках.

YouTube-каналы:

Telegram-каналы:

QA

Сайты:

  • ПорталSoftware Testing сотни тематических статей, подборок книг по тестированию и обзор новостей отрасли.

  • БлогQCoder концентрат полезных знаний.

Курсы:

Telegram-каналы:

YouTube-каналы:

  • Любительский канал Алексея Баренцева полезные видео для начинающих тестировщиков.

  • QAGuild об автоматизации тестирования и ИТ.

  • Heisenbug доклады с международной технической QA-конференции.

  • Канал ИТ-компанииiTechArt, где еженедельно публикуются записи выступлений разработчиков и тестировщиков.

DevOps

Книги:

Telegram-каналы:


Не забудьте поделиться с коллегами и теми, кому может быть интересна эта подборка!

Подробнее..

Где логика?! История тестирования одного микросервиса

21.04.2021 12:06:56 | Автор: admin

Эта статья расшифровка доклада Дениса Кудряшова, QA-инженера Leroy Merlin, с конференции QA Meeting Point 2020.

Денис рассказал, как столкнулся со сложной логикой, реализованной в сервисе, применил подход Control Flow Testing, и что из этого вышло. Из текста вы узнаете, можно ли использовать этот подход для синхронных или для асинхронных логических схем, какие нюансы есть у каждого кейса, а также почему моки и Control Flow Testing идеальное сочетание.


Небольшой эндпоинт и первые нюансы

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

Хотя схема на картинке не из реального проекта, но передает ситуацию почти на 100%. На реальной схеме было большое количество ветвлений и различных вариантов обработки данных. Но это было не главное: я знал, что есть какой-то нюанс, который смутил моего коллегу так и оказалось.

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

Во-вторых, обнаружилось, что мы не можем влиять на выбор ветки входными данными. Те данные, которые отправлялись на вход тестируемого микросервиса, могли повлиять только лишь на список возвращаемых параметров. То есть мы могли задать какие-то интересующие нас параметры, они бы вернулись в ответе. Если же их не задавали тогда возвращался просто дефолтный набор данных. Но на маршрут движения данных по схеме мы никак не влияли. Повлиять могли исключительно ответы связанных сервисов, но на том окружении мы не могли ничего сделать, так как интегрированные сервисы были в зоне ответственности других команд.

Нюансы всплыли, задача ясна, надо подумать, как это протестировать. Первый и самый основной вопрос: а кто уже делал подобное до меня?

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

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

Допустим, пусть схема асинхронная. Но, может быть, коллеги уже нашли какое-то решение? К сожалению, на тот момент команда микросервиса тоже билась над этой задачей. Что ж, решения нет, нужно гуглить.

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

То, что мы тестируем, выглядит как API. То есть такая логика может быть зашита в любом микросервисе. В нашем случае, если мы запрашиваем какой-то сервис, то отправляем запрос, происходит магия обработки данных по некоей логической схеме и возвращается ответ. И если мы отправляем такой же запрос в асинхронную схему, то нам как минимум возвращается ответ о том, что процесс стартанул либо нет. То есть весь тест условно можно свести к запросу и анализу ответа и каких-то дополнительных данных. Это уже лучше. Но опять же есть нюанс. Одинаковый результат можно достигнуть совершенно разными ветками схемы. И вот здесь возникает вопрос: как нам эти пути однозначно определить (проверить-то нужно все варианты)? Пометим себе этот вопрос и идём дальше.

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

Попробуем формализовать и обобщить задачу и приведём какую-то абстрактную схему, для простоты с одним ветвлением.

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

Данная методика называется Control Flow Testing и заключается в том, что мы как бы разделяем нашу логическую схему на пути обработки данных, и подбором входных данных и управлением ответами от интегрированных сервисов формируем прохождение наших данных по тестируемой ветке логической схемы. Вроде бы просто. Но опять же есть нюанс. Имеется как минимум две схемы работы, одна асинхронная, другая синхронная. Можем ли мы применить подход Control Flow Testing для обеих схем?

Начнем проверку нашей гипотезы с синхронной схемы.

Control Flow Testing для синхронных схем

Вот пример того, как может выглядеть реальная схема в нашей документации. Она полностью синхронная, здесь есть несколько запросов в интегрированные микросервисы. Первый запрос в эндпоинт /start, далее запросы в сервис 1 и сервис 2. Движение данных у нас зависит от ответов микросервисов. В принципе схема достаточно информативная, но для удобства восприятия вариантов движения данных, ее можно разбить её по веткам и представить в табличном виде.

Вот такая простая табличка получилась у меня. Мы берём проверку на узле ветвления за шаг, движемся от проверки к проверке и таким образом описываем путь данных. + и обозначают True/False соответственно, пустое значение ветвление недоступно в данной ветке. В принципе ничего сложного. Единственное, что мы должны учесть в нашем примере это запрос в сервис 2, но о том, как это сделать правильно, расскажу ниже.

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

То же самое касается повторяющихся веток. Такая ситуация возможна в случае, когда, например, после какого-то определённого ветвления данные не изменяются, после чего ветки вновь объединяются в единый поток. Я остановлюсь на этом более подробно, а пока примем, что отсутствие повторяющихся веток является критерием качественно спроектированной схемы.

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

Какие же нюансы у нас возникают при попытке применить Control Flow Testing для анализа схемы? Опытным путем было выяснено, что табличку надо составлять на самом первом этапе, то есть на этапе проектирования фичи или сервиса. Мы столкнулись с тем, что при составлении таблицы и дальнейшей проверке ветвлений были получены результаты, которые вынудили команду переделать схему. У нас были дополнительные ненужные проверки, очень-очень много дублей. Всё это разработчикам пришлось выпилить, из-за чего процесс затянулся. Поэтому таблички лучше всё-таки предоставлять в самом начале проектирования фичи.

Пример таблицы с ветками схемы, возвращающими только ошибки (дополнительный материал, не было в презентации)Пример таблицы с ветками схемы, возвращающими только ошибки (дополнительный материал, не было в презентации)

Следующий момент: иногда нам необходимо проверить последний вызов в схеме (или проверить его отсутствие см. рисунок выше). Для чего это делается?

Если мы посмотрим на схему, то вызов в сервис-2 (самый правый снизу) происходит у нас как бы в информативном режиме для схемы, и после него никаких ветвлений нет. Соответственно, данный вызов может повлиять либо на состояние системы (и мы его должны будем проверить, чтобы удостовериться, что вызов был или не был произведен), либо на возвращаемые данные. В последнем варианте нам необходимо дополнительно проверить вернувшиеся данные.

Control Flow Testing для асинхронных схем

Ок, вроде бы с синхронной схемой разобрались. Что же с асинхронной?

С асинхронной схемой ситуация примерно следующая: в документации схемы обычно описываются в BPMN виде. Это связано с нюансами реализации и используемыми инструментами.

Выделенная часть схемы это цепочка запросов в сервис 5, которая является циклической. При обработке представленной схемы у нас может возникнуть ситуация, когда данные пойдут по пути положительного выполнения задачи, и схема достигнет статуса готово. Но при этом с начальный момент времени схема зациклится и повиснет в статусе ожидает старта. Такое очень даже возможно, а значит нам нужно каким-то образом учесть эти циклы.

Что важно при этом помнить? Первое: циклы это не блоки ветвления. Они используют блоки, но если мы посмотрим на выделенный кусок схемы и уберём проверку тайм-аута, то у нас получится просто ровная веточка, при движении по которой статус задачи изменяется от в работе до готово.

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

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

Однако циклы будут нам очень полезны при составлении тест-кейса. В тест-кейсе проверяется статус задачи, статус допускает несколько вариантов. Если мы попадаем в вариант, который у нас представлен циклической частью схемы, то дописываем какие-то дополнительные действия по проверке статуса схемы.

Что ещё интересного в тест-кейсе с асинхронной работой? Здесь мы в некоторых случаях вынуждены эмулировать действия сторонних сервисов, делать запросы в тестируемый микросервис или кидать сообщения в очередь RabbitMQ или Kafka от имени интегрированных микросервисов. То есть нам придётся в самом тесте эмулировать эти сервисы. Но в целом тест-кейс похож на вариант с синхронной схемой.

Перейдём к нюансам асинхронных схем.

  1. Ответ сервиса нам, как правило, возвращает 200, 201, 202 то есть ответы группы Ок (2хх). В этом случае ответ абсолютно неинформативен, мы только знаем, что процесс запущен, и приходится дополнительно проверять через методы сервиса, в каком статусе он находится. Соответственно, в проверяемой ветке статус может иметь различные значения. Нам необходимо учитывать такую инвариантность статуса при проведении теста и правильно ее обрабатывать. В противном случае тест просто может упасть, не дождавшись смены статуса на нужный.

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

Вывод: мы можем применить Control Flow Testing к обеим вариантам логических схем.

Правила составления таблиц

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

Первое: в таблицу вносятся все узлы ветвлений по порядку. Это значит, что мы берём логическую схему, и, в зависимости от формата, проходим ее либо слева направо, либо сверху вниз. И записываем в табличку все узлы, в которых происходит выбор того или иного пути дальнейшей обработки данных.

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

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

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

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

Моки

Итак, мы используем подход Control Flow Testing, используем табличное представление схемы, но это не все для теста нам потребуются моки. Зачем? Чтобы ответить на этот вопрос, давайте ещё раз взглянем на схему.

Для тестирования определенной ветки нам нужно заставить сервис отправлять нужные нам данные. Как мы это можем сделать? Вариант 1 мокировать этот сервис и уже в заглушке отправлять нужные нам данные.

Вариант 2: запрос в сервис 1, который также возвращает какие-то данные. Однако вернувшиеся данные в схеме не анализируются, проверяется только ответ сервиса. То есть если бы у нас был 404 not found, мы бы пошли по веточке с запросом в сервис 2, иначе тестируемый сервис вернул бы некоторые данные и положительный ответ. При мокировании важен только ответ сервиса, возвращаемые данные не важны.

И вариант 3, когда мы не анализируем вообще ответ сервиса, но при этом запрос у нас есть и каким-то образом нам нужно отлавливать момент запроса вот в этот сервис, либо отсутствие запроса в этот сервис. Здесь возвращаемые заглушкой данные также не важны.

Как использовать моки

Если мы посмотрим на табличку с уже известными ветками и допустим, что нам потребовалось составить тест-кейс для ветки 3, очень удобно использовать те данные, которые у нас уже имеются. Что у нас есть? Есть запрос в эндпоинт /start, помеченный плюсиком. В блоке проверка ответа нас интересует, чтобы сервис возвращал какой-то код ответа в теле, равный двум. В этом случае мы попадаем в ветку 3. Но нам этого недостаточно, нам необходимо ещё поставить мок для сервиса 2. Соответственно, в тесте мы проверим, что у нас был запрос в этот сервис. Потому как схема, может, например, быть неактуальной. Команда доработала какие-то фичи, что-то сделала и запроса в сервис может не быть. Нам этот момент необходимо выяснить, мы вешаем туда мок и в тесте проверим, что запрос в сервис 2 действительно был.

Таким образом мы можем настроить моки под каждую ветку. И вот что интересно: для каждой ветки комбинация моков и возвращаемых параметров будет индивидуальна. При помощи комбинации входных данных и моков мы можем однозначно задать нужную ветку обработки данных. И если в данном случае, например, для ветки 3 мы не устанавливаем мок для запроса в сервис 1, а у нас по каким-то причинам ветка пошла именно по этому пути, то тест однозначно свалился, потому что мок-сервер ничего нам не ответит и что-то пойдёт не так и явно вывалится с ошибкой.

Настройка моков

Какие есть нюансы настройки моков?

Первое это уникальные настройки для каждой ветки. То есть мы настраиваем не просто мок, мы также настраиваем и тело ответа (не во всех случаях, см. примеры выше).

Далее мы имеем как минимум два варианта для настройки мок-сервера.

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

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

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

Основное достоинство настройки моков непосредственно в тесте заключается в том, что мы не зависим от входных данных и перед каждым тест-кейсом у нас очищены и определённым образом настроены мок-серверы. Мы точно знаем, какие эндпоинты у нас есть на заглушке, а каких нет. Мы сразу видим, на каком запросе у нас тест свалился.

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

А что же дальше? А дальше автоматизация!

Я вас не буду грузить кодом. Реализовать автоматизацию можно по-разному, в зависимости от инструментов, которые вы предпочитаете.

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

Здесь представлена схема запуска теста. Мы используем кастомный фреймворк на базе TestNG, и в тесте у нас обрабатываются все NG-шные аннотации. Мы дописали дополнительную аннотацию @Wiremock, которая отвечает за настройку мока. В ней всего два параметра: имя файла с JSON-настройками для мока, и логический параметр чистить или не чистить мок-сервер (хост мок-сервера задается в настройках окружения). То есть при очистке мы просто удаляем какие-то настройки, которые у нас были до старта теста. Если в этом нет необходимости или у нас гоняются какие-то тесты параллельно, мы их просто оставляем и дописываем либо перезаписываем наши настройки.

Тестирование

Давайте посмотрим также на процедуру тестирования наших логических схем. Ниже представлена блок-схема теста:

Мы отправляем запрос в тестируемый сервис, проверяем его ответ, а также (при необходимости) тело ответа. Здесь нет никакой валидации запросов в мок-сервер, постольку поскольку логические схемы с запросами к интегрируемым сервисам, после которых нет постобработки и ветвлений, у нас достаточно редки. Если это необходимо, мы добавляем дополнительно проверку вот таких висячих запросов (был или не был произведен), и на этом тест заканчивается. Здесь проявляется плюс настройки моков перед тестом нет нужды проверять, куда у нас действительно были запросы, в какие эндпойнты с какими параметрами. Комбинация однозначна либо тест свалился, если была попытка произвести несипользуемый в ветке запрос, либо по схеме был произведен нужный запрос, тестируемый сервис достучался в мок и получил нужные данные.

Напоследок поговорим про асинхронные схемы.

Здесь единственное отличие только в цикле ожидания (нужен при ожидании требуемого в тесте статуса тестируемого процесса. Ну и дополнительно имитация действий интегрируемых сервисов. Т.е. выполняем запрос, получаем ответ, проверяем, что у нас схема запустилась. Дальше ждём нужного статуса, имитируем какие-то действия и проверяем, что у нас получилось.

Что же в итоге?

  1. Мы выяснили, что подход Control Flow Testing применим для тестирования логики наших сервисов.

  2. Он замечательно работает как на синхронных, так и на асинхронных схемах, и мы можем его успешно применить.

  3. Отличный инструмент для анализа логических схем их табличное представление (когда мы разбиваем схемку на ветки и анализируем, каким образом у нас происходит запрос с какими параметрами)

  4. Моки наше всё, потому как настраивая моки определённым образом, мы можем выбрать конкретную тестируемую ветку и делаем возможным тестирование по методике Control Flow Testing.


Q&A

Как вы организуете хранение преднастроек моков? Интересует кейс, когда есть одна фишка и очень много комбинаций. Используете ли инструмент генерации или храните в сыром виде?

Сейчас мы тестируем новый инструмент генерации. До этого использовали настройку именно перед тестом. Просто закидывали JSONы, которые у нас хранились рядом с тестом. Сейчас делаем генерацию. Что касается преднастроенных моков, мы решили проблему следующим образом: для подобных тестов и микросервисов мы с командой соорудили несколько вариантов сервера в Wiremock с преднастройками. И раскатываются они у нас один раз, автоматически, при деплое. То есть мы какие-то изменения вносим, запускаем джобу в Jenkins, и у нас всё автоматом раскатывается по серверам, никаких настроек менять не нужно. Для тех тестовых окружений, где уже используются эти моки, это проходит бесшовно. Если что-то необходимо добавить, мы просто добавляем это в репозиторий с настройками и раскатываем в Wiremock. Всё. Здесь никакой магии.

Проводите ли функциональное тестирование в живой среде без моков?

Пока да. Единственное, что мы от этого сейчас отказываемся в пользу изолированных сред. Поскольку команда у нас становится всё больше и больше, IT в Leroy Merlin динамично развивается и поддерживать какую-то такую живую среду, хотя бы отдалённо похожую на прод, становится накладно. Это занимает огромное количество времени, поэтому мы уходим в сторону изолированного тестирования. Но пока есть.

Философский вопрос: по ощущениям насколько это трудозатратный способ? Не слишком ли много времени придётся потратить на составление таблиц?

Производство фичи с разветвлённой логикой без таблиц с исключительно компонентными интеграционными тестами занимает, условно говоря, какой-то период времени допустим, месяц. При использовании подхода с таблицей, методики Control Flow Testing, мы умудрились как минимум в два раза сократить время выкатки фичи, и я подозреваю, что это не предел. Мы с коллегами сейчас разрабатываем поэтапное проектирование логических схем, где стараемся свести количество итераций по изменению и доработке самой логики до максимум двух. То есть да, можно ускориться, и это действительно очень и очень помогает в разработке. Мы можем таблицу использовать как документацию в конечном счёте. Здесь очень много нюансов, об этом можно говорить долго, но да, это действительно ускоряет разработку.

Насколько зависимы будут результаты тестов сервисов при мокировании других сервисов? Вы как-то задаётесь этим вопросом?

Да, мы задаёмся этим вопросом. Сейчас для таких схем мы начинаем применять дополнительно контрактное тестирование.

Сколько времени в среднем уходит на поддержку моков?

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

Насколько затраченное время эквивалентно пользе от таких табличек? Находят ли они баги? Помогают ли они найти баги на этапе проектирования, дают ли уверенность разрабам, что всё ок?

Они дают уверенность нашим тимлидам, что всё ок, это точно. Разрабы, я думаю, тоже довольны. То, о чём я сейчас рассказывал в докладе реальный кейс, хоть схемы и утрированы. И мы, как только начали применять подобный подход, действительно сходу нашли несколько багов только в одной схеме. С учётом того, что нашем микросервисе порядка 17 эндпоинтов с такими схемами и половина из них сейчас не покрыта вот такими тестами да, это очень сильно улучшит качество нашего сервиса. И да на этапе проектирования это позволяет отлавливать баги. Но это, скорее, не баги, а валидация требований, выраженных в логической схеме. Можно так ответить.


Запись видео можно посмотреть здесь:


QA Meeting Point - бесплатная онлайн-конференция для всех, кто занимается тестированием ПО и его автоматизацией: QA-специалистов и разработчиков. Своими болями и успехами делятся инженеры из разных городов России. Сейчас уже можно подать доклад на конференцию, которая состоится осенью 2021.

Подробнее..

23 июня, 1900 онлайн-митап QAчественное общение

15.06.2021 14:10:21 | Автор: admin

Привет!

Вы уже догадались по названию, какой теме будет посвящен этот митап.

В целом, всё как всегда онлайн, бесплатно, но надо зарегистрироваться заранее (на почту получите ссылку на трансляцию, а потом ещё и запись, если вдруг некогда будет смотреть онлайн).

Меняется лишь состав спикеров и обсуждаемые вопросы. Вот они:

19:05 19:35, Контрактное тестирование Rest API

Семен Ковалев, старший специалист по тестированию, Альфа-Банк

Семен расскажет отом, что такое контрактное тестирование, иразберет простой пример контрактного теста наPostman.

19:35 20:05, Структурированный подход к организации тестов

Анна Сотниченко, специалист по тестированию, Альфа-Банк

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

20:05-20:35, Построение модели Onboarding в QA

Иван Боклач, руководитель группы тестирования,Альфа-Банк

Подключайтесь, будет интересно.

Подробнее..

Джуном? в 40-к лет? Ещё и на удаленку? Да ну, не выдумывайте

24.03.2021 00:15:52 | Автор: admin

И все-таки это возможно...

..., в 40 лет выучиться топтать кнопки и этим зарабатывать, но путь к этому тернист, сложен, неоднозначен, сами придумайте какое-нить сложное определение, непростой и нелегкий. Если Вы уверены, что готовы к нему - то вы однозначно его пройдете!

Вообще таких success stories в интернетах полным-полно, помните как таксист учил Java на перекурах, курьер слушал подкасты на велике, хирург... уж не помню, когда хирург умудрялся учить ООП, но похоже делал он это вместе с таксистом и курьером.

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

Да-да, я именно тот 40-летний джун, которому удалось попась на удаленку и среднюю зарплату в не очень крупную, но гордую контору... Хотите узнать как это получилось?


Глава 1: что мы имеем?

Прекрасно, когда вам 15-ть... считай жизнь только начинается... и 25-ть... девушки, тусовки... и 35-ть... кажется, как много уже сделано...

Мой случай, сложнее... 40 лет, жена и дети, родители-пенсионеры, дом и хозяйство, собака и кошка, мыши и тараканы, работа в кровавом энтерпрайзе по 10 часов/день и полное отсуствие времени...

Да, энтерпрайз давал зарабатывать приемлимые деньги, но постоянное погружение в болото (хоть и теплое) бюрократии, под управлением гибкой методологии "Я начальник, ты - раб", оттачивание мастерства по придумыванию на ходу отмазок и отговорок; умение в пол-глаза и пол-руки наваять до 12-ти (кстати, реальное число) версий объяснительных по одной проблеме... все это..., угнетало...

Я же в конце концов специалист, инженер, ИТ-шник, Телеком-щик, кто угодно, но не тот, кем меня заставляют быть!

Таким образом, перед началом этого самого тернистого пути, из плюсов у меня было только 15 лет ИТ/Телеком опыта (который успел подрастеряться) и старый служебный ноутбук для программирования старых служебных УАТС.

Глава 2: начало...

Решение принято, надо двигаться - вспоминать/повышать квалификацию, но с чего начать? Кто спрятал рецепт счастья? Где пархает эта синяя птица удачи?

А ещё надо решать вопрос, где брать на все это время... ведь работу то бросать нельзя - все хотят кушать и куклы LOL... На работе - работаешь..., наняты специальные люди, которые за зарплату следят как ты работаешь, тут в образование не вложишься...

Выход один - придется снова жертвовать сном...

Не буду подробно утомлять читателя муками выбора специализации, но взор упал на "попробовать Python" и на "почитать про QA" (на самом деле, просто потому что Python просто "попер", а QA очень отдаленно пересекался с работой в энтерпрайзе)...

Глава 3: и как все это учить?

Все это учить можно в Интернете и бесплатно... Звучит классно, но - не работает...

Информации в этих ваших Интернетах настолько много, что, лучше бы ее не было вообще... ну или просто поменьше...

При любом более-менее релевантном поисковом запросе, тебя раздивает на части реклама, которая уверяет, что в твоей жизни уже все прекрасно, осталось перевести все-лишь какие нить n*10 тысяч рублей вот по этим реквизитам (и это уже с 30% скидкой, надо же как повезло), и буквально после наших месячных курсов, HR-ы из FAANG будут мыть тебе ноги в надежде привлечь твое внимание...

А как же традиционный для нашей страны особый путь? Надо найти возможность и учиться бесплатно... Что в результате получилось:

  • Видосики в Youtube - отбросил, потому как засыпаю... Плюс тяжко разбираться, какая инфа актуальная, какую технологию уже давно все забыли... Дальше видосиков не шло, кнопки не понажимать...

  • Подкасты - почти сразу после начала, голоса авторов перекрывал мой храп.

  • Книги - тоже рубит, сухое повествование убаюкивало ещё в студенческие времена...

Все это на самом деле тоже достойные источники, но мне нужно больше золота практики...

Зашли курсы от www.codecademy.com и немного www.datacamp.com, пока там можно писать код бесплатно...

Так, синтаксис примерно понятен, прохэллоувордились, дальше что? И из FAANG что-то все никак не звонят...

А потом произошло странное... на одном из курсов я осознано написал неправильный код, который прошел ревью... И тут начало приходить понимание...

Глава 4: хорошее ревью - стоит денег, ревью от ментора - бесценно.

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

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

Выбор программ основывался на следующих условиях:

  • много практики, чем больше тем лучше, и только выжимка теории (читайте по про метод сломанной пирамиды);

  • ревью... ревью живого человека, у которого можно спросить, с которым можно поспорить;

  • кейсы приближенные к коммерческим, поменьше виртуальности;

  • комьюнити таких же дураков джунов как я...;

  • бюджет побюджетнее..., действительность корректирует хотелки.

И да, я нашел таких ребят! И да, я НЕ назову их здесь!

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

Ревью настолько жесткие, что после каждого возвращенного, т.е. считай не выполненного, задания чувствуешь себя побитой собакой и понимаешь как много ты ещё не знаешь... Зато как круто ощущать себя, когда после ревью просят поправить только очепятки...

А ещё комьюнити... Можно перетереть с такими же как ты, учениками/студентами, с преподами, и даже с основателями/евангелистами всей этой кухни!

Все классно, прокачка шурует, взбираемся на гору знаний, пора применять знания на практике..., но где ж ее взять? Это проблема номер раз..., вторая небольшая проблемка вылезла из-за повышения сложности заданий на курсах. Задания делаешь дольше и логично, что их ревью затягивалось.

Появлялись паузы, которые было решено заполнять реальными тестовыми заданиям от работодателей.

А что... наваяем на коленке резюме, закинем на несколько бирж, и будем просить тестовые задания... Я прям так и писал "вряд ли я буду у вас работать, но если есть возможность, пришлите тестовое, пожалуйста.

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

Половина работодателей присылала тестовые, а половина от присланных - давали обратную связь и рекомендации.

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

Все требовали того самого коммерческого опыта разработки... Который никак не получишь, не поработав в той самой коммерческой разработке...

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

Грустно пробежав по строкам мессаги от рекрутера, даже особо не дочитав пишу "Коммерческого опыта нет от слова совсем, тестовое готов сделать. Время тратить?". На удивление рекрутер не сдался и предложил сделать тестовое, хотя бы ради обратной связи...

Тестовое сделал вечером, отправил ещё позже и... через 20 минут я получаю приглашение на второй этап... Ну вот те на...

На следующий день, меня собеседует ведущий разработчик и проджект менеджер. Технических вопросов практически нет, к коду в тестовом претензий нет, придираться не хотят... Тестят soft-скилы...

Ещё удивительнее было через пару дней... прилетела обратка от давно отправленного тестового... ещё один офер :).

Послесловие.

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

Про QA: Я рассказал, про то как познавал Python и ни слова о QA. Исправляюсь... разрешите посоветовать труды Святослава Куликова, уж очень доступно все изъясняет... Спасибо ему за бескорыстный труд!

Про английский язык: Он просто необходим... У меня дружба с ним не клеялась и сейчас если и склеена то на сопли и слезы...

При супруге, знающей в совершенстве английский и немецкий, очень стыдно бэкать и мэкать в попытках что-то перевести и тем более сказать. Стандартные методы обучения снова не для меня, здесь на удивление, помогла юношеская страсть к литературной фантастике... Прочитать в оригинале, то что читал в детстве в переводе - это круто. Кто тоже так считает, welcome на english-e-reader.net.

Про контору, которая учит меня писать код: Не хочу, чтобы пост считали рекламным, но готов ответить на все вопросы в личке.

Про контору, которая забрала меня к себе писать код: Меня пригласили писать тесты на PyTest, Selenium и допиливать какие внутренние библиотеки. Сам ещё не знаю с какой стороны подойти к той пиле, которой должен буду допиливать...

Всем удачи! А мне пора писать код... :).

Подробнее..

Какв Ozon пришли к релизам мобильных приложений раз в неделю

23.05.2021 16:04:26 | Автор: admin

Несколько лет назад вOzonмежду двумя релизами приложения на одной платформе могло пройти три месяца.Мы планировали, что хотим выпуститься с определенной большой фичей и пока еёне сделаем не релизим.

С чем мы столкнулись, пока выпускали релизы по этой схеме:

  1. Сложно спрогнозировать, когда выйдетфича.Ок,мы как-топрикидывалисроки, ночембольшебыл разрабатываемый функционал, тем сложнееточно оценить срок.Трекатьпрогресс фичитоже не очень удобно, потому что оно там делается,и промежуточныебилдыс чем-то готовым для посмотретьсложнособирать.

  2. Долгоправитьбаги.Вкоде они могутбыть исправленыбыстро. А вотдо пользователейфиксдоходит уже вместе с той самой глобальной фичей.

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

  4. Долго релизить мелкие фичи. Какие-то улучшения могут занимать немного времени на разработку, но быть важными для пользователей и бизнеса. Точно так же, какисправления багов в пункте выше, для релиза они будут ждать того монстра, которого мы пилимтримесяца.

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

  6. Многохотфиксов. Чем больше число и объем изменений, тем сложнеебудет найти все баги перед релизом. Вот и появляютсяхотфиксы. Ещёза такой долгий срок разработки может прилететь какая-то очень срочная фича, ждать нельзя надо срочно выпускать(например, поддержать разрешение на отслеживание или добавить что-то по срочному рекламному контракту).

Проблеммного,и они все значимые. Когда бизнеспришёл к нам и сказал, что надо релизить быстрее мы уже ожидали этого. Но не ожидали, что они скажут: Релизьте раз в неделю.

Мы в шоке, как это реализоватьнепонятно.Мы в шоке, как это реализоватьнепонятно.

Тут у насслучиласьстадия отрицания:Мы не успеем всёпроверить, никаких фичей в релиз не попадет, Apple ревьюит о-го-госколько.Зачем, почему, может,не надо?.В ответ мы услышали: Релизы раз в неделю.

Сокращаем время выпуска релиза: первая попытка

Решили, что надодвигаться к целиитерационно.

Сначала научитьсявыпускать релизхотя быкопределённойдате. Первой попыткой был план успетьзарелизитьза месяц. Условно,мы решили 1 мая, что следующий релиз должен выйти 1 июня.

Ок, дата есть. Прикинули, что неделя уходит на регресс. На разработку остается три недели. Запланировали работына весь срок девелопмента.

Параллельно решили начать писатьавтотесты. Ну, как начать. У нас и до этого они были, но пользы не ощущалось. Поняли, что пора их встраивать в процессы.

Идёт первый месяц. Работаем. Пилим фичи, тестируем. Все заряжены.Но в итоге получили: тотобъём работ, который запланировали разработать за три недели, закончили под конецчетвёртой. Стали искать, где же выиграть время,нашли только один варианттестирование. Как могли, сократили регресс, но всёравно нашлинесколько критичных багов. В итогев зависимости от платформы с релизом опоздали на неделю-полторы.

Вторая попытка: нужно что-то менять

Да, мы решили, что нужны изменения. Но поменяли не процессы, а... сроки. Раз тяжело планировать на месяц давайте запланируем релизчерездве недели! Меньше успеем сделать фичей, быстрее проведем регрессионное тестирование - проще будет запланировать объем работ.

Тем временемтестировщикипродолжают писатьавтотесты

Пробуем всёравно каждый раз не успеваем.

Стали анализировать,из-за чегоне выходит уложиться в срок:

  1. Неправильно оцениваем время на разработку.

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

  3. Продактыпоздно вносятпоследниеправки в ТЗ.

  4. Не учитываем время на починкубагов.

У нас был план:то, что не готово к началу тестирования в релиз неидёт. Но он не сработал.Приходилипродактыи говорили, что две недели ждать следующего релиза они не могут. Потомуходиливыше,и оттуданамговорили, что, да, надо доделать.

И тут пришлиQA.Сказали, что при двухнедельных релизахскоупнеособосократился.

Разработчиков много, они разделены по разномуфункционалуи задвенедели успеваютнакомититьпрактически во все компоненты. Стало понятно, что несмотря на то, что мыНИ РАЗУне успели в срок ни при месячном релизе, ни при двухнедельных пора двигаться дальше.

Недельные релизымыидём к вам!

Прежде всего надо было составить календарь наших действий на неделю. По разработке получилось так:

Понедельник

Релизная ветка

Вторник

Фичи

Среда

Фичи

Четверг

Фичи

Пятница

Фиксы багов

Фичиуходятвсвои фича-ветки. И когда она полностью сделана, проверена, принятапродактом, тогда уже попадает вdevelop.

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

Получается, что где-то в среду-четверг должен начаться процентныйроллаутприложения.

Меняемся в тестировании

Чтобы всёэто поддержать со стороныQA, пришлось ротировать обязанности тестировщиков по неделям. Одну неделю тестер проверяетфичи, вторую занимается написанием кейсовиавтотестов,участвует врелизномтестировании.При этомрелизноетестирование получилось сократить где-то до дня на каждую платформу.

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

Чтобы разработка не зависала на начальных этапах, мы выработали требования кфиче, которуюберём в работу у неёдолжныбыть в наличии

  1. Дизайн;

  2. Бекенд;

  3. Контракт.

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

Дальше встал вопрос о том, когда же можно включатьфичув релиз. Получились такие правила:

  1. Бекендфичидолжен быть напродакшене.

  2. К началурелизноготестирования нет критичныхбагов(ни на фронте, ни набекенде).

  3. Дляфичиестьфичефлаг, которым в любой момент можно закрытьфункционал. По версии платформы, по версии приложения, по дате, на определенную группу пользователей как угодно.

Меняемся в разработке

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

Ещёмы постоянно автоматизируем процессы, чтобы разработчикам надо было меньше отвлекатьсяна какие-то рутинные вещи,и они могли сконцентрироваться на разработке.

Тикетавтоматом двигается по статусам. Запушилкоммит перешел вinprogress.Создалmergerequest перешел вcodereview.ПрошелreviewпопалвQA.

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

По каждой сборке запускаютсяUI-автотестыпозатронутомуфункционалу.Это тоже определяется самопо измененным файлам вmergerequest.В результате репорт попадаетвкомментарийтикета вJira.

Дажеmergerequestна влитие эпика вdevсоздаётсяпросто по принятию продактом фичивJira.Если нет конфликтов, то и вливается сам.Релиз сам закрывается, а новый самсоздаётся.

QA Notes

Ещёмы ввели требования к разработчикам писатьQANotes.Там указывается:

  1. Что было сделано.

  2. Что могло быть задето.

  3. Приложены скриншоты или видео.

  4. На какой среде удалось проверить.

  5. Для багаещёпричина, из-за чегосломалось(в идеалетикет, которыйпривёл к такому поведению).

QANotesпозволили значительно ускоритьтестированиеиревьюкода. А ещёдали нам скрытый бонус:пропалиреопеныотQAиз-закрешейна старте.

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

Автотестыраньше находят баги. Теперь не надо ждатьрелизноготестирования, чтобы увидеть проблемы после интеграции. Прогоныавтотестовпроисходят после каждоговливания эпика вdev,а такжекаждуюночь. Еслинадо, то можно запустить на эпик-веткедо вливания вdev. Раньше нашли баг раньше исправили.

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

А еще добавиласьротируемаяроль QAза релиз.Этоттестировщикгде-то раз вдватримесяцаделаетповторяющиесявещи:

  1. Составляет наборрелизныхтестов.

  2. Распределяет нагрузку команды тестирования пофичам. Если видит, что у одних сейчас малотикетов, а другие не успевают может перекинуть кого-то в помощь.

  3. Напоминаеттестировщикампосмотретьотчёты поавтотестамнарелизномбилде.

  4. Пушитпересборкурелиз-кандидатов, если что-то добавилось.

  5. После релиза неделюмониторитпаденияи отвечает на запросы поддержки.

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

Автоматизация помогает контролировать стабильность среды с помощью выполнения тестов после изменения кода приложения:

Мы также проверяем, что новыеавтотестыне ломают существующие:

Новая схема релиза мобильных приложений

У нас стало значительно меньшехотфиксов.Релизы теперь чаще впять-десять раз, но хотфиксим мы реже, чем раньше.Причины две.Во-первых,получается делать более стабильные релизы.Во-вторых, если это не что-то невероятно критичное, то фикс, скорее всего, сможет подождать неделю до следующего релиза.

Теперь мы спокойнее переносимфичи. Неприятно, когда не успели, но перенос выхода фичи на неделю воспринимается спокойнее, чем на более долгий срок.

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

И главное. Мы теперьукладываемсяв сроки. Всегда. С первой попытки выпустить релиз за неделю мы успели это сделать. И с тех пор вот уже два года приложениеOzonобновляется раз в неделю, принося новыефичи, исправления ошибок.

Какиеестьсложности

В первую очередь этонепростойрефакторинг. Когдавмерживодинкоммит, вам надо перепроверить всёприложение.Сейчас мы прежде всеговливаемтакое по понедельникам-вторникам, чтобырефакторингмаксимально настоялся вdev, накрутилсяавтотестамии был потроган при тестированиифичей.

Ещё однасложностьпраздники,из-за которых рабочая неделя из пяти дней сокращается дочетырёх. Тут появляется больше риска,т.к.обычно мырелизимнатретий-четвёртыйдень после отрезаниярелизнойветкииостаётсяещёдень на мониторинг.Тогда какздесь обычно релиз происходит уже в последний рабочий день. Спасибо, фичефлагами процентной раскатке.

Что ещёможно улучшить

Прежде всего хочется научиться ещёраньше раскатывать билды на пользователей. Найти тестовыесегменты, на которые можно катить до началарелизноготестирования. Но это рискимиджевыхи денежныхпотерь.Такихсуперлояльных пользователейнам ещё только предстоитпоискать.Если вдруг вамможет быть этоинтересно пишите, добавим вас в сегмент бета-тестировщиков.

Ещёмы никогда не останавливаемся в автоматизации процессов. Постоянно находим возможность убрать ручную рутину. И покрываемавтотестамивсёбольшефункционала.

Для себя мы выработали такие шаги, на которые надо пойти, чтобы завести у себя релизы раз в неделю:

  1. Строгие требования к готовностифичи.

  2. Приоритет напереоткрытыхтикетах.

  3. Весь функционалзакрытфичефлагами.

  4. Строгое расписание релизов.

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

Подробнее..

Гайд по тестированию рекламы для мобильных приложений

15.06.2021 18:13:51 | Автор: admin

Тестировать рекламные механики не так просто, как может показаться. Главные действующие лица здесь сторонние SDK, которые не особо подконтрольны команде разработки. А так как рекламные интеграции важная часть наших мобильных приложений, то ниже вместе с @maiscourt и @santypa расскажем, как мы это делаем.

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


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

Но получение тестовой рекламы требует изменения определённых параметров в наших экспериментах, обращения к тестовой админке медиатора, добавления тест-мода (специальные параметры, чтобы партнёр понимал, что запрашивается именно тестовый креатив), использования своей дебаг-панели, а также VPN по странам, а в отдельных кейсах по городам.

И тут нам понадобятся некоторые инструменты.

Инструменты

Ниже список инструментов, которые мы используем при тестировании рекламы, а потом перейдём к задачам.

  1. Сниффер для анализа трафика (у нас Charles).

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

  3. Своя админка с фича-тогглами, где можно включить/отключить, или изменить наши эксперименты.

  4. Наша дебаг-панель.

  5. VPN.

  6. Внешние гайдлайны.

  7. Внутренняя база знаний и Confluence для её хранения.

  8. Чек-листы.

  9. Zephyr для хранения тест-кейсов.

Пройдёмся по каждому.

Инструмент 1. Charles. Активно используется не только тестировщиками, но и разработчиками. Практически все задачи требуют замены продакшн параметров на тестовые. Например, часто возникает необходимость добавить в конфиг эксперимент или обращаться к тестовым юнитам медиатора.

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

Инструмент 2. Тестовая админка медиатора. Медиатор это специальная платформа, которая позволяет подключать приложение сразу к нескольким рекламным сетям, а также управлять показом рекламы (например, Google AdMob, Fyber и другие). Ещё во время онбординга мы проводим обучающие курсы по рекламе, где сотрудники в тестовой админке медиатора создают свой тестовый юнит для настройки параметров рекламы под себя.

Инструмент 3. Админка с фича-тогглами. Практически все рекламные (и не только) механики в приложении iFunny закрыты под фича-тогглы (механизм реализации, при котором часть кода прячется за флаг, контролирующий его включение или выключение). Это нужно, чтобы сделать более надёжным и безопасным выпуск той или иной функциональности.

Чтобы получить нужный для тестирования конфиг, мы используем нашу админку с фича-тогглами или подменяем параметры, используя Charles. А эксперименты помогают понять, какая из запущенных гипотез является наиболее оптимальной. Всё это есть в нашей админке, которая хранит данные и управляет ими по всем фичам и экспериментам.

Документацию обновляем и дополняем по мере необходимости: если после обновления SDK изменилась описанная логика работы, или если вышли нормативы/регламенты, требующие внесения обязательных правок.

Инструмент 4. Дебаг-панель. Для удобства разработали свою рекламную дебаг-панель, которая представляет собой отдельный интерфейс и в большинстве случаев позволяет локально на клиенте настроить необходимые параметры, заменяя собой практически все инструменты, описанные выше.

Инструмент 5. VPN. В основном используется для проверки задач, связанных с GDPR и CCPA. Для тестирования GDPR подходит VPN с возможностью получения IP европейской страны. Для тестирования CCPA необходим VPN с возможностью получения калифорнийского IP.

Инструмент 6. Внешние гайдлайны. В работе с рекламными SDK часто используем их официальную документацию, где можно получить:

  • рекламные креативы и их идентификаторы, которые используются для настройки и получения тестовой рекламы;

  • форматы запросов и ответов рекламной SDK, а также параметры, из описания которых понимаем, за что они отвечают, и какие возможные значения для них допустимы;

  • changelog изменений рекламных SDK чтобы понять, на какие изменения при обновлении SDK нужно обратить внимание во время тестирования.

Инструмент 7. Внутренняя документация. Внешние гайды не всегда являются достаточно подробными. Кроме того, проверка одной и той же функциональности от разных SDK требует переключения между разными источниками для поиска необходимой информации. Поэтому оказалось удобным агрегировать информацию из разных гайдлайнов SDK и делать сборную внутреннюю документацию в нашем Confluence, дополняя её своими комментариями.

Инструмент 8. Чек-листы. Наравне с внешней и внутренней документацией для проверок различных задач используем чек-листы (пример можно посмотреть ниже в разделе про обновление SDK). Для такого типа задач, как проверка обновлений SDK, обновлений медиатора или адаптеров, мы используем уже составленный чек-лист, который изменяется по мере необходимости.

Для остальных задач составляем чек-листы либо в процессе разработки задачи, либо непосредственно перед тестированием, в зависимости от сложности задач.

Инструмент 9. Тест-кейсы. Тест-кейсы неотъемлемая часть тестирования любого проекта/функциональности, в том числе рекламы. Тест-кейсы разделены по приоритетам, что позволяет использовать risk-based testing, о котором будет рассказано подробнее ниже. В тест-кейсах фигурируют такие проверки, как загрузка и показ рекламы, запросы на рекламу, работа разных механик (например: водопад, аукцион), а также запрос и отображение рекламы от партнёрских рекламных сетей. Данные проверки в полной мере позволяют убедиться, что рекламный функционал работает без сбоев/корректно.

Задачи

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

Разберём, с чем приходится сталкиваться на постоянной основе:

  1. Обновление SDK.

  2. Тестирование форматов.

  3. Безопасность.

  4. Регрессионное тестирование.

  5. Смоук тестирование.

  6. Другие задачи (юридические вопросы, локализации, эксперименты, аналитика, рефакторинг и так далее).

Задача 1. Обновление SDK. Можно сказать, что обновление SDK наиболее популярная задача в рамках тестирования рекламы. Из-за частого проведения тестирования обновлений SDK (а также медиатора или адаптеров) составили чек-лист проверок:

  • Вёрстка. Проверяем всё: центрирование, размер, отображение на устройствах с разными разрешениями экранов.

  • Пользовательские сценарии. Тап по контенту/кнопке и по privacy icon, возврат в приложение, воспроизведение и остановка видеорекламы.

  • Репорт (отправка жалоб, связанных с рекламой). Пользователь может пожаловаться на рекламный контент или сообщить о технических проблемах.

  • Соответствие стандартам GDPR и CCPA.

  • Отправка аналитики. Внутренняя и внешняя (партнёру и медиатору).

  • Технические проверки. Например, уход в фон во время загрузки рекламы.

Задача 2. Тестирование форматов. Баннерная и нативная рекламы у нас закрепились и работают стабильно, но мы пробуем интегрировать и другие виды, в частности, fullscreen-рекламу. В целом, тестирование Rewarded Video и Interstitial во многом схоже с тестированием других видов: проверяется корректная загрузка и отображение рекламы, а также отправка аналитики.

Ключевым в проверке fullscreen-рекламы является её отображение на разных по диагонали экранах, например, на смартфоне и планшете. Важно, чтобы появившаяся на экране реклама не перекрывалась другими элементами, и по завершению таймера скрывалась автоматически или тапом по крестику, возвращая пользователя в исходную точку приложения:

Отдельно нужно сказать про механику Rewarded Video после окончания просмотра рекламы (или просмотра до определённой временной метки) пользователь должен получить вознаграждение. Поэтому очень важно хорошо протестировать этот функционал.

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

Задача 3. Безопасность. Чтобы следить за качеством трафика, интегрировали в iFunny внешнее антифрод-решение. В него для дополнительной проверки атрибуции показов и кликов на каждое событие генерируется новое. На стороне системы с помощью технологий машинного обучения и большого объёма накопленных данных происходит дальнейший анализ. Со своей стороны мы проверяем отправку и разметку событий для разных сетей и разных типов рекламы.

Задача 4. Регрессионное тестирование. Раз в две недели iFunny релизится на iOS и Android. Независимо от количества рекламных задач, попавших в релизную ветку, мы проводим регрессионное тестирование рекламного функционала/блока. В регрессионных паках собраны следующего рода проверки:

  • Основные проверки, что реклама запрашивается и отображается на нужных экранах приложения.

  • Работа нативной и баннерной рекламы, а также рекламных сетей, с которыми сотрудничаем по сути, это упрощённый чек-лист, используемый для тестирования SDK (добавления, обновления).

  • Работа разных механик: водопад и биддинг (что это такое, можно ознакомиться здесь).

  • Проверка на соответствие юридическим нормам.

  • Проверки каких-то наших внутренних разработок (например, эксперименты с дизайном).

Если встречаем проблемы в процессе тестирования (не проходят какие-то кейсы регресса), то чиним в текущей релизной ветке не катимся с рекламой, которая не работает.

Проведение полного ручного прогона регресса занимает порядка 2-3 дней. Поэтому, чтобы сократить время прохождения регресса, используется практика проведения Risk-based testing (вид тестирования, основанный на вероятности риска). Суть такого тестирования исключить некоторое количество тест-кейсов из прогона, проведение которых не может выявить потенциальных ошибок на текущем релизном билде. Иными словами, кейс не имеет смысла включать в регрессионное тестирование, если при разработке не был затронут функционал, проверяющийся в кейсе.

Задача 5. Смоук тестирование. Перед тем, как выкладывать сборку в сторы, а также при тестировании хотфиксов, мы прогоняем смоук тесты. В рамках смоук тестирования реклама проверяется, но не так детально, как при регрессе. Мы тестируем основные моменты, связанные с рекламой, а именно её загрузку и отображение.

Задача 6. Другое. К тестированию других задач можно отнести:

  • юридические задачи, например, связанные с GDPR и CCPA;

  • задачи локализации (для пользователей iFunny из Бразилии);

  • эксперименты, связанные с дизайном рекламы;

  • задачи аналитики;

  • рефакторинг, оптимизации. Например, оцениваем доступный нам для анализа контент на предмет валидности.

Бонус. Онбординг новых сотрудников

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

Всё обучение делится на два блока. Первый блок состоит из лекций о базовых знаниях, что такое водопад и аукцион; каким образом приложение получает рекламу и какие действия происходят при её обработке; какая бывает аналитика и по каким триггерам собираются события. Краткое содержание этих лекций можно найти здесь.

Во втором блоке рассказывается о том, какие рекламные механики работают в iFunny. Здесь теоретический материал подкрепляется практикой каждый участник семинара учится получать определённый вид рекламы от наших партнёров и работать с необходимыми инструментами. Практические задания курса образуют своего рода задачник. Прорешав его, можно с уверенностью приступать к реальным задачам из бэклога.

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

Вместо заключения

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

Подробнее..

Перевод Как тестировали в 2020 технологии QA, общемировая статистика и тренды

19.03.2021 16:09:40 | Автор: admin

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

Кому будет полезно: QA-лидам, тест-дизайнерам, тест-менеджерам, другим неравнодушным.

Тенденции инструментов тестирования

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

  • Согласно отчету PractiTest, 47% опрошенных тестировщиков используют инструменты для тестирования или обеспечения качества, такие как HP ALM, Team Foundation Server, PractiTest или Xray.

  • Согласно отчету JetBrains, 44% разработчиков регулярно используют баг-трекинговые инструменты, а 10% используют инструменты для проверки кода, такие как Collaborator, Review Assistant или CodeScene.

  • Самым распространенным баг-трекером остается Jira (68%). На втором месте GitHub Issues (26%).

В исследовании Russia Quality Report от Performance Lab за 2020 год говорится, что Jira в качестве TMS используют 73% российских компаний, 29% применяют Excel. Свои разработки в этой сфере применяют 13% опрошенных.

Что касается инструментов автоматизации, в совместно подготовленном исследовании QATestLab и Test IT говорится о том, что наиболее популярными для веб-тестирования являются Selenium и Apache JMeter, для API Postman.

К слову, у Test IT есть своя одноименная разработка система управления тестированием, в которой удобно вести документацию, а также создавать, запускать и анализировать ручные и автотесты. Ребята активно завоевывают российский и зарубежный рынок.

Тенденции методик тестирования

Быстрота выпуска продукта на рынок остается приоритетным критерием для оценки тестирования и одной из главных целей QA. Без методологии тестирование похоже на бесцельное блуждание в направлении релиза вы думаете, что куда-то идете, но не можете ни к чему приблизиться, потому что не можете отслеживать прогресс. Обратите внимание на нижеперечисленные тенденции методик тестирования ПО, чтобы выбрать подходящую.

  • Самая распространенная модель тестирования разработки программного обеспечения Agile или нечто похожее на Agile: 87% компаний использовали этот подход в 2019 году. Следующим шагом был DevOps с показателем 36% по сравнению с 28% в 2018 году (по данным PractiTest).

  • 82% компаний используют исследовательское тестирование в качестве методологии тестирования программного обеспечения, а 61% используют обычную проверку на основе сценариев (по данным PractiTest).

  • 78% организаций используют автоматизацию тестирования для функционального и регрессионного тестирования. Только 11% компаний не автоматизируют тесты (по данным PractiTest).

Рост популярности Agile в России, впрочем, не означает, что отечественные компании перестали сталкиваться с проблемами при внедрении в практику гибких методологий разработки. Согласно исследованию Russia Quality Report, чаще всего опрошенные указывали на невозможность применения автоматизации тестирования в необходимом объеме. Еще 17% респондентов отметили недостаточное понимание подходов Agile к тестированию.

Нельзя умолчать и о популярности DevOps подхода: тестирование в среде DevOps выполняется на каждом этапе разработки на небольших частях системы. Специалисты пишут больше интеграционных тестов, сокращая циклы разработки. CD естественный процесс доставки изменений, что только улучшает ситуацию для QA, уменьшая количество изменений на тестируемых сборках.

Тенденции разработки ПО

Тестирование неотъемлемая часть жизненного цикла разработки ПО, поэтому тенденции разработки сильно влияют на тестирование. Понимание последних трендов разработки сильно помогает тестировщикам и руководителям QA сузить поиск ошибок. Если вы тестировщик, то приведенные ниже современные тенденции в разработке программного обеспечения помогут вам стать еще более эффективными.

  • Наиболее востребованным языком программирования на сегодняшний день является Rust (83,5%), за ним следует Python (73,1%). Разработчики больше всего не любили VBA (75,2%), а Python хочет изучить 25,7% опрошенных программистов (StackOverflow).

  • 25% сотрудников мировой IT-индустрии считают, что самая большая проблема, стоящая перед стартапами, приоритизировать разработку ПО (CodingSans).

  • Безопасность горячая тема: 69% респондентов отметили, что разработчики должны уметь писать безопасный код, но 68% считают, что добрая половина разработчиков не может самостоятельно обнаружить уязвимые части кода, которые обнаруживаются позже (GitHub).

Тенденции тестирования ПО

Известно, что процесс обеспечения качества включает в себя все от стратегического планирования и общения с разработчиками до документирования ошибок и других проблем; тем не менее главная часть QA это непосредственно тестирование.

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

  • Тестировщики часто выполняют работу за рамками своей роли в компании. 74% тестировщиков также пишут сценарии и делают автоматизацию, 57% также выполняют тесты управления данными (PractiTest).

  • В 35% компаний тестирование может проводить кто угодно, кроме тестировщиков, но 55% компаний все же используют профессиональных тестировщиков для подавляющего большинства тестов (PractiTest).

  • Web по-прежнему является самой популярной платформой для тестирования, 77% тестировщиков работали над web-тестированием в 2019 году. Это меньше, чем 79% в 2018 году (PractiTest).

Также важной частью QA-процесса является нагрузочное тестирование.

Тенденции QA-команд

Работать в команде всегда лучше, чем поодиночке вспомните притчу про веник и прутья. Четыре человека могут найти больше багов (и быстрее), чем один, и зачастую неважно, насколько этот один крут. Если вы являетесь QA-лидом, приведённые ниже тенденции возможно помогут вам в оптимизации вашей команды для достижения наилучших результатов.

  • Сложности: 44% тестирующих команд назвали сложным или невозможным участие в проектах своей компании в начале процесса, в то время как 43% командам трудно работать с данными и тестовыми средами (PractiTest).

  • Состав: 48% QA-команд состояли из 1-5 сотрудников, а 24% имели от 6 до 15 тестировщиков в 2019 году (PractiTest).

  • Задачи: по статистике, 63% задач команд по тестированию связаны с анализом требований, 55% задач связаны с ретроспективными встречами по проектам.

Карьерные тенденции в QA

Если вы читаете этот текст, скорее всего, вы работаете в области обеспечения качества, либо заинтересованы в этом. Если вы в поиске работы, вам следует кое о чем знать, прежде чем приступить к активным действиям. Как люди приходят в QA? Некоторые оказываются в профессии далеким от привычного способом.

  • Только 18% тестировщиков планировали стать тестировщиками ПО и изучали процессы. 24% стали тестировщиками случайно (PractiTest).

  • 65% получили знания о тестировании ПО в процессе самого тестирования. 58% читали книги по тестированию, а 44% закончили курсы и получили профильные сертификаты (PractiTest).

  • 75% отметили важность коммуникативных навыков, 63% назвали необходимым умение писать тестовые сценарии и умение автоматизировать тесты (PractiTest).

Тенденции дефектов ПО

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

  • Баг-репорты являются наиболее распространенной тестовой документацией, используемой компаниями 79% пользователей отмечают их использование (PractiTest).

  • 76% тестировщиков использовали баг-трекеры, такие как Jira Bugzilla или Redmine, что делает их наиболее распространенным инструментом управления тестированием. Следующим по популярности инструментом был Agile Workflow tools (59%) (PractiTest).

  • Наиболее распространенной ошибкой на проде было выкатывание непроверенного или сломанного кода более чем на 60%. Второй наиболее распространенной ошибкой была удаленная база данных (HackerRank).

Наряду с тестированием на наличие программных ошибок, тестировщики также проводят тестирование баз данных.

Другие тенденции QA

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

  • В 2019 году 36% тестировщиков были подотчетны PM, по сравнению с 43% в 2018. 34% тестировщиков отчитывались перед руководителем отдела разработки (PractiTest).

  • 73% разработчиков заявили. что научились программированию самостоятельно, чуть меньшее количество училось разработке на курсах или в университете (69%) (HackerRank).

  • На 100 тыс. человек приходится 5,2 тестировщиков. В Ирландии самый высокий процент тестировщиков на душу населения 61,2 на 100 тыс. человек. Далее следуют США и Канада, затем в списке Израиль (QualiTest Group).

Согласно исследованию Russia Quality Report, в России большинство работодателей не считает, что профильное образование в сфере IT или дополнительные сертификаты так уж необходимы тестировщику. Значение придается наличию у соискателя опыта работы (в среднем - 1-3 года) и таким личным качествам, как внимательность, ответственность и дотошность.

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

Помните, баги всегда прячутся в самых неожиданных местах. Удачи!

Перевод статьи

Автор: Nuala Turner

Также при подготовке использовался источник RQR2020 и исследование QATestLab и Test IT

Подробнее..

Как QA в управлении хранилища данных эволюционировал. Часть 2

19.03.2021 18:12:20 | Автор: admin

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

Итак, поехали!

Проблемы прошлого

Для начала вспомним, какие же проблемы остались актуальными:

  • Ручной сбор пакета разработчиками.

  • Ручное ревью пакета.

  • Необходимость в синхронизации продуктового и тестового контуров.

  • Недоступность операций над метаинформацией при возникновении очереди.

  • Отдельный контур для тестирования интеграции.

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

Три тестовых контура (vial, live и test)

Я уже писал про vial и live серверы для проведения модульного и регрессионного тестирования ETL-процессов. Они позволили отделить эти виды тестов, но старый test-контур при этом никуда не делся и использовался для интеграционного тестирования пакета, уже прошедшего модульное тестирование на vial. Кроме того, ряд задач невозможно было протестировать на vial в силу различных обстоятельств, и с ними по-прежнему работали на test.

Было: все тестирование на одном контуре.

Стало: модульное и интеграционное тестирование, а также регресс разнесены по разным контурам.

Распределение этапов тестирования между контурамиРаспределение этапов тестирования между контурами

Таким образом:

  • тестовых контуров стало больше;

  • test по-прежнему использовался.

Зачем нужен test?

Во-первых, test был нужен для проведения интеграционного тестирования. Успешное прохождение модульного тестирования не означало, что пакет полностью корректен и никак не сломает остальные объекты хранилища. Например, разработчик мог, скажем, поправить длину какого-то поля в таблице и в метаинформации, и на этапе модульного тестирования это никак бы не отразилось, а зависимый ETL-процесс мог быть завязан на старое значение и при изменениях падал. Это можно отловить только при интеграционном тестировании.

Во-вторых, ряд задач просто нельзя было на тот момент тестировать на vial по разным причинам. Например, бэкапы для некоторых таблиц нельзя (или очень проблематично) было перенести на vial с prod. Поэтому их тестировали на test.

Хорошо, с важностью и необходимостью testа разобрались.

А в чем были проблемы с test при текущем flow с тремя тестовыми контурами?

Оказывается, проблем было несколько:

  • необходимость синхронизаций с продом;

  • конфликты задач;

  • деградация данных.

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

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

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

Давайте рассмотрим решения проблем при помощи наших разработок, и начнем с проблемы ручного сбора пакетов.

Текущие реалии

НастоящееНастоящее

Мы шаг за шагом улучшали наши процессы и создавали новые инструменты, развивая их. Постепенно переходили к автоматизации. Остановимся на этом подробнее.

Составляющие автоматизацииСоставляющие автоматизации

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

Портал автоматизации

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

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

Отображение пакета на портале автоматизацииОтображение пакета на портале автоматизации

Какие функции предоставляет портал автоматизации?

  • Автоматический сбор пакета.

  • Накаты задач на все контуры.

  • Большой пул работ с метаинформацией.

  • Управление Демонами.

  • Ревью.

  • Управление релизом.

На портале автоматизации у разработчика появилась возможность собрать свой пакет автоматически. Причем, если задача не содержит специфических объектов и действий, на лету создается пакет с типовым содержимым и сценарием. А если сценарий по данной задаче содержит специфические действия, то на портале есть функционал создания сложного сценария работы с объектами хранилища данных и наката.

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

Автотестер

Итак, автотестер это совокупность нескольких демонов, создающих готовые vial-окружения без каких-либо ручных действий со стороны сотрудников.

Автотестер запускает накаты задач ежедневно в 20:30, поскольку в это время нагрузка на тестовый контур резко снижается и работы автотестера никак не будут блокировать работу сотрудников. Он берет все задачи, которые успешно прошли ревью и по которым в Jira указан уровень тестирования автоматическое. Такой уровень тестирования проставляется у всех задач, для которых не предполагаются ручные действия во время наката. А далее запускает процесс создания пробирок.

Автотестер создает чат с разработчиком и QA и в случае возникновения ошибок окружения (моргнула база, кончилось место или же в самом пакете вылезли ошибки, которые не были выявлены на ревью) отправляет туда лог ошибки.

Пример slack-канала и сообщения об ошибке в немПример slack-канала и сообщения об ошибке в нем

После успешного переноса задачи на vial запускаются автотесты и сравнения текущих и предыдущих версий целевых таблиц, а также чекеры целостности данных. Результаты всех этих проверок автотестер отправляет в тот же slack-канал.

Результаты автопроверок в slack-каналеРезультаты автопроверок в slack-канале

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

Авторевью

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

  • занимает много времени;

  • невозможно отследить глазами выполнение абсолютно всех требований.

Меню запуска ревью на портале автоматизацииМеню запуска ревью на портале автоматизации

Большое количество проверок было просто вынесено в отдельный сервис, который запускается для проверки созданного пакета и выдает свой вердикт о его качестве. Далее ревьюверу остается проверить логи с результатами авторевью и самые критичные требования к объектам из задачи. То есть ревью стало двухфакторным и проходит гораздо быстрее.

Например, на этапе авторевью можно быстро отловить использование в ETL-процессах хардкода вместо макропеременных или же увидеть, что ETL-процесс работает очень долго, поэтому необходимо его оптимизировать.

Рассмотрим основные категории проверок в рамках ревью.

Meta-review

Работа с метаданными объектов хранилища осуществляется в SAS Data Integration Studio. Метаданные физически хранятся на SAS-сервере и представляют собой таблицы атрибутов и таблицу связей их используем для автоматизации. После внесения разработчиком изменений в метаданные, происходит запрос на SAS-сервер по объектам, которые были затронуты доработкой.

По названию объектов выстраиваются связи и находятся необходимые для анализа атрибуты в виде таблиц, которые, в свою очередь, подвергаются проверкам на предмет соответствия стандартам разработки. Под стандартами разработки в данном случае можно понимать соответствие объектов внутренним соглашениям по разработке, особенности работы с GP, особенности работы связанных систем. В результате работы авторевью пользователь получает отчет со списком выявленных проблем.

Package-review

Результат разработки опубликованный в VCS релиз-пакет, который содержит в себе все файлы, необходимые для установки задачи, а также файлы, свидетельствующие о корректности разработки.

Package-review запускается для проверки наполнения релиз-пакета. Проверяется наличие всех необходимых файлов, соответствие конфига и содержания пакета, корректность создания или изменения физической структуры объектов, производится парсинг скриптов, сопоставление объектов, дорабатываемых в скриптах, с объектами метаданных. В результате работы package-review пользователь получает отчет со списком объектов релиз-пакета, не прошедших проверки, и рекомендации по устранению проблем.

Diff-review

Запускает python-скрипт, выполняющий сравнение деплоев джобов до и после разработки и создающий diff-файлы.

Log-review

Выполняет проверку логов в пакете.

Автотесты

На крупных проектах в целях автоматизации тестирования пишутся собственные тестовые фреймворки, и наш проект не исключение. На связке python + pytest создан наш тестовый фреймворк, позволяющий:

  • Запускать автотесты на всех объектах по задаче.

  • Выполнять часть тестовых проверок на лету, запуская самописные тестовые функции.

  • Формировать итоговый отчет с результатами тестирования в Allure.

У запуска автотестов есть особенность: их перечень зависит от объектов тестовой задачи. Например, при создании нескольких абсолютно новых ETL-процессов интеграционные проверки запускаться не будут, поскольку в хранилище еще нет никаких зависимостей от этих процессов. И наоборот: при доработке существующих процессов будут запускаться интеграционные проверки.

Какие виды тестов во фреймворке существуют?

  • Static включают проверки хардкода, корректности метаинформации и настроек инкрементальной загрузки ETL-процесса.

  • BI проверяют зависимости в SAP BO юниверсах.

  • Интеграционные тесты проверяют возможные ошибки в зависимых ETL-процессах хранилища и в важных отчетах.

  • Work проверяют что корректно отработала инкрементальная загрузка новых/измененных данных из источников, обновились данные и так далее.

Интеграционное тестирование

В этом направлении мы совершили огромный прорыв и очень им гордимся.

Итак, интеграционное тестирование прошло следующие этапы:

  • Ручной запуск всех зависимых процессов на тестовом контуре.

  • Вынесение части проверок в авточекер и выполнение их автоматически.

  • Расширение перечня автопроверок и переход к накату на тест только метаинформации.

Апогеем этой эволюционной лестницы стал полный отказ от интеграционного контура. Почему это удалось?

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

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

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

Попутно были достигнуты следующие результаты:

  • Влияние человеческого фактора на итоги интеграционного тестирования уменьшилось в разы.

  • Время интеграционного тестирования сократилось на 8090%.

  • Качество самих интеграционных проверок улучшилось за счет максимально актуальных данных.

Качество проверок улучшилось, потому что на тесте не всегда были актуальные данные, да и зависимости в BI и важных стратегических отчетах ранее мы не могли проверить, а с приходом автоматизации это стало реальным.

Выполнение проверок на лету

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

Какие функции у нас есть?

  • ddl(имя_таблицы) возвращает DDL-скрипт создания таблицы, используемый для проверки корректности метаинформации и соответствия ее ТЗ.

  • profile(имя_таблицы) сводный отчет наполняемости таблицы (насколько заполнено каждое поле таблицы, какие уникальные значения есть в различных полях и т. д.).

  • dq_check(имя_таблицы, ключ) позволяет определить, сколько дублей и NULL есть в ключевых полях таблицы, а также выявить проблемы версионности.

  • compare_(таблица1, таблица2, ключ) самый основной инструмент, выдающий результаты сравнения двух таблиц.

Compare() показывает, сколько столбцов и строк в каждой таблице, сколько строк сджойнилось и в каких столбцах были обнаружены расхождения для сджойненных записей.

Ниже показано, что все записи из первой и второй таблицы (12987767 234 строки) сджойнились, но по полю order_id были обнаружены расхождения в 9458 234 строках.

Пример результата функции compare()Пример результата функции compare()

Если такое расхождение и предполагалось получить в результате доработки ETL-процесса все хорошо, если же оно неожиданно это повод для обсуждения с аналитиком и разработчиком.

При помощи функций compare() выполняются сравнения с прототипом и бэкапом. Они позволяют сравнить: полностью все таблицы, только актуальные версии записей или же отдельные партиции (для больших партицированных таблиц).

Тест-кейсы в Allure

В Allure тест-кейсы создаются автоматически и динамически, отталкиваясь от особенностей проверяемых объектов, так же, как тесты, о которых я писал выше. Кроме того, ряд проверок выполняется на лету в процессе наката задачи на vial, а их результаты сразу записываются в тест-кейсы.

Пополнение базы автотестов

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

Разработка собственных допсервисов

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

Разработка

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

Эта проблема затрагивала не только QA-инженеров, но и самих разработчиков. И для ее решения было предложено использовать отдельные метасерверы. На них с помощью плейбуков разработчики готовят окружение, разрабатывают свои задачи и проводят первичную проверку результата.

Далее задача отправляется согласно установленному flow.

Проблемы на данном этапе

Из оставшихся проблем были решены:

  • Необходимость в синхронизации продуктового и тестового контуров отпала после перехода на vial и автоматизацию интеграционного тестирования.

  • Ручное ревью пакета решено после введения авторевью. Полностью избавиться от ручного ревью не получится, но механизм авторевью значительно разгрузил сотрудников.

  • Имеется целых три тестовых контура теперь для тестирования используется только связка vial/live, причем live лишь для некоторых задач.

  • Для тестирования интеграции требуется отдельный контур контур больше не используется.

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

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

Но разработчики уже решили эту проблему в своем окружении, а в планах решить ее и применительно к QA.

Дорога к светлому будущему

Мы уже многое сделали для улучшения нашей работы, но нам еще многое предстоит.

Будущее прекрасное далекоБудущее прекрасное далеко

Какие же наши основные задачи?

  • Переход авторевью в разработку и поддержку на стороне QA.

  • Тестовые контуры переходят в зону ответственности QA в команду QA нанимается SRE.

  • Тестирование на отдельных метасерверах.

  • Разработка новых сервисов автоматизации.

Тестирование на отдельных метасерверах позволит избавить от зависаний меты на vial, но не все сразу. Впрочем, мы обязательно это сделаем.

А что касается новых сервисов автоматизации, то сейчас мы занимаемся написанием статистического анализатора результата регресса, анализатора корректности эталонного SQL-кода (этот код поддерживает в актуальном состоянии системный аналитик), на основе которого разработчики создают ETL-процессы, а также автоматизацией тестирования инкрементальной загрузки.

Заключение

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

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

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

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

Вот что было сделано:

  • Автоматизировано большое количество действий, выполняющихся ранее вручную: сбор пакетов, накат/откат задач, ревью, большая часть тестов и т. д.

  • Разработаны внутренние сервисы для ускорения и повышения эффективности работы с хранилищем:портал автоматизации, авторевью, автотесты и т. д.

  • Процессы непрерывно улучшаются за счет пополнения базы тестов, повышения стабильность автотестов.

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

Кроме того, QA наращивают техническую экспертизу за счет расширения обязанностей, взятия на себя все большего числа сервисов в поддержку и разработку. У нас много планов, и мы их обязательно реализуем. А о результатах расскажем в новых статьях.

Спасибо, заходите почитать про наше хранилище!

Подробнее..

Перевод Паттерны и Методологии Автоматизации UI Примеры из жизни

01.04.2021 16:06:37 | Автор: admin

Полезные паттерны для автоматизации тестирования UI

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

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

Паттерн Декоратор (Decorator)

Мой фреймворк должен поддерживать различные варианты компонентов веб-сайта. Это необходимо, потому что наше веб-приложение постоянно меняется, и A/B-тесты выполняются на уровне компонентов.

Если у вас есть подобное требование, паттерн Декоратор может вам подойти! Он позволяет упаковать компоненты в конверты, которые перезаписывают или дополняют только определенные функции. Вам не нужно писать новый класс для каждой новой характеристики компонента: должны быть реализованы только изменения. Вы также можете использовать этот метод, если веб-компоненты меняются в зависимости от размера браузера или типа устройства.

Пример Декоратора

В этом примере у нас есть два компонента Login. У второго есть дополнительная кнопка отменить.

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

Давайте посмотрим на это с точки зрения декоратора!

LoginComponent - это интерфейс для каждого компонента Login. В нем говорится, что каждый компонент должен иметь определенный метод login.

package decorator;public interface LoginComponent {   void login(String user, String password);}

BasicLoginComponent имеет конкретную реализацию метода login. В этом примере он просто выводит Basic login в командную строку.

package decorator;public class BasicLoginComponent implements LoginComponent {   @Override   public void login(String user, String password) {       System.out.println("Basic login: " + user + ", " + password);   }}

Этот класс является сердцем паттерна. LoginDecorator может брать любой LoginComponent и оборачивать его нужными функциями. После этого результатом остается LoginComponent.

package decorator;public abstract class LoginDecorator implements LoginComponent {   private final LoginComponent loginComponent;   public LoginDecorator(LoginComponent loginComponent) {       this.loginComponent = loginComponent;   }   @Override   public void login(String user, String password) {       loginComponent.login(user, password);   }}

MobileLoginDecorator переопределяет функциональность login новым классом, специфичным для мобильных устройств. Опять же, он просто выводит Mobile login, чтобы этот пример был коротким.

package decorator;public class MobileLoginDecorator extends LoginDecorator {   public MobileLoginDecorator(LoginComponent loginComponent) {       super(loginComponent);   }   @Override   public void login(String user, String password) {       System.out.println("Mobile login: " + user + ", " + password);   }}

CancelButtonDecorator может добавить функцию cancel в любой компонент Login.

package decorator;public class CancelButtonDecorator extends LoginDecorator {   public CancelButtonDecorator(LoginComponent loginComponent) {       super(loginComponent);   }   public void cancel() {       System.out.println("Click the cancel button");   }}

Теперь мы можем проверить, как все это работает!

package decorator;public class Main {   public static void main(String[] args) {   System.out.println("DECORATOR PATTERN");   System.out.println("=================");   // This is the basic login component   LoginComponent loginComponent = new BasicLoginComponent();   loginComponent.login("User", "PW");   // Let's turn it into a mobile login component.   loginComponent = new MobileLoginDecorator(loginComponent);   loginComponent.login("User", "PW");   // Finally, we can add a cancel functionality.   loginComponent = new CancelButtonDecorator(loginComponent);   ((CancelButtonDecorator) loginComponent).cancel();   }}

Результат всего этого:

DECORATOR PATTERN=================Basic login: User, PWMobile login: User, PWClick the cancel button

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

Page Object и Page Component

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

Однако, если страница содержит много функций, классы объектов страницы могут стать огромными и превратиться в сложный и хаотичный код. Здесь и появляется расширение объектов страницы: Page Component. Идея состоит в том, чтобы обернуть функциональность компонента в класс, а не всю страницу.

Пример Page Object

Это очень простой интернет-магазин, который включает поиск и список результатов найденных продуктов. Если вы реализуете это с помощью Page Object, результат может выглядеть примерно так, как этот класс WebshopPage.

package pageobjects;public class WebshopPage {   public void search(final String queryString) {       System.out.println("Enter " + queryString);       System.out.println("Click search button");   }   public void checkResultHeadline() {       System.out.println("Check if the headline is correct.");   }   public void checkResults() {       System.out.println("Check if there are search results.");   }}

Все действия, которые можно выполнить на этой странице, включены сюда. Мы можем проверить это с помощью простого Main класса.

package pageobjects;public class Main {   public static void main(String[] args) {   System.out.println("PAGE OBJECTS");   System.out.println("============");   WebshopPage webshopPage = new WebshopPage();   webshopPage.search("T-Shirt");   webshopPage.checkResultHeadline();   webshopPage.checkResults();   }}

Как и ожидалось, это дает нам следующий результат:

PAGE OBJECTS============Enter T-ShirtClick search buttonCheck if the headline is correct.Check if there are search results.

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

Пример Page Component

Здесь на помощь приходит Page Component. В нашем случае вы можете разделить страницу на два компонента: панель поиска и список результатов.

Класс SearchBar должен содержать только метод поиска.

package pagecomponents;public class SearchBar {   public void search(final String queryString) {       System.out.println("Enter " + queryString);       System.out.println("Click search button");   }}

Методы проверки заголовка результата и самих результатов относятся к ResultList:

package pagecomponents;public class ResultList {   public void checkResultHeadline() {       System.out.println("Check if the headline is correct.");   }   public void checkResults() {       System.out.println("Check if there are search results.");   }}

Есть еще WebshopPage, но в этой версии просто доступны два компонента.

package pagecomponents;public class WebshopPage {   public SearchBar searchBar() {       return new SearchBar();   }   public ResultList resultList() {       return new ResultList();   }}

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

package pagecomponents;public class Main {   public static void main(String[] args) {   System.out.println("PAGE COMPONENTS");   System.out.println("===============");   WebshopPage webshopPage = new WebshopPage();   webshopPage.searchBar().search("T-Shirt");   webshopPage.resultList().checkResultHeadline();   webshopPage.resultList().checkResults();   }}

Результат все тот же:

PAGE COMPONENTS===============Enter T-ShirtClick search buttonCheck if the headline is correct.Check if there are search results.

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

Паттерн Фабрика (Factory)

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

Однако у этого подхода есть серьезный недостаток. Поскольку каждый класс компонента должен быть известен фреймворку и каждый компонент должен совместно использовать дублированный код инициализации при его создании. С помощью фабричного класса можно реализовать один источник истины, который может создавать экземпляры каждого необходимого класса.

Пример Фабрики

Для этого примера мы можем расширить приведенный выше пример и использовать фабрику для создания компонентов.

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

package factory;public class Component {   public void initialize() {       System.out.println("Initializing " + getClass().getName());   }}

Каждый из перечисленных выше компонентов может быть унаследован от этого класса Component:

public class ResultList extends Component {    ...}public class SearchBar extends Component {    ...}

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

package factory;public class ComponentFactory {   public static Component getComponent(final String componentName) throws Exception {   System.out.println("Creating " + componentName + "...");   // Create a component instance for the passed in component name.   Component component;   switch (componentName){       case "SearchBar":           component = new SearchBar();           break;       case "ResultList":           component = new ResultList();           break;       default:           throw new Exception(componentName + " unknown.");   }   System.out.println("Component created: " + component);   component.initialize();   return component;   }}

Код Main класса не выглядит иначе, потому что WebshopPage по-прежнему отвечает за управление его компонентами.

package factory;public class Main {   public static void main(String[] args) throws Exception {   System.out.println("FACTORY PATTERN");   System.out.println("===============");   WebshopPage webshopPage = new WebshopPage();   webshopPage.searchBar().search("Berlin");   }}

Результат измененного примера:

FACTORY PATTERN===============Creating SearchBar...Component created: factory.SearchBar@3d075dc0Initializing factory.SearchBarEnter BerlinClick search button

Компонент запрашивается, создается и инициализируется должным образом.

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

Внедрение зависимости (Dependency Injection)

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

Как правило, программное обеспечение, использующее внедрение зависимостей, полагается на какую-то специализированную среду, такую как Spring или Guice, которая обрабатывает создание и внедрение объектов. Чтобы прояснить концепцию, в следующем примере фреймворк не используется.

Пример Внедрения зависимости

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

Это интерфейс LoginData, который должны реализовывать все наши экземпляры данных для входа. Он просто возвращает имя пользователя и пароль.

package dependencyinjection;public interface LoginData {   String getUserName();   String getPassword();}

Давайте рассмотрим две реализации: одну для реальных, а другую для фейковых данных для логина.

package dependencyinjection;public class LoginDataReal implements LoginData {   @Override   public String getUserName() {       return "Real user";   }   @Override   public String getPassword() {       return "Real password";   }}package dependencyinjection;public class LoginDataFake implements LoginData {   @Override   public String getUserName() {       return "Fake user";   }   @Override   public String getPassword() {       return "Fake password";   }}

Конструктор LoginPage принимает экземпляр класса LoginData и использует его в своем методе login. Таким образом, фактическое имя пользователя и пароль для использования не управляются самой страницей LoginPage, а вместо этого выбираются и вводятся извне.

package dependencyinjection;public class LoginPage {   private final LoginData loginData;   public LoginPage(final LoginData loginData) {       this.loginData = loginData;   }   public void login(){       System.out.println("Logging in with " + loginData.getClass());       System.out.println("- user: " + loginData.getUserName());       System.out.println("- password: " + loginData.getPassword());   }}

Единственная отсутствующая часть - это тестовый класс, который использует оба набора данных для входа.

package dependencyinjection;public class Main {   public static void main(String[] args) {   System.out.println("DEPENDENCY INJECTION");   System.out.println("====================");   LoginPage loginPageReal = new LoginPage(new LoginDataReal());   loginPageReal.login();   LoginPage loginPageFake = new LoginPage(new LoginDataFake());   loginPageFake.login();   }}

Этот класс создает две отдельные страницы входа в систему, которые отличаются только переданными данными входа. Запуск класса выводит следующее:

DEPENDENCY INJECTION====================Logging in with class dependencyinjection.LoginDataRealuser: Real userpassword: Real passwordLogging in with class dependencyinjection.LoginDataFakeuser: Fake userpassword: Fake password

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

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

И наконец: Две Методологии

Мы только что просмотрели много кода. Итак, давайте завершим эту статью чем-то совершенно другим: методологиями!

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

Не усложняй (Keep It Simple)

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

Вам это не понадобится (You Arent Gonna Need It)

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

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

Переведено командой QApedia. Еще больше переведенных статей вы найдете на нашем телеграм-канале.

Подробнее..

Какие вопросы ожидать на позицию автоматизатора и причем тут сортировка?

03.04.2021 16:09:23 | Автор: admin

Здравствуйте, коллеги.

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

Само собой, если вы проходите собеседование на позицию junior, от вас не будут требовать опыта и знаний по всем вопросам. Будет круто, если вы разбираетесь хотя бы в ~30% всего этого. От позиции middle я бы ожидал примерно ~50%-60% знаний перечисленных мною тем. Ну и далее по восходящей. :)

Кто такой автоматизатор?

Чтобы понять, какие вопросы вас ждут на позицию автоматизатора, прежде всего стоит определиться с повседневными задачами автоматизатора. Ведь именно на их основе хороший интервьюер готовит вопросы. Какой смысл спрашивать о том, с чем автоматизатор работать не будет? Хотя бывают и исключения, но об этом чуть ниже.

Я всегда люблю говорить, что автоматизация тестирования - это три направления одновременно. Чтобы заниматься этим эффективно необходимо:

  1. Разбираться в тестировании. Иначе не получится писать хорошие тесты, проверяющие именно то, что необходимо.

  2. Уметь программировать. Конечно, на первый взгляд тесты кажутся очень простыми. Последовательно вызываешь методы кликов, ввода значения и так далее. Но это неплохо работает только на небольшом количестве тестов, да и то если сам продукт меняется не слишком часто и работает стабильно. Чем больше тестов и сложнее продукт, тем больше опыта в программировании потребуется от автоматизатора для эффективной работы.

  3. Знать, как развернуть необходимый софт на серверах. Читай - немного понимать в системном администрировании или девопсе. Ведь тесты чаще всего запускаются в CI-системе, привязываются к Pull Requestам, а сам код запускается в Docker. И со всем этим надо уметь работать.

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

Тестирование

Обычные вопросы по тестированию чаще всего затрагивают теорию и практику.

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

Скорее всего спросят про знание устройства самого продукты, который вы будете тестировать. Например, если вам предстоит работать с Web, надо понимать как он работает: разбираться в протоколе HTTP, знать о связке HTML / CSS / JavaScript, понимать смысл кросс-браузерного тестирования и так далее.

Для тестирования мобильных приложений надо понимать основное отличие операционных систем iOS и Android, особенности тестирования на симуляторах, эмуляторах и реальных девайсах и многое другое.

Само собой, поскольку все это нам предстоит автоматизировать, еще необходимо разбираться в стеках автоматизации. Для автоматизации тестирования Web необходимо понимать как настроить Selenium или Selenoid, как подбирать CSS или XPath-локаторы для элементов, какие браузеры выбрать для тестов.

Для мобильной автоматизации пригодится знание драйверов (Espresso или XCUITest) или опыт работы с Appium. Умение настраивать ферму девайсов или устанавливать необходимые эмуляторы и симуляторы.

Для автоматизации API необходимо знать про методы HTTP-запросов (GET, POST, PUT, DELETE и т.д.) и их отличия, коды ответа сервера и их основные форматы (JSON, XML).

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

Недавно, к слову, я писал автоматическую песочницу, имитирующую подобную задачу на собеседовании. Кому интересно, потыкать ее можно тут.

Программирование

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

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

Чаще всего причина недовольства простая - мне это не нужно для работы. И в целом это правда. Не каждый день вы будете реализовывать методы сортировки самостоятельно. Тем более для написание тестов. Тогда зачем это спрашивают?

Я думаю, что ответ довольно простой. Потому что заставить писать кандидата полноценный тест долго и сложно. Во-первых, у всех кандидатов разный опыт работы с фреймворками. Кто-то пишет на Selenide, кто-то написал свою обертку, а кто-то на голом фреймворке Selenium. И это только Java. На других языках программирования свои фреймворки и их тоже может быть несколько.

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

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

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

Чаще всего человек, который действительно пишет много кода, справится с подобными задачами. Особенно если немного попрактикуется решать именно такие специфичные задачи. Для этого существуют такие ресурсы, как leetcode, codewars и прочие.

Обязательно стоит ожидать вопросы по ООП - что такое класс и экземпляр класса, что такое инкапсуляция, полиморфизм и наследование, какие бывают модификаторы доступа (в Java) и прочее.

Еще на собеседовании могут поспрашивать немного про паттерны программирования. Тут хорошо знать про Singleton, Factory, PageObject, PageFactory, Builder и так далее. Можно еще почитать про принципы разработки SOLID, KISS, DRY, SRP.

Девопс

Ну и заключительная часть - это работа с различным софтом и инструментами. Тут могут спросить с какой CI-системой вы чаще всего работали. На мой взгляд, самыми популярными являются Jenkins, Gitlab CI, TeamCity и Bamboo.

Помимо этого спросят про опыт работы с bash: команды cd, ls, ps, mv, cp и так далее. Просто, чтобы убедиться, что вы не растеряетесь, зайдя на какой-нибудь сервер на основе linux по ssh.

Еще могут быть вопросы по Docker - что такое образ, как запустить контейнер, как сделать маунт директории хост-машины, как собрать docker compose файл, как распространят образы между коллегами (docker registry)... Примерно так.

Скорее всего попросят решить какую-нибудь задачку на SQL-запрос. Он тоже довольно популярен и с ним приходится работать, например, при тестировании серверной части: баз данных, сервисов или API.

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

Итог

Само собой, это не полный список возможных тем на собеседовании. Всегда стоит ожидать совершенно любого вопроса на самые разнообразные темы.

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

Но есть и те, кто только недавно начал проводить собеседования. Такие ребята еще не до конца набили руку и могут попадаться вопросы, не всегда имеющие отношения непосредственно к задачам их будущего коллеги. Или даже не до конца сформулированные вопросы. К этому тоже стоит быть готовыми и не стесняться уточнять и задавать дополнительные вопросы. Не всегда, когда что-то непонятно, проблема может быть в вашем незнании темы. Порой еще и в неопытности того, кто эти вопросы задает. :)

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

Я думаю, про это я напишу как-нибудь в следующий раз.

Ну и минутка рекламы - приходите на наши курсы для тестировщиков. На них мы рассказываем многое как из этого списка, так и в целом о тестировании. Вся информация и ссылки в профиле. :)

А на этом все. Спасибо за внимание.

Подробнее..

Перевод Нагрузочное тестирование на Gatling Полное руководство. Часть 1

16.04.2021 20:09:46 | Автор: admin

Эта статья представляет собой полное, подробное и исчерпывающее руководство по эффективному использованию Gatling для нагрузочного тестирования. Вы также можете ознакомиться с моими видеоуроками по Gatling на YouTube, где я более подробно раскрываю эту тему.

Краткий обзор руководства

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

Первый раз слышите о Gatling? Тогда для начала уделите внимание моей вводной статье о Gatling. Но если в двух словах:

  • Gatling - это инструмент для нагрузочного тестирования с открытым исходным кодом, полностью написанный на Scala.

  • Простой и выразительный DSL, который предлагает Gatling, упрощает написание скриптов нагрузочного тестирования.

  • Он не содержит графического интерфейса (например, как JMeter), хотя поставляется с графическим интерфейсом для облегчения записи скриптов.

  • Он может обрабатывать огромный объем трафика на одном компьютере, устраняя необходимость в сложной распределенной инфраструктуре тестирования.

  • Проверку кода с помощью Gatling можно встроить в систему контроля версий и легко использовать в связке с инструментами непрерывной интеграции для запуска нагрузочных тестов и тестов производительности как части вашей CI-сборки.

Что такое тестирование производительности?

Прежде чем мы начнем, давайте вкратце разберемся, что такое тестирование производительности (performance testing).

Тестирование производительности - это тестирование, которое вы выполняете, когда хотите увидеть, как ваша система справляется с различными уровнями трафика и пропускной способности.

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

Существует несколько различных типов тестирования производительности, такие как:

  • Нагрузочное тестирование (Load Testing) - тестирование системы на заранее определенном объеме пользователей и трафике (пропускной способности);

  • Стресс-тестирование (Stress Testing) - тестирование системы под постоянно увеличивающейся нагрузкой, чтобы найти точку останова (breakpoint).

  • Тестирование стабильности (Soak Testing) - тестирование со стабильным уровнем трафика в системе на более длительном периоде времени для выявления узких мест.

Gatling подходит для всех этих подвидов тестирования производительности.

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

  • Время отклика транзакции (Transaction Response Times) - сколько времени требуется серверу, чтобы ответить на запрос.

  • Пропускная способность (Throughput) - количество транзакций, которые могут быть обработаны за определенный период времени.

  • Ошибки (Errors) - сообщения об ошибках, которые начинают появляться в определенные моменты нагрузочного теста (например, тайм-ауты).

Это исчерпывающее учебное руководство по нагрузочному тестированию на Gatling, разделенное на несколько разделов. Если вы новичок в нагрузочном тестировании на Gatling, я бы рекомендовал вам ознакомиться с каждый из разделов по порядку.

Исходный код

Вы можете найти весь исходный код из этого руководства в моем репозитории на Github.


1. Установка Gatling

Прежде чем начать что-либо делать, убедитесь, что у вас установлен JDK8 (или более новый). Если вам нужна помощь с этим, ознакомьтесь с этим руководством по установке JDK.

Самый простой способ установить Gatling - загрузить версию Gatling с открытым исходным кодом с сайта Gatling.io. Кликните Download Now, и начнется загрузка ZIP-архива:

Download GatlingDownload Gatling

Разархивируйте архив в любое место на вашем компьютере. Откройте полученную папку и перейдите в каталог bin. Оттуда запустите:

  • gatling.bat - если вы используете Windows

  • gatling.sh - если вы работаете на Mac или Unix

После окончания загрузки Gatling вам будет предложено выбрать симуляцию для запуска:

Choose Gatling Simulation to runChoose Gatling Simulation to run

Введите 0, чтобы выбрать computerdatabase.BasicSimulation. Вам будет предложено ввести описание запуска (run description), но это необязательно, и его можно оставить пустым.

Gatling запустит выбранный вами скрипт, который выполнит базовый нагрузочный тест на тестовом сайте Gatling с базой данных компьютеров.


2. Gatling Recorder

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

Как только вы овладеете Gatling (к концу этого руководства!), вы сможете писать скрипты с нуля в своей IDE или даже просто в текстовом редакторе.

Но прежде чем заняться этим, для начала вам будет проще использовать встроенный Gatling Recorder для записи вашего пользовательского пути (user journey).

2.1 Создание HAR-файла

Самый удобный способ использования Gatling Recorder, как мне кажется, предполагает генерацию HAR-файла (Http-архива) вашего пользовательского пути в Google Chrome.

Создание этих файлов и их импорт в Gatling Recorder позволяет обойти проблемы с записью на HTTPS.

Чтобы создать HAR-файл, выполните следующие действия:

  1. Откройте тестовый сайт Gatling с базой данных компьютеров - это сайт, с которого мы будем записывать пользовательский путь.

  2. Откройте Chrome Developer Tools и перейдите на вкладку Network.

  3. Кликните Clear, чтобы удалить все предыдущие сетевые вызовы, а затем убедитесь, что красная кнопка записи включена.

  4. Полистайте сайт, чтобы сгенерировать свой пользовательский путь - например, поищите какой-нибудь компьютер, создайте другой компьютер и т. д. Вы должны увидеть, что внутри вкладки Network начинают появляться новые записи.

  5. Кликните правой кнопкой мыши в любом месте вкладки Network и выберите Save all as HAR with content. Сохраните этот файл где-нибудь на вашем компьютере.

  1. Теперь перейдите в свою папку bin Gatling (в которой вы впервые запустили Gatling в предыдущем разделе) и запустите файл recorder.sh в Mac/Unix или recorder.bat в Windows. Загрузится Gatling Recorder.

  2. Измените Recorder Mode в правом верхнем углу на HAR Converter.

  3. В разделе HAR File перейдите к местоположению HAR-файла, созданного на шаге 5.

  4. Назовите свой скрипт, изменив Class Name на, например, MyComputerTest.

  5. Все остальное оставьте как было по умолчанию и кликните Start!

  6. Если все сработает так, как должно, вы увидите сообщение, что все прошло успешно.

Gatling Recorder screenshotGatling Recorder screenshot
  1. Чтобы запустить скрипт, вернитесь в папку bin Gatling и снова запустите gatling.sh или gatling.bat. После того, как Gatling загрузится, вы сможете выбрать только что созданный скрипт.

Если вы хотите посмотреть на только что созданный скрипт, вы можете найти его в папке user-files/simulations в вашем каталоге Gatling. Откройте скрипт MyComputerTest, который вы только что записали, в текстовом редакторе. Он должен выглядеть как-то так:

import scala.concurrent.duration._import io.gatling.core.Predef._import io.gatling.http.Predef._import io.gatling.jdbc.Predef._class MyComputerTest extends Simulation {val httpProtocol = http.baseUrl("http://computer-database.gatling.io").inferHtmlResources().userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36")val headers_0 = Map("Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","Accept-Encoding" -> "gzip, deflate","Accept-Language" -> "en-GB,en-US;q=0.9,en;q=0.8","Upgrade-Insecure-Requests" -> "1")val scn = scenario("MyComputerTest").exec(http("request_0").get("/computers").headers(headers_0)).pause(9).exec(http("request_1").get("/computers?f=amstrad").headers(headers_0)).pause(4).exec(http("request_2").get("/assets/stylesheets/bootstrap.min.css").resources(http("request_3").get("/assets/stylesheets/main.css")))setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)}

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


3. Настройка проекта Gatling

Итак, теперь, когда вы получили представление о том, как выглядит скрипт Gatling (и как с ним запустить нагрузочный тест), давайте приступим к настройке среды для создания наших скриптов. Первое, что нам нужно выбрать, это IDE:

3.1 Выберите IDE для создания скриптов нагрузочного тестирования на Gatling

Хотя вы вполне можете создавать скрипты Gatling в любом текстовом редакторе, гораздо проще (и эффективнее) делать это в IDE. В конце концов, мы будем писать код Scala. Scala работает поверх JVM, поэтому любая IDE, поддерживающая JVM, должна нам подойти.

У вас есть несколько вариантов:

  • Другой вариант, который (недавно) стал доступен, - это Visual Studio Code или сокращенно VS Code. Эта IDE последние несколько лет развивалась с головокружительной скоростью и стала популярной среди разработчиков множества различных технологических стеков. Ознакомьтесь с другой моей статьей Создаем Gatling скрипты с помощью VS Code для получения указаний по настройке.

  • Мой личный выбор, который я и буду показывать в этом руководстве, - это IntelliJ IDEA. Бесплатная версия достаточно хороша и поставляется со встроенной поддержкой Scala. Она идеально подходит для разработки скриптов Gatling.

Теперь, когда мы выбрали нашу IDE, нам понадобится система сборки, которая будет сочетаться с ней:

3.2 Выберите систему сборки для Gatling

Конечно, вы можете использовать Gatling без системы сборки и просто запускать его из первичных zip-файлов (как мы делали в первом разделе). Но есть вероятность, что вскоре вы все-таки захотите использовать систему сборки в своем проекте нагрузочного тестирования Gatling. Это упростит обслуживание в системе контроля версий. Опять же, у вас есть несколько вариантов на выбор:

Я расскажу о настройке нового проекта в IntelliJ Idea с Maven в оставшейся части этого раздела.

3.3 Создание проекта Gatling из архетипа Maven

Откройте терминал или командную строку и введите:

mvn archetype:generate

В конце, вы увидите этот запрос:

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains):

Введите gatling.

Затем вы должны увидеть:

1: remote -> io.gatling.highcharts:gatling-highcharts-maven-archetype (gatling-highcharts-maven-archetype)

Просто введите 1 для выбора архетипа Gatling. На следующем экране выберите последнюю версию:

Choose Gatling VersionChoose Gatling Version

Я ввел 35, чтобы выбрать версию 3.3.1 для этого туториала.

Для groupId введите com.gatlingTest.

Для artifactId введите myGatlingTest.

Для version просто нажмите ENTER, чтобы принять 1.0-SNAPSHOT.

Для package нажмите ENTER еще раз, чтобы принять в качестве имени пакета com.gatlingTest.

В конце введите Y, чтобы подтвердить все настройки, и Maven создаст для вас новый проект.

Следующее, что нужно сделать, - это импортировать этот проект в вашу IDE. Я импортирую проект в IntelliJ.

На стартовой странице IntelliJ выберите Import Project.

Import IntelliJ Gatling projectImport IntelliJ Gatling project

Перейдите в папку проекта, которую вы только что создали, и выберите файл pom.xml. Кликните open, и Intellij начнет импортировать проект в IDE за вас.

После того, как импорт проекта будет завершен, откройте панель Project Directory слева и раскройте папку src>test>scala. Дважды кликните по классу Engine.scala. Вы можете увидеть сообщение No Scala SDK in module вверху экрана. Если это так, нажмите Setup Scala SDK:

Import Scala SDK in IntelliJImport Scala SDK in IntelliJ

Проверьте, какие версии Scala у вас есть:

Scala versions in IntelliJScala versions in IntelliJ

Если у вас нет версии, указанной здесь, кликните Create, выберите версию 2.12 и кликните кнопку download:

ПРИМЕЧАНИЕ: Я НАСТОЯТЕЛЬНО рекомендую использовать версию Scala 2.12 с IntelliJ - 2.13, похоже, не очень хорошо работает с Gatling

Download Scala in IntelliDownload Scala in Intelli

В качестве альтернативы, если у вас возникли проблемы с загрузкой бинарников Scala через IntelliJ, вы можете вместо этого загрузить бинарники Scala непосредственно со Scala-lang. Кликните Download the Scala binaries, как показано на этом скриншоте:

Download Scala binaries from Scala-langDownload Scala binaries from Scala-lang

Сохраните бинарники где-нибудь на жестком диске и распакуйте ZIP-архив. Вернувшись в IntelliJ, снова кликните Setup Scala SDK, и на этот раз кликните Configure. Нажмите кнопку Add в левом нижнем углу:

Add the Scala binaries to IntelliJAdd the Scala binaries to IntelliJ

Перейдите в папку, которую вы только что загрузили и распаковали, и выберите папку lib:

Select the Lib folder to import Scala BinariesSelect the Lib folder to import Scala Binaries

Теперь в диалоге Add Scala Support вы сможете выбрать библиотеку Scala, которую вы загрузили:

Add Scala SupportAdd Scala Support

На этом моменте, вам также может потребоваться пометить папку scala как source root в IntelliJ. Для этого кликните правой кнопкой мыши по папке scala и выберите Mark Directory As -> Test Sources Root:

Mark Test Sources as Root in IntelliJMark Test Sources as Root in IntelliJ

На всякий случай также отметьте всю папку src как source root:

Mark Sources RootMark Sources Root

Наконец, кликните правой кнопкой мыши объект Engine и выберите Run:

Run the Engine Object in IntelliJRun the Engine Object in IntelliJ

Вы должны увидеть сообщение типа There is no simulation script. Please check that your scripts are in user-files/simulations. Так и должно быть, далее мы приступим к настройке наших скриптов нагрузочных тестов Gatling.

3.4 Добавление базового скрипта Gatling

Чтобы протестировать нашу новую среду разработки, давайте добавим базовый скрипт Gatling. Этот скрипт запустит тест на базе данных компьютеров Gatling.

Примечание: В оставшейся части этого руководства мы будем писать Gatling-тесты для пользовательского приложения, которое я создал для этого туториала... Сейчас же я просто хотел продемонстрировать простой скрипт для базы данных компьютеров Gatling, чтобы мы могли проверить, правильно ли настроена наша среда.

Кликните правой кнопкой мыши папку scala и выберите New > Scala Package - назовите пакет computerdatabase. Кликните эту папку правой кнопкой мыши и выберите New > Scala Class - назовите этот класс BasicSimulation. Скопируйте весь приведенный ниже код в новый класс:

package computerdatabaseimport io.gatling.core.Predef._import io.gatling.http.Predef._import scala.concurrent.duration._class BasicSimulation extends Simulation {  val httpProtocol = http    .baseUrl("http://computer-database.gatling.io") // Здесь находится корень для всех относительных URL    .acceptHeader(      "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"    ) // Вот общие заголовки    .acceptEncodingHeader("gzip, deflate")    .acceptLanguageHeader("en-US,en;q=0.5")    .userAgentHeader(      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0"    )  val scn =    scenario("Scenario Name") // Сценарий представляет собой цепь запросов и пауз       .exec(        http("request_1")          .get("/")      )      .pause(7) // Обратите внимание, что Gatling записал паузы в реальном времени  setUp(scn.inject(atOnceUsers(1)).protocols(httpProtocol))}

Теперь давайте запустим скрипт. Кликните правой кнопкой мыши объект Engine и выберите Run Engine. Gatling загрузится, и вы должны увидеть сообщение computerdatabase.BasicSimulation is the only simulation, executing it. Нажмите Enter, и скрипт выполнится.

Мы также можем запустить наш Gatling тест напрямую через Maven из командной строки. Для этого откройте терминал в каталоге вашего проекта и введите mvn gatling:test. Эта команда выполнит Gatling тест с помощью плагина Maven для Gatling.

Наша среда разработки Gatling готова к работе! Теперь нам нужно приложение, которое мы будем тестировать. Мы могли бы использовать базу данных компьютеров Gatling, но вместо этого я разработал API-приложение специально для этого туториала - базу данных игр!


В преддверии старта курса "Нагрузочное тестирование" приглашаем всех желающих записаться на бесплатный демо-урок в рамках которого рассмотрим интерфейс LoadRunner Virtual User Generator, запишем скрипт тестирования web-сайта, проведём его отладку и параметризацию. В результате вы научитесь создавать скрипты нагрузочного тестирования web-сайтов.

ЗАПИСАТЬСЯ НА ДЕМО-УРОК

Подробнее..

Перевод Нестабильные(Flaky) тесты одна из основных проблем автоматизированного тестирования

26.04.2021 10:24:01 | Автор: admin

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

Если вы не сталкивались с нестабильными тестами, обязательно прочтите эту статью, поскольку в ней делается попытка систематизировать причины возникновения нестабильности в тестах. Если вы сталкивались с нестабильными тестами, посмотрите сколько из них попадает в перечисленные области.

Данная статья призвана рассказать как бороться с каждой из причин.

За прошедшие годы я не раз сталкивался с нестабильными тестами, но вместо того чтобы рассматривать конкретные случаи, давайте попробуем сгруппировать причины возникновения нестабильности по задействованным при выполнении автотестов компонентам:

  • Сами тесты;

  • Фреймворк для запуска тестов;

  • Сервисы и библиотеки, от которых зависит тестируемая система и тестовый фреймворк;

  • Операционная система и устройство с которым взаимодействует фреймворк автотестирования.

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

Однако в распределенной системе каждая служба приложения и службы, от которых она зависит, могут находиться в другом аппаратном / программном стеке, как и служба, выполняющая тест. Это проиллюстрировано на рисунке 2 как полная среда выполнения теста

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

Сами тесты

Сами тесты могут вызвать нестабильность. Типичные причины:

  • Неправильная инциализация или очистка;

  • Неправильно подобранные тестовые данные;

  • Неправильное предположение о состоянии системы. Примером может служить системное время;

  • Зависимость от асинхроных действий;

  • Зависимость от порядка запуска тестов.

Фреймворк для запуска тестов

Ненадежный фреймворк для запуска тестов может привести к нестабильности. Типичные причины:

  • Неспособность выделить достаточно ресурсов для тестируемой системы, что приводит к ее сбою;

  • Неправильное планирование тестов, поэтому они "противоречат" и приводят к сбою друг друга;

  • Недостаточно системных ресурсов для выполнения требований тестирования.

Сервисы и библиотеки, от которых зависит тестируемая система и тестовый фреймворк

Приложение (или тестируемая система) может быть источником нестабильности

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

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

Типичные причины:

  • Состояние гонки;

  • Непроинициализированные переменные;

  • Медленный ответ или отсутствие ответа при запросе от теста;

  • Утечки памяти;

  • Избыточная подписка на ресурсы;

  • Изменения в приложении и в тестах происходят с разной скоростью.

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

Герметичная среда менее подвержена нестабильности.

Операционная система и устройство с которым взаимодействует фреймворк автотестирования

Наконец, оборудование и операционная система могут быть источником нестабильности тестов. Типичные причины включают:

  • Сбои или нестабильность сети;

  • Дисковые ошибки;

  • Ресурсы, потребляемые другими задачами / службами, не связанными с выполняемыми тестами.

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

В следующих статьях мы рассмотрим способы решения этих проблем.

Ссылки на источники

Подробнее..

Перевод Нестабильные тесты одна из основных проблем автоматизированного тестирования(Часть 2)

05.05.2021 08:04:43 | Автор: admin

Это продолжение серии статей о нестабильных тестах.

В первой статье(оригинал/перевод на хабре) говорилось о 4 компонентах, в которых могут возникать нестабильные тесты.

В этой статье дадим советы как избежать нестабильных тестов в каждом из 4 компонентов.

Компоненты

Итак 4 компонента в которых могут возникать нестабильные тесты:

  • Сами тесты;

  • Фреймворк для запуска тестов;

  • Сервисы и библиотеки, от которых зависит тестируемая система и тестовый фреймворк;

  • Операционная система и устройство с которым взаимодействует фреймворк автотестирования.

Это отображено на рисунке 1.

Причины, варианты локализации проблемы и варианты решения нестабильности обсуждаются ниже.

Сами тесты

Сами тесты могут быть нестабильными.

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

Таблица 1 Причины, варианты локализации проблемы и варианты решения нестабильности в самих тестах.

Причины нестабильных тестов

Варианты локализации проблемы

Варианты решения

Неправильная инициализация или очистка.

Ищите предупреждения компилятора о неинициализированных переменных. Проверьте код инициализации и очистки. Проверьте, что среда настроена и очищена правильно. Убедитесь, что тестовые данные верные.

Явно инициализируйте все переменные правильными значениями перед их использованием. Правильно настройте и очистите тестовую среду. Убедитесь, что первый тест не вредит состоянию тестовой среды.

Неправильно подобранные тестовые данные.

Перезапустите тесты самостоятельно.

Сделайте тесты независимыми от какого-либо состояния из других тестов и предыдущих запусков.

Неправильное предположение о состоянии системы. Примером может служить системное время.

Проверьте зависимости приложения.

Удалите или изолируйте зависимости вашего приложение от аспектов среды, которые вы не контролируете.

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

Логируйте время, когда были обращения к приложению. В рамках отладки добавьте задержки для проверки результатов прогона автотеста.

Добавьте в тесты элементы синхронизации, чтобы они ждали определенных состояний приложения. Отключите ненужное кеширование, чтобы иметь предсказуемый график ответов приложения. НЕ ДОБАВЛЯЙТЕ явные ожидания, это может привести к нестабильности тестов в будущем.

Зависимость от порядка запуска тестов (Вариант решения схож с второй причиной).

Перезапустите тесты самостоятельно.

Сделайте тесты независимыми от какого-либо состояния из других тестов и предыдущих запусков.

Фреймворк для запуска тестов

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

Таблица 2 Причины, варианта локализации проблемы, и варианты решения нестабильности в фреймворке для запуска тестов

Причины нестабильных тестов

Варианты локализации проблемы

Варианты решения

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

Проверьте логи, чтобы удостовериться появилось ли приложение.

Выделите достаточно ресурсов.

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

Запустите тесты в другом порядке.

Сделайте тесты независимыми друг от друга.

Недостаточно системных ресурсов для выполнения требований тестирования (Схоже с первым случаем, но здесь ресурсы потребляются во время выполнения рабочего процесса).

Проверьте системные логи, чтобы удостовериться не закончились ли ресурсы.

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

Сервисы и библиотеки, от которых зависит тестируемая система и тестовый фреймворк

Приложение (или тестируемая система) может быть источником нестабильности.

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

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

Таблица 3 Причины, варианта локализации проблемы, и варианты решения нестабильности в приложении или тестируемой системе

Причины нестабильных тестов

Варианты локализации проблемы

Варианты решения

Состояние гонки.

Логируйте доступ к общим ресурсам.

Добавьте в тесты элементы синхронизации, чтобы они ждали определенных состояний приложения. НЕ ДОБАВЛЯЙТЕ явные ожидания, это может привести к нестабильности тестов в будущем.

Непроинициализированные переменные.

Ищите предупреждения компилятора о неинициализированных переменных.

Явно инициализируйте все переменные правильными значениями перед их использованием.

Медленный ответ или отсутствие ответа при запросе от теста.

Логируйте время когда делаются запросы и ответы.

Проверьте и устраните все причины задержек.

Утечки памяти.

Посмотрите на потребление памяти во время прогона тестов. В обнаружении проблемы поможет инструмент Valgrind.

Исправьте программную ошибку вызывающую утечку памяти. В этой статье на wikipedia есть отличное описание этих типов ошибки.

Избыточная подписка на ресурсы.

Проверьте логи, чтобы узнать не закончились ли ресурсы.

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

Изменения в приложении и в тестах происходят с разной скоростью.

Изучите историю изменений.

Введите правило при изменении кода, писать на это тесты.

Операционная система и устройство с которым взаимодействует фреймворк автотестирования

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

Таблица 4 Причины, варианта локализации проблемы, и варианты решения нестабильности в ОС и устройстве с которым взаимодействует фреймворк автотестирования

Причины нестабильных тестов

Варианты локализации проблемы

Варианты решения

Сбои или нестабильность сети.

Проверьте наличие ошибок в системных логах.

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

Дисковые ошибки.

Проверьте наличие ошибок в системных логах.

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

Ресурсы, потребляемые другими задачами / службами, не связанными с выполняемыми тестами.

Изучите активность системного процесса.

Сократите активность процессов не связанных с прогоном тестов.

Заключение

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

Ссылки на источники

Подробнее..

Кто такой кросс-системный тестировщик и почему он не должен быть agile?

30.05.2021 18:13:46 | Автор: admin


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

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

Четыре пилотных проекта


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

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

Чтобы наладить эту работу, было решено запустить ряд пилотных проектов. Первым был проект тестирования промо-акций, которые наши коллеги тестировали на регулярной основе. Этот пилот позволил нам приступить к формированию базы знаний отдела (в Confluence было создано 137 страниц методических рекомендаций), а сотрудники начали работать с типовыми инструкциями а значит стали более взаимозаменяемыми.



Второй пилотный проект был организован полностью на базе и ролевой модели нового подразделения. Мы тестировали процесс формирования цифровых кодов товаров. Проект под названием Digital Content 2.0 продолжался 5 месяцев. Он затрагивал 15 систем, а для его реализации было разработано 114 тест-кейсов. В ходе этого пилота мы пришли к необходимости централизованного управления тестовыми средами и мастер-данными проектов и у нас была создана группа специалистов, поддерживающих работу всех команд в тестовой среде.



Третий пилотный проект MarketPlace выполнялся уже полностью самостоятельно, без участия подрядчика. Наша команда провела тестирование 15 систем, совместная работа которых позволила реализовать продажу товаров маркетплейса Goods на сайте М.Видео. Было разработано еще 209 тест-кейсов, но самое главное мы создали общий верхнеуровневый шаблон процесса кросс-системного тестирования, который можно было использовать на новых проектах.

В ходе MarketPlace мы начали вести тест-кейсы в Jira, собирать в удобной форме отчеты и статистику.



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

Четвертый пилот, после которого наша работа перешла в новое качество это тестирование мобильного приложения Эльдорадо. Тестирование под названием Eldo Mobile стало продуктовым то есть его заказчиком выступил не Projet Manager, а Product Owner. И хотя на этапе трехмесячного пилота мы протестировали только 16 связанных систем, новый подход позволил спланировать кросс-системное тестирование для каждого нового релиза мобильного приложения.

Работа подразделения кросс-системного тестирования сегодня


На сегодняшний день подразделение кросс-системного тестирования выступает внутренним поставщиком сервиса QA для владельцев продуктов и процессов. Нам поступают заявки от разных подразделений, а тест-менеджеры составляют план-график и распределяют задачи тестирования. Планирование происходит раз в неделю крупные и мелкие задачи распределяются между тест-менеджерами и тестировщиками, с учетом их загрузки и опыта.



Если происходит тестирование какого-то сложного процесса, тестировщик может всю неделю работать над одним и тем же проектом. В других случаях специалист успевает решить две или три задачи от разных заказчиков. Иногда тестировщик работает сразу с двумя тест-менеджерами, которые распределяют его время согласно динамическому цифровому графику.

Предварительно выстроенная методология подразумевает работу с типовыми тест-кейсами. Благодаря этому человека можно легко переключить с одной задачи на другую. В нашей работе это нередко оказывается необходимым, особенно, если что-то внезапно начало гореть, а по другим проектам дедлайн позволяет немного сдвинуть сроки.

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

Фактически, сегодня мы привносим методологию кросс-системного тестирования в уже сформированные agile-команды. Такой подход позволяет нам избегать постоянных согласований и проводить тестирование в четкие сроки.

Качества кросс-системного тестировщика


Даже когда вся разработка идет в ритме agile, кросс-системное тестирование остается по своей сути проектным, со всеми вытекающими потребностями в планировании, перераспределении ресурсов, причем как в каждой команде, так и внутри всей группы.

Дело в том, что условия работы кросс-системных тестировщиков и тест-менеджеров меняются постоянно. Например, недавно мы получили задачи на кросс-системное тестирование чат-бота, а также процесса оформления договоров по некоммерческим закупкам. Чтобы отработать эти задачи тестировщикам приходится включаться в новую сферу, разбираться в функционале и особенностях ранее незнакомых систем.

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

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

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

Тестирование продуктов


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

Мы заранее определяем, в какой момент времени и зачем команда кросс-функционального тестирования подключается к процессу и четко распределяем ресурсы тестировщиков.

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

Плюс централизованного подхода в том, что один тестер может работать сразу с несколькими проектами или продуктами. Например, мобильное приложение регулярно занимает 50 % времени у назначенных специалистов. Остальные 50 % они могут потратить на проверку других систем в соответствии с задачами тест-менеджеров.

Результаты работы нового подразделения


Мы еще не так долго живем в парадигме кросс-системного тестирования, но уже сейчас видно, что сроки проведения тестов стали короче (иногда в несколько раз), а качество тестирования выше.

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

Новая методика добавила прозрачности в работу всех команд и позволила повысить QA. Непрерывное накопление экспертизы и кросс-системная аналитика позволяют все более точно прогнозировать, какие изменения в одних системах могут повлиять на работу других систем.

База знаний растет, и сегодня мы уже можем брать на себя такие тест-кейсы, которые еще несколько месяцев назад не смогли бы выполнить без дополнительной подготовки. Поэтому практика кросс-системного тестирования постепенно становится естественной частью экосистемы разработки М.Видео-Эльдорадо и корпоративной культуры компании в целом.

P.S. Наша команда расширяется. Нам нужны талантливые тестировщики. Если вы такой, добро пожаловать на борт!
Подробнее..

К вопросу о сертификации ISTQB

16.06.2021 14:10:53 | Автор: admin
Добрый день, уважаемый Habr. Мне кажется, что у большинства членов комьюнити сложилось довольно скептическое отношение к сертификации вообще и к ISTQB в частности, поэтому не хотелось бы сводить разговор к холивару на эту тему. А хотелось бы обсудить, некоторые моменты, которые лично меня ставят в этом вопросе в тупик, думаю, что похожие проблемы испытывают и другие русскоязычные тестировщики, перед которыми, в силу различных причин, стоит задача получения сертификата.

Вопрос касается терминологии, на которую во многом завязан экзамен, а русскоязычных экзаменуемых я упомянул в том смысле, что кроме понимания терминов вообще, им еще предстоит как-то увязать их англоязычное и русскоязычное толкование.

Дабы не распылять внимание уважаемого сообщества, в этой заметке, я хотел бы остановиться на терминах, так или иначе связанных с тест-кейсами, поскольку считаю это понинятие одним из самых важных среди задач, стоящих перед тестировщиком. Здесь мы попытаемся сравнить официальные русско-язычный и англо-язычный глоссарии, являющиееся альфа и омегой для испытуемых. Итак, вод ряд терминов, так или иначе связанных между собой:

Англоязычный глоссарий:

test procedure: See test procedure specification

test procedure specification: A document specifying a sequence of actions for the execution
of a test. Also known as test script or manual test script. [After IEEE 829] See also test
specification

test specification: A document that consists of a test design specification, test case
specification and/or test procedure specification

test script: Commonly used to refer to a test procedure specification, especially an automated one

test case: A set of input values, execution preconditions, expected results and execution
postconditions, developed for a particular objective or test condition, such as to exercise a
particular program path or to verify compliance with a specific requirement. [After IEEE
610]

******** Те же термины из русско-язычного глоссария ********

процедура тестирования (test procedure): См. спецификация процедуры тестирования.

спецификация процедуры тестирования (test procedure specification): Документ, описывающий последовательность действий при выполнении теста. Также известен как ручной сценарий тестирования. [IEEE 829] См. также спецификация теста

спецификация теста (test specification): Документ, состоящий из спецификации проектирования теста, спецификации тестовых сценариев и/или спецификации процедуры тестирования.

автоматизированный сценарий тестирования (test script): Обычно используется как синоним спецификации процедуры тестирования, как правило, автоматизированной.

тестовый сценарий (test case): Набор входных значений, предусловий выполнения, ожидаемых результатов и постусловий выполнения, разработанный для определенной цели или тестового условия, таких как выполнения определенного пути программы или же для проверки
соответствия определенному требованию. [IEEE 610]

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

Ну что же, идем в англоязычный глоссарий, и видим, что несмотря на упоминание об автоматизации этот терми содержит и другой посыл Commonly used to refer to a test procedure specification. Идем по указанному посылу где смысл начинает плавно меняться: A document specifying a sequence of actions for the execution of a test. Also known as test script or manual test script.

Опа, и нас переносит из области автоматизации в прямо противоположную ей область: Also known as test script or manual test script. Таким образом, выходит, что тестовый скрипт это все же нечто иное, чем скрипт, написанный для автоматизации теста. Но тогда что же это? Буду весьма обязан, если кто-нибудь из специалистов возьмет на себя труд принять участие в обсуждении этой группы, связанных между собой терминов.

По всему выходит, что центральной фигурой здесь выступает test specification на которую, в конечном итоге замыкаются все ссылки англоязычного глоссария: test specification: A document that consists of a test design specification, test case specification and/or test procedure specification. Как видите он собирает в себя вообще все, что можно, и вместо поставленной задачи разобраться в различии между терминами test script и test case, мы вдобавок, получаем кучу новых понятий никак не проясняющих, а лишь усугубляющих наше (ну мое по крайней мере) недоумение.

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

Recovery mode Способыхраненияданныхвавтотестах и автоматизациятестированияПО вавионке что будет на LoGeek Night QA

07.06.2021 18:08:54 | Автор: admin

17 июня в 18:00 состоится Online LoGeek Night QA. На нем наши тестировщики расскажут о плюсах и минусах разных способов хранения данных в автотестах с примерами на Java, а также об автоматизации высокоуровневого тестирования ПО в авионке.

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

Программа

18:00 18:50 Александр Гвоздев

Автоматизация высокоуровневого тестирования ПО максимального уровня безопасности для авионики (приборы первичной индикации, уровни A и B).

В докладе Александр рассмотрит:

Категории критичности отказных состояний бортового ПО и их влияние на аспекты сертификации;

Особенности верификации ПО максимального уровня безопасности;

Реализацию тестирования ПО первичной индикации;

Автоматизацию высокоуровнего тестирования ПО первичной индикации

О спикере: тестировщик по призванию. С 2000 года занимаюсь тестированием бортового ПО авиационного, аэродромного, автомобильного и даже подводного, и жизни многих людей зависят от качества моей работы. Рад, что внёс (пусть даже относительно крошечный) вклад в прогресс всего человечества.

18:50 19:40 Максим Власов

Способы хранения тестовых данных.

В докладе Максим расскажет о:

Двух способах хранить данные в авто тестах: данных в виде хардкода в файлах (json, xml, csv) и модуле внутри фреймворка, который данные генерирует;

О минусах и плюсах этих подходов с примерами на Java.

О спикере: большой опыт тестирования web приложений. В роли автоматизатора QA 5 лет. Два самых крупных проекта Yandex, реклама и Luxoft, банковская сфера. Прошёл путь от ручного тестировщика до тест лида. Любит рассказывать про сложные вещи простым языком.

19:40 20:00 Розыгрыш призов

Как принять участие

Митап пройдет онлайн 17 июня, 18:00 (МСК).

Чтобы принять участие, нужно:

  • Зарегистрироваться насайте;

  • Перейти по ссылке в ZOOM, которую вы получите за сутки и за час до начала митапа на почту.

Будем рады вас видеть!

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru