понедельник, 29 февраля 2016 г.

Знакомьтесь - хороший автоматизатор

Кто же такой хороший автоматизатор? Тот кто может все заавтоматизировать?! Отнюдь нет!

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

  1. на создание новых тестов;
  2. на поддержку имеющихся тестов;
  3. на прогон тестов.

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

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

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

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

  1. Проектируйте тесты, оптимизируя время прогона.
  2. Автоматизируйте только важные тесты, а не все подряд.
  3. Разбивайте наборы тестов на части, например, по приоритетам или по функциональности.
  4. Распараллеливайте тесты, используя софтверные или хардверные решения.

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

Дизайн тестов

Говорят, в тестировании нет интересных задач по программированию. Это не всегда так! Одна из таких задач - «как уместить слона в спичечной коробке?». Тут вам придется прибегнуть к использованию оптимальных алгоритмов, а также разных инструментов и фреймворков. Также, принимая во внимание тот факт, что в будущем вам понадобится распараллеливание тестов, вам придется писать еще и thread safe код, использующий изолированные друг от друга тестовые данные.

Как пример подобной задачи, можно рассмотреть тест на проверку данных в HTML таблице (10 строк, 4 столбца) с требованием, что тест не должен работать дольше 5 секунд.

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

Вариант 2: можно взять html код таблицы и разобрать его, используя наиболее шустрый html парсер. Здесь мы имеем только 1 запрос от инструмента к браузеру, и проверку данных в фоне. Поверьте, это будет намного быстрее.

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

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

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

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

Автоматизация только важных тестов

Данную тему необходимо рассматривать с двух сторон: новая и имеющаяся автоматизация.

Вопрос о новых тестах нужно ставить так: «Что именно нужно автоматизировать?». Вы должны четко осознавать приоритеты и соответственно выделять время и ресурсы на автоматизацию. Например: разрабатывая второстепенную (абсолютно не критичную) функцию, нет смысла вкладываться в автоматизацию по полной. И вообще, можно задаться вопросом: «Зачем нужно автоматизировать эти тесты?».

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

Немаловажным будет и то, что:

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

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

Разбиение тестовых наборов на части

Разбивая тесты на части (об этом я уже говорил в статье «Зачем всегда запускать все UI тесты?»), вы всего-навсего оттягиваете неминуемый коллапс. Количество тестов будет неимоверно расти, и вы, как следствие, придете к распараллеливанию.

Распараллеливание тестов

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

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

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

Заключение

Резюмируя все вышесказанное, хороший автоматизатор – это разработчик:

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

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

Автоматизатор, пора тебе выйти из тени и сказать, что ты есть, кто ты есть и зачем ты здесь.

Отправить комментарий

Условия копирования публикаций:

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