вторник, 26 февраля 2013 г.

Перезапуск тестов

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

У автоматического теста есть всего один полезный выхлоп - падение теста. Все остальное время автоматические тесты просто греют воздух укрепляя в нас уверенность в нашем продукте (не всегда обоснованную, но это другая история). Это нагревание воздуха, безусловно, полезно для процесса и так далее, но большую часть времени никакой полезной информации не несет. Примерно как ребята в аэропортах, которые могут каждый год рапортовать, что в 100500 проверенных за год пар обуви ни одной бомбы не обнаружено. Работа, безусловно, полезная, но самое крутое что они могут сделать - это, как ни странно, исполнить свое предназначение и найти уже наконец эту чертову бомбу в этих чертовых ботинках. И перезапуск теста это примерно как "ой, кажется у вас в ботинках бомба, пройдите, пожалуйста, повторный досмотр - вдруг мы ошиблись?".

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

И что же означает это падение тестов? Обычно причины две:
  1. Баги в продукте
  2. Нестабильные тесты/Баги в тестах/Нестабильное тестовое окружение
Второе в одной группе, т.к. это, как правило, и является основным объяснением перезапуска тестов. И если мы начинаем перекладывать падение наших тестов на второй пункт, то мы попадаем в страну, где хреновые тесты - это норма, и где-то прячутся баги, которые мы могли бы найти раньше (и мы их, возможно, нашли, но успешно проигнорировали).

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

Да, я понимаю, что у всех своя специфика, уникальный внутренний мир проекта, сроки горят, начальство негодует и KPI не выполняется. Все это может заставить вас игнорировать какие-то упавшие тесты. Как правило это просто пустые отмазки. Как правило, но далеко не всегда.  Но тем не менее не позволяйте нестабильным, хреново написанным тестам становиться нормой. Не делайте нормой нестабильное тестовое окружение. Это все инженерные задачи - они решаются (не всегда легко, но тем не менее решаются). Если, конечно, суть вашей работы не заключается в том, чтобы демонстрировать пару тысяч зеленых квадратиков on commit.

