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

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

.
Автоматизируйте ваши автотесты
23.05.2016 11:51

Автор: Майкл Фрициус (Michael Fritzius)

Оригинал статьи: https://testzius.wordpress.com/2016/02/22/continuous-integration-strategies/

Перевод: Ольга Алифанова

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

Они экономят вам время, правда?

Эээ... не всегда.

Чем больше команд переходит на DevOps, тем очевиднее становится необходимость автоматизировать автотесты.

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

Этот процесс называется "непрерывная интеграция" (CI) или "непрерывная разработка" (CD).

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

 

Масштаб

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

В Интернете полно информации о непрерывной интеграции.  Мне бы хотелось обсудить специфику тестирования при применении CI/CD.

Взяли и запустили автотесты вручную, делов-то!

Да, запуск автотестов кажется тривиальной задачей, особенно если все, что вам нужно для этого сделать - это напечатать "run". Но ручной старт автотестов - рискованная затея.

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

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

"Что я только что делал? Что, что черт побери? Что я делал-то???"

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

Как часто нужно запускать автотесты?

В автоматизации нет смысла, если вы не гоняете автотесты регулярно.

Суть CI - в быстром информировании о здоровье вашего продукта. Запуская автотесты регулярно, вы получите кучу преимуществ. К примеру:

Регулярный запуск заставляет людей реагировать на результаты

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

Регулярный запуск улучшает ваши тесты

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

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

Он предотвращает устаревание тестов

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

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

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

Стратегии

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

Это довольно много. Я бы сказал, дофига.

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

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

Присвойте категории вашим тестам

Большинство фреймворков (например, JUnit, Cucumber) позволяют группировать схожие тесты.

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

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

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

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

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

Цепочки тестов

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

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

Такое "формирование цепочки заданий" - отличный способ бороться с методологией "все пропало".

Если какой-то из smoke-тестов рискует упасть, такой подход экономит время аж двумя способами:

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

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

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

Визуализируйте результаты

Гораздо проще разобраться в вопросе, когда у вас есть графическое представление результатов тестов, а не просто сырой текст.

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

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

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

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

Распараллельте свои тесты

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

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

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

Скажите, не ждите, пока вас спросят

Люди предпочитают, чтобы им сообщали, что что-то рухнуло, а не идти выяснять этот вопрос самостоятельно. Уверен, что большинство CI/CD инструментов способно сообщить вам письмом, если тест упал.

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

Помещайте известные баги в карантин

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

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

Это решает сразу 3 задачи:

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

Перемещайте в карантин нестабильные тесты

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

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

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

Прогоняйте тесты с известными проблемами в первую очередь

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

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

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

В первую очередь тестируйте изменившийся код

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

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

Зачем все это нужно?

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

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

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

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

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

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

Взгляните на свою организацию другими глазами, ищите возможности сэкономить время при помощи CI/CD. Где бы вы опробовали вышеописанные тактики?

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