вторник, 19 июня 2012 г.

Роботу роботово

Without changing our pattern of thought, we will not be able to solve the problems we created with our current patterns of thought
А. Эйнштейн

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

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

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

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

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


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

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

Короче говоря - тест этот говно полное, а не тест.

Что мы можем сделать чтобы он перестал быть говном?
  • Убрать лишние телодвижения
    • Никаких сетапов в браузере (мелкий кусок API или хелпер на "создать псто" и мы уже сэкономили кучу сил и энергии)
    • Никакой лишней навигации (хелперы/API на логин и переход к псто... да хоть директ линком в псто)
  • Никаких тестов с сотнями проверок (в идеале один тест - один ассерт)
  • Никаких трешевых тестов
    • CRUD - ок
    • Дешевые проверки на безопасность - ок
    • Основной функционал - ок
    • Выдирание алайнов элементов страницы и их стилей - в другой набор тестов пожалуйста
    • И т.д.
Да, возможно в вашем конкретном случае это будет не реализуемо, потому что никто вам не даст никаких клевых API, никто вас не снабдит классными хелперами забирающимися в потроха приложения. Но не отчаивайтесь - дерьмовое testability в наше время в порядке вещей. А отсутствие хороших хуков в приложение, легкости конфигурирования и смены состояний приложения это оно и есть. Для примера можете попробовать автоматически протестировать мало-мальски сложное мобильное приложение (лучше сразу на symbian чтобы жизнь медом не казалась) - после веба ощущения как-будто вам обе руки отрезали. Тестирование веб-приложения с плохим testability после того как вам показали хорошее - точно те же ощущения. Получается эдакий технический долг перед тестировщиками с которым ваши тестировщики будут жить вечно.

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


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

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

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

6 комментариев:

  1. "фу ересь какая так не бывает" - бывает :) Но действительно редко. Причем часто в этому способствуют тестировщики.

    ОтветитьУдалить
    Ответы
    1. Это из серии "почему разработчики не хотят писать тесты". Вопрос инженерной культуры, которая в большинстве случаев в нашей стране довольно низкая. У тестировщиков тоже. Но как правило это болячки целых команд/контор

      Удалить
  2. да, и тестирование "через GUI" это действительно плохо. Или я не понял тонкого цинизма? ;)

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

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

    ОтветитьУдалить
    Ответы
    1. Насчет сформировавшегося проекта есть пара вариантов:
      1. Там вообще небыло тестирования. В этом случае про слово testability можно, как правило, забыть.
      2. Там было ручное тестирование. В этом случае testability в каком-то виде может присутствовать (волшебные API для пресета тестовой среды, хорошие конфиги, логгирование и т.п.). Хотя как показывает практика в большинстве своем люди занимающиеся ручным тестированием вопросами testability не задаются (я хз почему так, но это так).

      Увы почему-то так получается, что вопросы testability начинают сильно напрягать только когда дело доходит до автоматизации. Это очень плохо, но см. выше про ручное тестирование.
      Дальше есть варианты с дружелюбностью среды (привет symbian) и еще сотни всего.

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

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

      Удалить