Разделы портала

Онлайн-тренинги

.
Основные принципы выбора фреймворка тест-автоматизации
22.01.2024 00:00

Автор: Филип Фрейр (Filipe Freire)
Оригинал статьи: Tea-Time With Testers, #03/2021
Перевод: Ольга Алифанова

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

Среднестатистический инженер-тестировщик

Проблема

Сравнение инструментов (или фреймворков) тестирования и реальный выбор инструмента могут быть болезненным и чересчур сложным делом для современной технической организации:

  • Этот процесс страдает от множества длительных и утомительных споров о рисках между «узкоспециализированными» защитниками различных инструментов, никогда не пользовавшимися инструментами-конкурентами.
  • В некоторых случаях крайне легко поддаться на сладкие речи нечестных продавцов тест-инструментария.
  • Легко впасть в такой антипаттерн, как «медовый месяц»: первичное впечатление/период адаптации не обнаруживает глубинных проблем, которые выходят на поверхность только при длительном использовании.
  • И, наконец, инструменты сильно зависят от своего контекста – скажем, степенью знакомства с ним, правил и стандартов на уровне команды, организации и отрасли, расширений и плагинов, и т. п. А это значит, что «один инструмент, чтобы всех отыскать, воедино собрать и единою черною волей сковать», просто не существует.

Это зачастую верно вне зависимости от области применения инструмента – UI, API, нагрузка и производительность…

Предлагаемые решения

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

  • Абстрагируйте относящуюся к инструменту сложность через доступные интерфейсы (прогонять может кто угодно).
  • Контейнеризируйте с самого начала (прогонять может кто угодно откуда угодно).
  • Абстрагируйте «типы атак» (прогонять может кто угодно и что угодно).
  • Выводите значимые результаты тестов (кто угодно может понять, что упало).
  • Упрощайте дебаг (кто угодно может разобраться с падением).

Общий принцип тут в использовании доступности и поддерживаемости в качестве компаса (и ярлыка) для создания «безопасной дистанции», критического взгляда, применяемого при сравнении тест-фреймворков.

Разберем каждый пункт подробнее.

Прогонять может кто угодно

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

Если вы не первый год в отрасли, то, возможно, видели мрачные симптомы того, о чем я говорю:

  • Автоматизированные проверки прогоняются только людьми, которые разрабатывали их через пользовательский интерфейс IDE – к примеру, что-то, сделанное Jetbrains, вроде IntelliJ, или типичное приложение на ElectronJS, вроде Insomnia, Paw, Postman.
  • Автоматизированные проверки прогоняются только локально через командную строку или набор команд оболочки, и их крайне сложно установить локально на чьей-либо машине, кроме машин инженеров, разрабатывающих проверки.
  • Автоматизированные проверки дошли до этапа, когда они прогоняются в цепочке CI в обычном Jenkins/GitlabCI/Github Actions/… НО только создавшие эти проверки инженеры знают о задачах CI, и только они проверяют их результаты.

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

Мой личный опыт гласит, что для борьбы с этой проблемой нужно бросить все силы на соблюдение одного-единственного принципа:

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

Реализация всегда зависит от конкретного контекста, но вот ряд хороших признаков, на которые стоит ориентироваться:

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

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

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

testthis run --flow release_goat_for_trex --environment staging --project dinopark

Далекие от технической стороны вопроса люди могут запускать тот же самый инструмент оттуда, где они привыкли работать – например, в Slack или ином чате, к примеру, через слэш-команду:

/testthis run --flow release_goat_for_trex --environment staging --project dinopark

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

Прогонять может кто угодно откуда угодно

За последние годы я высоко оценил крутую возможность напрямую общаться с товарищем, который по совместительству – капитан Docker (да, Том, я говорю о тебе).

Основной урок, который мы выносим, ежедневно общаясь с асом пилотирования Docker (и контейнеров):

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

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

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

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

Всем плевать, потому что тест-инженер неправильно распространяет свой труд.

Распространение – это не просто поделиться ссылкой на репозиторий или CI-задачу. Чтобы исправить эти «спящие» дилеммы тест-инструментария, нужно помнить, что:

  • Любой создаваемый нами участок тест-инструмента должен приносить пользу сразу, а не через «6 месяцев».
  • Если нет простого, читабельного README, демонстрирующего, как пользоваться инструментам, мне совершенно точно плевать на него.
  • Если я не могу просто поднять контейнер инструмента, то даже технически подкованные люди будут игнорировать его.

И, возможно, нужно помнить про ключевые бонусы – побочный продукт вышеописанных принципов:

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

Контейнеризация – шаг на уровень выше, потому что контейнеры могут «запускаться где угодно», и запустить их можно «откуда угодно».

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

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

Прогонять может кто угодно и что угодно

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

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

И тут большинство тест-инженеров заметят ловушку: люди тратят много времени:

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

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

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

testthis run --flow some_flow (... другие аргументы)

testthis run-load --flow some_flow (... другие аргументы) (аргументы, специфичные для нагрузки, вроде количества виртуальных пользователей и итераций)

testthis run-distributed-load --flow some_flow (... другие аргументы) (аргументы, специфичные для нагрузки) (распределенные аргументы)

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

Кто угодно может понять, что упало

Тут мы возвращаемся к тому, о чем я уже упоминал.

Мы, тест-инженеры, обычно делаем так: если набор автоматизированных проверок падает, нам приходит некое банальное сообщение и ссылка на задачу CI. Это создает проблемы:

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

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

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

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

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

SomeAutoChatbot говорит: конечная точка ABC в окружении разработки 029 падает с ошибкой 502 Bad Gateway для тест-сценария buy-an-action-man. Trace-id ошибки 053de188-7438-42b1. Ссылка на логи some kibana/cloudwatch link. Возможное решение: перезапустите сервис заказов тут или свяжитесь с @oncall-support-dev-env-team.

Оно не должно выглядеть скучным, как это:

Что-то не работает, пожалуйста проверьте мою упавшую задачу Jenkins и тикет 1234 по тест-кейсу в Jira.

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

Кто угодно может разобраться с падением

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

Это реально, но у тебя нет такой возможности.

Мы стремимся усложнить себе проектную жизнь, игнорируя, возможно, наиболее полезный после контейнеризации вопрос:

Как сделать так, чтобы всем могли с легкостью провести дебаг падения тест-инструмента?

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

Иногда люди просто сбрасывают это со счетов, говоря: «А, если люди сделают то и это в конкретном используемом мной dev-окружении, они как-нибудь проведут дебаг инструмента… проблема решена».

Они не понимают, что они – часть проблемы. Так быть не должно. Могу предложить ряд шагов по решению:

  • Нужно иметь множество способов, которыми люди могут проводить отладку тест-инструмента – как через точки остановки и перезапуск, так и типичный «вывод в консоль».
  • Создаваемый вами инструмент детализирует (где-то в важных логах и другой документации) шаги, предпринятые при попытке следовать определенному сценарию.
  • Любые способы отладки должны документироваться там, где информацию легко найти.
  • Самостоятельно попробуйте все предложенные вами способы отладки.
  • Если какой-то из способов трудно объяснить, или он слишком запутанный, или сложный, избавьтесь от него и выберите более простой.

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

Говоря о выборе тест-инструментария, об этом в большинстве случаев умалчивают: «зло» инструментов, пытающихся имитировать человека и делать то же, что делает он.

Что я имею в виду:

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

Тут нужно держать в уме два ключевых момента:

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

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

Поэтому завершу предупреждением:

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

Прочитайте об опыте Майкла Болтона с Katalon и mabl – так это выглядит с точки зрения опытного тестировщика.

Обсудить в форуме