41 комментарий:

  1. Ответы
    1. Я помню про твой богатый внутренний мир

      Удалить
    2. Относись к повторному запуску теста как к тесту из клауда!
      Система сама определила нестабильность окружения и перезапустила тест так что тебе этого не видно!!!
      По существу, "Не делайте нормой нестабильное тестовое окружение. Это все инженерные задачи - они решаются (не всегда легко, но тем не менее решаются)." сравнительно легко пересчитывается в деньги, с одной стороны "проверять руками", с другой стороны "перепроверять за автотестами" с известным процентом хуевых фейлов, с третьей стороны делать задорого стабильное окружение, с четвертой перезапуск тестов. Цена каждого подхода известна, в большинстве случаев и цена ошибки тоже, ну если ты не делаешь систему которая с ньюйоркской биржи в лондонскую триллионы за миллисекунду перекачивает. Решение должно быть рациональным. А не вот это вот, вы все негодяи, а я виконт де бражелон.
      Ну и ты в курсе про наш замечательный third party бэкенд. Cколько будет стоить сделать стабильным его? Инженерная ли это задача вообще? Или из области религиозных практик. Наловить девственниц там, принести в жертву в полнолуние, понизить процент застрявших в очереди писем на полпункта с каждым полнолунием. Как-то это пореалистичнее выглядит.

      Удалить
    3. Можно еще не париться и писать тесты типа AssertTrue(random.choice([True, False])). В принципе это дешевле чем писать хорошие тесты. Иногда оно будет ловить баги. И разница с плохими тестами в плохом окружении минимальна. Дичайший ROI!

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

      Удалить
    4. Я тебе описал 4 варианта действий, результат которых с известной погрешностью будет близок. Если мы не перекачиваем триллионы из нюёрка в лондон само собой. Твой ответ "Надо просто взять и написать хорошие тесты" с привлечением аналогий, выводящих спор в область демагогии впрочем ожидаем.

      http://risovach.ru/upload/2013/02/mem/nelzya-prosto-tak-vzyat-i-boromir-mem_12302163_orig_.jpg

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

      Удалить
    5. как же меня бесит эта блогплатформа

      Удалить
    6. Я про вас ничего не писал. Только про твой богатый внутренний мир :)

      Но то что тебе вероятности этих вещей заранее известны я рад. Лично мне они никак не известны :(

      Удалить
    7. Пока мы не перекачиваем триллионы из лондона в нюёрк, клали мы на эту вероятность!
      "Ковальски, мы будем богаты, законы физики не для нас!"

      Удалить
    8. Можно тогда тесты вообще не писать. Объяснение про триллионы вполне сканает.

      Удалить
    9. Ненаписание тестов убьет маленький проект с первым релизом, проебанный триллион убьет большой проект с третьим.
      Наверное можно включать мозг и смотреть на свой проект трезво.
      Интересный кстати вопрос, перезапускались ли зафейленные тесты в картах apple?

      Удалить
    10. Топ багов 2012-го помнишь? Там профукивание полумиллиарда за 45 минут никого не прикончило (жить стало хуже, но живут еще). Есть и более эпичные реципиенты, но пока выживают.

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

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

      Удалить
    11. Я сдаюсь.
      Ты победил.
      Полужопые инженерные решения плохо!
      Неполужопые инженерные решения хорошо!

      Удалить
  2. Имхо, не можешь починить - выкинь нафиг и проверяй руками. Иначе никакого доверия.

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

      Удалить
    2. Смотря какой уровень ответственности у этих вчерашних тестировщиков, а то ведь и хороший программист может запортачить проект. Мы вот создали условия для таких ручных тестировщиков и теперь удивляемся положительным результатам.
      А что такое экзотический самопальный фреймворк мне вообще не понять. У меня есть фреймворк, он учитывает спецыфику моего проекта и желания тестировщиков, которые с ним работают, как мне оценить степень его экзотичности? Даже работая с инструментами от Microsoft всё равно приходится создавать какую-то библиотеку, на использовании которой строятся тесты. Видимо это и есть "самопальный фреймворк"

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

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

      Удалить
    5. tanyfromsiberia, ооп тут зря упомянули:
      "Просто мне кажется не надо требовать от человека, ... чтобы этот инструмент соответствовал всем принципам ооп." Попробуйте с помощью ооп написать командлету с четырьмя параметр-сетами, где четвёртый может быть использован как самостоятельно, так и в составе первых трёх.
      Приходится подстраиваться под вендорские фреймворки, под не наследуемые классы и передачу параметров не в виде интерфейса.

      Удалить
    6. В защиту "самопала"... очень часто разлюбезные "несамопальные" фреймворки без костылей к текущему процессу с его специфико не применишь. Так или иначе почти все придется допиливать, надстраивать.

      В защиту "вчерашних ручных тестеров"... а разве не с этого начинало большинство? Не понимаю я порой пренебрежительного тона к "вчерашним" самим себе )

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

      Удалить
    7. Обучение в стиле "сбросить с лодки на середине реки" это отдельная тема для разговора. И человек, который без всякой практики писать свой собственный самобытный фреймфорк для тестов как раз подходит под эту категорию.

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

      Удалить
    8. Не покидает ощущение , что делается попытка говорить конкретно об абстрактном... )

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

      Удалить
    9. Я уже насмотрелся на такие чудеса - больше не хочу. Но, возможно, мой опыт тут нерепрезентативен.

      Удалить
    10. Днем было не до ответов потому отвечу тезисно:
      "Мне кажется если такой ручной тестировщик проявил такую инициативу". Инициатива идет сверху и никакого иного варианта у тестеров нет. Во всяком случае в нашем случае.
      "учитывает спецыфику моего проекта и желания тестировщиков, которые с ним работают" - есть системообразующие вещи, будь то Fitnesse или MSTest, к ним безусловно придется сделать свой DSL. Большинство же самопалов как раз и начинается с механизма организации тестов и репортинга результатов.
      "очень часто разлюбезные "несамопальные" фреймворки без костылей к текущему процессу с его специфико не применишь" - надо менять процессы. Поддержание своего велосипеда будет тяжелее и дороже.

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

    ОтветитьУдалить
    Ответы
    1. Ключевое здесь "ещё надо разобраться". А не просто перезапуск.

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

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

      Удалить
    3. "А не просто перезапуск." - я бы предложил сочетание лог-коллектора с данными от прошлого запуска для анализа и перезапуск. Если проблема в инфраструктуре, перезапуск поможет. Если нет - хуже уже не будет.
      Если железо свободно, пусть тест работает, больше фидбека на каких-то типовых проблемах соберётся.

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

      Удалить
    5. Ну почему исказить картину? Каждый тестовый запуск имеет свой независимый результат. Если два запуска сломались в одном и том же месте, там и копать (тест или продукт).
      Если в разных - скорее всего, инфраструктура или тест.
      Больше запусков -> больше информации -> легче траблшутить.

      Три разнородных примера:
      1) приложение в начальной стадии написания (падаёт всё и рандомно). Решение: тест нарезан на куски типа создать проект в БД, удалить проект в БД. Этот тест запихан в цикл из двадцати повторений. Примерно после десятого повторения выплывает баг с кривой записью консоли в БД проекта. Как починено: отдано программисту для запуска с подъёмом отладчика.
      2) тест без повторов. После нескольких часов теста приложение падает рандомно (неуловимый баг, но хоть лог для саппорта)
      3) читано где-то, наверное, на SQA :) - запускать комплексный тест несколько раз. Могут всплыть баги "длительного использования" (что угодно, один и те же данные удаляются и постепенно засоряется хистори продукта, или ломаются кривые запросы, и т.д.)

      Если можно заставить компьютер работать за нас - почему же нет? Конечно, разбор проблем обязателен.

      Удалить
    6. Потому что цикл примерно такой:
      1. Тесты упали
      2. Разобрались что к чему. Если понятно - починили или завели баги. Если непонятно - навтыкали градусников в подозрительные места и перешли к п.3
      3. Запустили тесты
      Примерно такую процедуру я во втором параграфе с конца и описал. Я не вижу в этом проблемы, хоть и занятия отладкой через CI это извращение (иногда необходимое, но все же). Без корректно завершенного п.2 это извращение вдвойне.

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

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

      Удалить
  4. Вот хотел написать "Подписываюсь под каждым словом" и ничего более, но...

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

    В остальном - подписываюсь под каждым словом.

    ОтветитьУдалить
  5. "Если проблема в инфраструктуре, то ее нужно устранять."
    Ок, назначаю тебя своим бесплатным консультантом.

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

    Как в данном случае поступил бы падаван боевой школы магической QA поняши?
    Закупил бы рекомендуемое железо?
    Разбирал бы каждый запуск тестов?
    Поставил бы в тесте таймаут в 6 часов?
    Сделал бы автоматический перезапуск теста при диагностировании конкретного ексепшна?
    Сделал бы объединение ексепшнов в группы и разбирал бы их в группах?
    Перестал бы работать с third party бэкендом и заменил бы всё на заглушку?
    Уволился бы и уехал в развитую страну, в которой все наши проблемы уже решены?
    Написал бы патч к закрытому коду third party продукта известного вендора?
    Что делал бы падаван, если тысяча тестов у нас ходит каждую ночь на 100 конфигурациях?

    Напоминаю для тех, кто забудет мой позапрошлый пост, 100 конфигураций не у нас и тесты мы не перезапускаем.

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

      Удалить
    2. Я специально для тебя написал последнее предложение.
      Про половину месячной зарплаты ты сделал мне смешно, за это отдельное спасибо.

      Удалить
    3. Замени "вы" на "гипотетические проект" и ответь на вопрос, например.

      Удалить
    4. половина месячного ФОТ гипотетического проекта это увеличение расходов на 5% на его жизненный цикл, гипотетический проект это убьет например, такой ответ устраивает?
      Как у нас или в Продукте с этим обстоит я честно не в курсе, но проблема вроде не стоит.

      Удалить
    5. Я правильно понимаю что использование лицензионного софта его тоже прикончит? Продукт вроде выжил, или там пиратство во все поля?

      Удалить
    6. "Я правильно понимаю что использование лицензионного софта его тоже прикончит? Продукт вроде выжил, или там пиратство во все поля?"
      Я в этом месте нихуя не понял, но на всякий случай напишу, что у нас нелицензионного софта нет, товарищ майор, а вот к этому, с бородой, присмотритесь.

      Удалить
  6. Я даже конкретизирую свой интерес.

    С моей точки зрения перезапуск теста из за медленной инфраструктуры (over9000 компаний разработчиков софта так тестируют, я гарантирую это) мало отличается от увеличения таймаута до статистически заметных величин. Порождает точно такой же positive false.
    Когда ты напишешь пост про недопустимость в тестах таймаутов больше трех секунд или сколько у нас там современный сферический пользователь в вакууме вебстраницу ждёт?

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

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

    ОтветитьУдалить
    Ответы
    1. Перезапуск теста из-за медленной инфраструктуры как минимум значит что оно у вас не очень равномерно тормозит. Что, надо заметить, довольно странно. Попахивает или фиговым администрированием или недостатком ресурсов. А пытаться сунуть в мясорубку слона это конечно круто, но не стоит ли для начала обзавестись подходящей мясорубкой?
      Если у вас часть контролов по таймауту не появляется, то есть мнение что такие тесты могут на перезапуске легализовать не только банальное зависание тестовой среды. Way to go, чо. Сильно помогает ежегодное ревью проходить?

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

      ЗЫ: Почему "продукт" с маленькой буквы?

      Удалить
    2. "ЗЫ: Почему "продукт" с маленькой буквы?"
      Я же не про нас пишу.
      Спасибо за информативные ответы.

      Удалить