Основные принципы выбора фреймворка тест-автоматизации |
22.01.2024 00:00 |
Автор: Филип Фрейр (Filipe Freire) Никто не разделяет мою любовь к этой бессмысленной тест-библиотеке, но я сделаю ее обязательной для всех. Среднестатистический инженер-тестировщик ПроблемаСравнение инструментов (или фреймворков) тестирования и реальный выбор инструмента могут быть болезненным и чересчур сложным делом для современной технической организации:
Это зачастую верно вне зависимости от области применения инструмента – UI, API, нагрузка и производительность… Предлагаемые решения Хочу поделиться своими личными руководящими принципами, которые помогли мне снизить уровень того бесполезного шума, который сопутствует выбору инструментария:
Общий принцип тут в использовании доступности и поддерживаемости в качестве компаса (и ярлыка) для создания «безопасной дистанции», критического взгляда, применяемого при сравнении тест-фреймворков. Разберем каждый пункт подробнее. Прогонять может кто угодноОдин из самых игнорируемых аспектов любого тест-инструмента, особенно нуждающегося в адаптации и доработке поверх внутреннего инструментария, заключается в том, что люди плохо понимают, как вообще этим инструментом пользоваться. Если вы не первый год в отрасли, то, возможно, видели мрачные симптомы того, о чем я говорю:
Корень у проблем всегда один и тот же: только тест-инженеры, разработавшие проверки, знают, как их прогонять и/или как интерпретировать результаты, и в наличии огромный дисбаланс пользы в пользу автоматизаторов за счет всей остальной команды. Мой личный опыт гласит, что для борьбы с этой проблемой нужно бросить все силы на соблюдение одного-единственного принципа: Какую бы сложность мы ни встраивали в свои автоматизированные проверки, нужно предоставить множество доступных интерфейсов для прогона этих проверок, абстрагируя любую относящуюся к инструментарию сложность (и настройки) на всех его уровнях. Реализация всегда зависит от конкретного контекста, но вот ряд хороших признаков, на которые стоит ориентироваться:
В живой природе это может выглядеть так: допустим, мы работаем над тест-инструментом 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 (и контейнеров): Если мы можем разобрать и контейнеризировать решение проблемы, к примеру, часть ПО, то решение может быть не идеальным, но мы одним ударом решаем множество мелких проблем для себя и окружающих. Мы движемся от типичного «На моей машине все работает» к возможности делиться и распространять, контейнеризировать и привязать зависимости к рабочему состоянию, и использовать инструмент, не заботясь о внутренней кухне, сложной настройке или специфике конкретной машины. Это теперь «работает в моем контейнере» - это чуть лучше, чем работа, возможная только на машине разработчика. К сожалению, в большинстве отраслевых организаций, за вычетом использования уже существующих контейнеризированных инструментов, лишь небольшое количество тест-инженеров используют эти мощности и думают о контейнеризации своих автоматизированных проверок и специально разработанных тест-инструментов, и не способны предоставить доступ к инструментарию, который уже позволяет контейнеризацию. Я убежден, что это еще и соль на очень распространенные раны тест-инженеров:
Всем плевать, потому что тест-инженер неправильно распространяет свой труд. Распространение – это не просто поделиться ссылкой на репозиторий или CI-задачу. Чтобы исправить эти «спящие» дилеммы тест-инструментария, нужно помнить, что:
И, возможно, нужно помнить про ключевые бонусы – побочный продукт вышеописанных принципов:
Контейнеризация – шаг на уровень выше, потому что контейнеры могут «запускаться где угодно», и запустить их можно «откуда угодно». «Откуда угодно» тут нзачит, что мы легко можем распространять инструмент через чат-бот, таблицу или любой иной инструмент, способный на подкапотные 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 – так это выглядит с точки зрения опытного тестировщика. |