Просто скажите «нет» end-2-end тестам

Автор оригинала: Майк Вакер
  • Перевод
У вас наверняка было такое, когда вы и ваши друзья очень хотели посмотреть какой-нибудь фильм, а после жалели о том, что потратили на него время. Или, может быть, вы помните тот момент, когда ваша команда думала, что нашла «киллер фичу» и обнаруживала ее «подводные камни» только после выпуска продукта.

Хорошие идеи часто терпят неудачу на практике, и в мире тестирования хорошим примером этого может служить стратегия тестирования, построенная на автоматизации end-to-end тестов.

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

Источник

End-2-end тесты в теории


Хотя полагаться в первую очередь на end-2-end тесты — плохая идея, но теоретически можно придумать несколько доводов в пользу этого утверждения. 

Итак, номер один в списке Google из десяти вещей, которые, как мы знаем, являются правдой: «Интересы пользователей превыше всего». Таким образом, использование end-2-end тестов, которые фокусируются на реальных пользовательских сценариях, выглядит отличной идеей. Кроме того, эта стратегия в целом привлекательна для многих участников процесса.

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

End-2-end тесты на практике


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

Допустим команда создает сервис для редактирования документов в режиме онлайн (например, Google Docs). Давайте предположим, что у команды уже есть какая-то фантастическая инфраструктура для тестирования. Каждую ночь:

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

Крайний срок приближается быстро. Чтобы поддерживать высокую планку качества продукции, допустим, мы решаем, что требуется по крайней мере 90% успешных end-2-end тестов, чтобы мы считали что версия готова. Допустим, крайний срок наступает через один день.


Несмотря на многочисленные проблемы, тесты в конечном итоге выявили реальные ошибки.

Что прошло хорошо

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

Что пошло не так

  • Команда завершила свой этап программирования на неделю позже (и много работала сверхурочно).
  • Поиск основной причины неудачного end-2-end теста является трудоемким и может занять много времени.
  • Неудачи параллельной команды и сбои в оборудовании сдвинули результаты тестов на несколько дней.
  • Многие мелкие ошибки были спрятаны за большими ошибками.
  • Результаты end-2-end тестов временами были ненадежными.
  • Разработчикам пришлось подождать до следующего дня, чтобы узнать, сработало ли исправление или нет.

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

Истинная ценность тестов


Как правило, работа тестировщика заканчивается, когда тест провален. Ошибка регистрируется, и затем задача разработчика — исправить ошибку. Однако чтобы определить, где end-2-end стратегия не срабатывает, нам нужно выйти за рамки этого мышления и подойти к проблеме используя наши базовые принципы. Если мы «сосредоточимся на пользователе (а все остальное приложится)», мы должны спросить себя: приносит ли проваленный тест пользу пользователю? 

Вот ответ: «Проваленный тест напрямую не приносит пользы пользователю».

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

Исправление ошибок напрямую приносит пользу пользователю.

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


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

Построение правильной обратной связи


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

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

Думайте о малом, а не о большем


Так как же нам создать этот идеальный цикл обратной связи? Думая о малом, а не о большем.

Модульное тестирование

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

  • Модульные тесты быстрые. Нам нужно написать небольшой блок кода и мы уже можем тестировать его. Модульные тесты, как правило, довольно маленькие. На самом деле, одна десятая секунды — слишком долго для модульных тестов.
  • Модульные тесты надежны. Простые системы и небольшие модули кода, как правило, гораздо более устойчивые. Кроме того, лучшие практики модульного тестирования — в частности, практики, связанные с герметичными тестами — полностью устраняют такие проблемы.
  • Модульные тесты позволяют быстро найти ошибки. Даже если продукт содержит миллионы строк кода, если модульный тест не пройден, то вы, скорее всего, взглянув на тестируемый модуль сразу поймете в чем ошибка.

Написание эффективных модульных тестов требует навыков в таких областях, как управление зависимостями, написание заглушек/ mock-ов и герметичное тестирование. Я не буду описывать эти навыки здесь, но для начала типичный пример, предлагаемый новому Googler -у (или как их называют в Google — Noogler-у), — это то, как Google создает и тестирует секундомер.

Модульные тесты против end-2-end тестов

При end-2-end тестах вам нужно подождать: сначала создания всего продукта, затем его развертывания и, наконец, выполнения всех end-2-end тестов. Когда тесты все же заработали, вероятнее всего, они периодически будут сбоить. И даже если тест обнаружит ошибку, она может быть в любом месте продукта.

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


Интеграционные тесты

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

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

Пирамида тестов


Даже при проведении и модульных, и интеграционных тестов вам, скорее всего, потребуется  небольшое  количество end-2-end тестов для проверки системы в целом. Чтобы найти правильный баланс между всеми тремя типами тестов, лучше всего использовать визуальную пирамиду тестирования. Вот упрощенная версия пирамиды тестирования из вступительной речи конференции Google Test Automation 2014 года.


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

По-хорошему, Google предлагает разделение 70/20/10: 70% модульных тестов, 20% интеграционных тестов и 10% end-2-end тестов. Точное соотношение будет отличаться для каждой команды, но в целом она должна сохранять форму пирамиды. Старайтесь избегать следующих «форм»:

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

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

Вакансии


Если вы любите и умеете писать модульные тесты, то вам к нам! В компании ЛАНИТ открыта вакансия разработчика Java в DevOps команду, где вы найдете себе единомышленников.
ГК ЛАНИТ
Ведущая многопрофильная группа ИТ-компаний в РФ

Комментарии 54

    +24
    Т.е. большей частью предлагается проверять, что к пуговицам претензий нет.
    На мой взгляд, E2E тесты как раз очень даже нужны для сложных продуктов. Скажу про enterprise, допустим, у вас есть полсотни сервисов. Эти полсотни сервисов это только сервисы написанные вашей командой, а есть еще сервисы других команд. И вот они все собраны в одну систему и надо проверить пользовательские сценарии, которые проходят не через 2, а через 10-12 сервисов. При этом много чего меняется в БД, посылаются события наружу из системы, срабатывают всякие триггеры на события и пр.
    Конечно, все это надо проверять по отдельности, но вот шансов что это все вместе где-нибудь да сбойнет, тоже немало. И это НАДО проверять. Е2Е тесты позволяют выявить где кто накосячил с настройками, что-то не так развернулось, где-то сетап забыли, где-то версия не та, где-то БД не обновили. И отмазка разработчика «у меня все работает» совершенно бесполезна. Если, конечно, у вас сервис уровня зааплодил картинку, проверил что она отображается — то да, вам Е2Е не очень нужны, но для сложных систем они необходимы.
      –5
      Ну вообще-то это перевод статьи автора, работающего в гугл… судя по примерам, возможно, над разработкой Google Docs. Не думаю, что к продуктам Google можно применить в общем смысле характеристику «сервис уровня зааплоадил картинку».

      В целом здесь речь идет про известный паттерн «пирамида тестирования», который не утверждает, что e2e не нужны совсем… он говорит, что распределение должно быть — 70% unit, 25%- integration и что осталось в порядке убывания на контрактные тесты, e2e и ручные тесты (% просто для ориентира).
        +12
        В заголовке «Просто скажите «нет» end-2-end тестам» весьма однозначное отношение. И дальше по тексту выдвигается утверждение, что такие тесты ничего не покажут и пользы не имеют.
          +14

          Кстати оригинальный заголовок звучит так: Just Say No to More End-to-End Tests
          Что более верно перевести как: Не надо делать ещё больше сквозных тестов
          Это звучит менее радикально

            +2
            Кстати, да, вы правы. Не обратил внимание.
              –8
              Кстати нет. Исходный перевот правильный.
      +11

      e2e проверяет, что оно "вообще работает". Можно покрыть всё к чертям юнит и интеграционными тестами, сами тесты покрыть мутационными тестами, etc, etc. Но потом обнаружить, что у пользователя в приложении (сайте, etc) вместо кнопки "войти" логотип компании (слишком большой), или кнопка "войти" рисуется не тем цветом (цветом фона по цвету фона), или "этим просто нельзя пользоваться, потому что сайт грузится 90 секунд".


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

        0
        Но потом обнаружить, что у пользователя в приложении (сайте, etc) вместо кнопки «войти» логотип компании (слишком большой), или кнопка «войти» рисуется не тем цветом (цветом фона по цвету фона), или «этим просто нельзя пользоваться, потому что сайт грузится 90 секунд».


        Всё, что вы описали проверяется не end-2-end тестами. Тесты GUI, производительности, юзабилити, нагрузочные итд. И да, их очень полезно иметь, если низ и середина пирамиды уже реализованы.
        И не стоит забывать про API тестирование (когда это возможно). Оно обычно прилично быстрее e2e тестов, менее flaky и позволяет подтвердить, что оно «вообще работает».

        +2

        Простой аргумент ЗА
        Есть фронтенд приложение, идеальное работает локально
        Но при продакшн-сборке ломается из-за маленького бага
        С Е2Е-тестами можно как минимум дать 100% гарантию что приложение открывается и какие-то базовые сценарии работают. Это смок тест вроде как называется?

          +1
          Модульные тесты против end-2-end тестов

          Яблоки против апельсинов — fight!

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

              "Сквозные" тесты прикольное название, мне нравится.


              Довольно однобокие аргументы на мой взгляд.


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

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


              Крайний срок приближается быстро. Чтобы поддерживать высокую планку качества продукции, допустим, мы решаем, что требуется по крайней мере 90% успешных end-2-end тестов, чтобы мы считали что версия готова

              Это тоже довольно интересно, ни разу не слышал, чтобы в проекте был допустимый процент упавших тестов. Всегда все 100% тестов должны быть зелёными, как юнит, так и е2е тесты.
              Процент упавших это реально смешно и правильно проиллюстрировано в статье. Упасть мог всего один тест, но это будет тест на вход в систему и никто вообще не сможет войти после релиза… Любая ошибка тестов требует расследования. Да, можно отыскать причину, понять что это узкая проблема, которая мало на что влияет, пометить тест как Skip="Will fix in bug #12345" и пустить полностью зелёный код в релиз с известной минорной проблемой.


              е2е тесты это как раз необходимость, без которой невозможно представить современный успешный проект. Потому что только е2е тесты проверяют реальные сценарии пользователя. И только с прохождением этих тестов мы можем знать, что пользователь может зарегистироваться, залогиниться, а потом создать/сохранить документ. Никакие модульные тесты по определению не могут это проверить. А значит, что мы либо просто не проверяем такой сценарий, либо этот сценарий должны проверять люди вручную.
              И уж в данном контексте откровенно смешно жаловаться на низкую скорость и надёжность е2е тестов. Ручной человеческий труд всегда будет на порядок медленнее и с большим количеством ошибок и срезанных углов, чем прогон набора автоматических тестов.
              Если у нас перед релизом есть ручные тесты, то релиз цикл сразу же увеличивается с нескольких минут/часов, до дней. Потому что надо попросить живого человека в его рабочее время провести полную регрессию, и только потом делать релиз, если всё ок. А если не ок, то починить и попросить опять провести полную регрессию…
              Ах да, полная регрессия не нужна, мы ведь типа починили маленькую ошибочку, которая затрагивала один сценарий, ну ок, проверим вручную только этот сценарий и пойдём в релиз… И с вероятностью 50% занесём новые баги в продакшен :)))


              PS у нас на проекте вообще нет позиции тестировщик, также мы вообще не проводим ручное тестирование. Есть только модульные и е2е тесты. Полный прогон всех тестов занимает 20 минут. Чаще всего нам хватает 2-3 релиза в неделю. Но технически мы можем делать несколько релизов на прод в день (полный цикл от пуша в ветку, до заливки на прод где-то 2 часа). Как вы такое сделаете с ручным тестированием и без автоматических е2е тестов?

                +1
                PS у нас на проекте вообще нет позиции тестировщик, также мы вообще не проводим ручное тестирование. Есть только модульные и е2е тесты. Полный прогон всех тестов занимает 20 минут. Чаще всего нам хватает 2-3 релиза в неделю. Но технически мы можем делать несколько релизов на прод в день (полный цикл от пуша в ветку, до заливки на прод где-то 2 часа). Как вы такое сделаете с ручным тестированием и без автоматических е2е тестов?


                это круто!
                На наших проектах у нас тоже нет тестировщиков, мы пишем много-много unit-тестов, интеграционные и контрактные тесты. Перед выпуском делаем ручной смоук небольшой на 30 мин, в идеале, соглашусь его тоже стоит автоматизировать — это как раз те самые e2e тесты… но пока это не было необходимостью.

                Это тоже довольно интересно, ни разу не слышал, чтобы в проекте был допустимый процент упавших тестов. Всегда все 100% тестов должны быть зелёными, как юнит, так и е2е тесты.


                это тоже для меня было удивительным — но из перевода слов не выкинешь ).

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


                В статье автор сравнивает по скорости и надежности unit-тесты и e2e тесты и в целом посыл статьи сводится к тому, что стратегия писать «много unit и мало e2e» лучше, чем «много e2e и мало unit». Мне кажется вы тоже с этим согласны судя по вашему тексту.

                  +2

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

                +2
                В моем проекте пару лет существовали e2e-тесты, за эти пару лет благодаря им обнаружен один баг и потрачены тонны времени на их разработу и поддержку. Очень часто мигают. В результате были скипнуты, пишем только unit.
                  +3

                  Приехали :)
                  Кажется программисты писали статью.
                  Придерживаюсь взгляда, что с точки зрения продукта (а обычно это означает, что и денег тоже), самые важные тесты — это e2e.
                  Потому что то, что там внутри написал отдел разработки, на каких хаскелях, какими тестами покрыл, в какие докеры завернул — это все безусловно важно. Отделу разработки.


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


                  Как на каждый релиз в сложном продукте проверять регрессии?

                    +1
                    В основном unit-тестами, немного e2e и совсем мало руками.
                    Здесь речь идет про паттерн «пирамида тестирования», рекомендую:
                    martinfowler.com/bliki/TestPyramid.html
                    habr.com/ru/post/358950

                    Хочу сказать, что у нас это работает. Судя по автору статьи — в гугле тоже.
                      0

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

                        +1

                        Пирамида тестирования — это неплохо.
                        Но я говорю несколько о другом — корректное функционирование частей (прохождение unit-тестов), не влечёт корректного функционирования всей системы (прохождение e2e тестов).


                        И с этой точки зрения для продукта гораздо важнее e2e тесты, нежели unit-тесты.

                          +1
                          мне кажется тут не стоит занимать крайние позиции, идея автора (и вообще пирамиды тестирования) следующая:
                          — очень очень много unit тестов влечет c высокой вероятностью общее корректное функционирование всей системы
                          — если еще к очень много-много unit-тестов добавить немножечко (тк они дорогие и ненадежные) e2e тестов- то вероятность корректного функционирования станет совсем высокой (но все равно до 100%)

                          и эта стратегия более экономически целесообразна, чем стратегия — писать только e2e тесты.
                            +1
                            — очень очень много unit тестов влечет c высокой вероятностью общее корректное функционирование всей системы

                            Как вы пишите много много юнит тестов и не огребаете при рефакторинге? Удается ли вам ловить реальные баги с помощью юнитов? Расскажите как, потому что сколько я не пытался заставить юнит тесты работать всегда получается одно и то же:
                            — Любой рефакторинг превращается в борьбу с тестами, время на рефакторинг увеличивается в разы.
                            — Тесты ломаются от чего угодно, только не от багов. Это из-за моков, но как писать юниты без них непонятно.

                            В итоге я пишу тесты, но с реальной БД, дергаю реальное АПИ настоящим HttpClient, некоторые АПИ заменяю самописными стабами. Юниты пишу для нетривиальных алгоритмов, которых совсем немного. В итоге проблемы с рефакторингом ушли, тесты регулярно ловят баги.

                            Тесты, конечно, мигают, работают не то что-бы супер быстро и есть проблемы с сетапом. Но несмотря на это ситуация значительно лучше, чем была с юнитами. Я готов подождать 30 минут и быть уверенным, что все АПИ «прокликано» тестами вместо того, чтобы ждать 2 секунды и знать что моки работают как надо.
                      +2
                      Почему в примере тестирование начинается за 1 день до релиза?
                      E2e как и други виды тестов это инструмент, плясать надо от тест кейсов или сценариев. Если вы можете проверить их юнитом — используйте юнит. Если интеграционный тест превращается в кашу из моков, может лучше честно запустить продукт и проверить что он действительно работает?
                        +1
                        E2e-тесты плохие, потому что петля обратной связи очень длинная (долгая).
                        Unit-тесты околобесполезны, потому что не гарантируют работоспособности продукта.

                        Решение — Behavior-тесты. Медленно работающие «концы», те самые «end» из Е2Е можно (и нужно) отрезать, и тесты начинают работать также быстро детерминировано как unit-тесты и продолжают гарантировать корректность логики приложения.

                        Загвоздка здесь в том, чтобы начать писать код так, чтобы концы можно было отрезАть. Например, при разработке на ангуляре, логику зачастую пишут пишут прямо в разметку. Естественно эту логику не протестировать кроме как посредством Е2Е.
                          +3

                          Автор оригинальной статьи написал это в 2015 году.
                          5 лет для ИТ — заметный срок, 25 лет назад не было интернета.


                          Тогда было ОК сидеть командой высокооплачиваемых ждунов и оправдывать свою неэффективность аргументом "оно компилится".
                          Сейчас есть docker-compose, в котором разработчик может за пару минут у себя локально прогнать все e2e-тесты на всей инфраструктуре, не играя в "угадайку" (пофиксили или нет) с RPS 1 выстрел в день.


                          Savochkin зачем такую древнюю статью откопали, кстати? :)

                            –2
                            потому что она актуальна и по сей день, статья очень полезная и крутая…
                            я с удивлением обнаружил что перевода на хабре нет.
                            если для вас это очевидно, то я вас искренне поздравляю

                            но я не уверен, что судя по комментарию про docker compose и далее, что мы на одной волне
                            вы точно говорите про e2e тесты — которые полностью имитируют поведение пользователя?
                            вы реально считаете, что их можно прогнать в сколько -нибудь сложной системе за пару минут??? ну не знаю… насколько я знаю у нас средняя скорость выполнения e2e тестов — 5.5 штук/минуту
                            если вы у вас десяток e2e тестов, ну ок…
                              0
                              1. Для быстрого результата можно запускать только тут часть тестов, которая относится к предположительно затронутой области. Полный набор прогоняется ночью.
                              2. Тесты можно гонять на нескольких машинах параллельно. Да, не у всех эти машины есть.
                                0

                                Есть ещё разночтения, а что собственно такое e2e тест. Для одних это большой или даже огромный сценарий с какого-то нулевого состояния, каждый шаг которого тестируется. А для других (в случае веб-приложений): залили конкретные фикстуры в базы(у), открыли конкретный адрес, проверили (опционально), что всё отображается корректно, выполнили шаг, проверели состояние баз(ы). То есть классическое: подготовили систему (часто недоступным пользователю способом — так быстрее)->выполнили одно атомарное действие за пользователя->проверили состояние системы.

                              +1

                              Концепция пирамиды известная, но не понимаю зачем смешивать всё воедино:


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


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


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


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


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

                                +1
                                Статья как и выводы голословны и могут быть применены только к конкретной команде.
                                Е2Е тесты быстры и легки в поддержке если их правильно писать. К примеру веб тесты помню пробегали 1300 за час (около 250 тестов против 5 брендов). Поддерживались 1им тестировщиков (включая Jenkins + настройка агентов). Или сейчас мобильные подольше бегут почти 1000 тестов (по 500 ios + android) 3часа. Тоже приемлимо. Поддерживаются 2мя тестировщиками.
                                  0
                                  через полгодика пожалуста статью напишите что в итоге вышло, хотя подозреваю какой примерно результат будет и соответственно выводы.
                                    0
                                    это вообще-то перевод статьи сотрудника Гугл от 2015 года, мы в DevOps командах уже более полугода используем этот подход, все хорошо
                                    0

                                    Расскажите мне, инженеру разработки ПО, что такое e2e тесты во фронтенде и почему так популярен этот баззворд?


                                    В общепринятой терминологии (ISO/IEC TR 19759) такого понятия нет. В этой статье они на картинке отображаются как системные тесты.
                                    Но в фронтенд-проектах они создаются как интеграционные, и в их разработке принимают участие именно фронтендщики, а не QA, что говорит о том, что они не системные, а интеграционные.

                                      0

                                      Инженер разработки ПО не может загуглить незнакомый термин?)


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

                                        0

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


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

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

                                          0
                                          e2e тесты запускаются на живой работающей системе, а не в каких-то директориях.
                                            +1
                                            а то, что генерируют фреймворки в e2e директориях фронтенд проектов — нет.

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

                                        +6
                                        Вообще опасное мнение выскажу сейчас. Но я лично пришел к перевернутой пирамиде. Да, я знаю, «антипатерн» и блаблабла. Пока что играюсь с таким подходом дома, в продакшн не тащу — слишком уж вразрез с устоявшимися практиками идет. Вот мои аргументы против юнит тестов:

                                        1. Юнит тесты это практически всегда тестирование реализации. То есть, есть ситуация, нужно сделать рефакторинг, потому что код плох, но сломать логику не хочется. И если рефакторинг в виде «переименовать переменную, вынести что-то в приватный метод» — юнит тесты ок. Но часто в коде полная лажа, нарушение всех принципов SOLID, ну или просто требования так поменялись и нужно разбивать/соединять классы — тут юнит тесты обычно летят в мусор. В тоже время e2e — да хоть несколько микросервисов в мусор выкинь, и перепиши заново — уже написанные тесты помогут в этом.

                                        2. Юнит тесты часто не нужны и даже мешают. Чаще всего я вижу что-то типо такого: есть метод, который делает проверку и вызывает другой метод. И к нему написан тест напичканный моками, который тестирует другие моки, который сложнее самого кода раз в 10. Из-за обилия моков и больших объектов это все дико не читабельное. А бывает еще хуже. Что-то типо Mockito.verify(some.call(Mockito.any()) — типо проверяем что функция приняла х**ню, вернула х**ню — круто. Такое всегда появляется, когда кто-то начинает устанавливать планки «покрытие не меньше 80%!». Доходит порой до тестирования конструкторов, в которых ничего кроме this.prop = prop нету. Бррр, аж вспоминать страшно.

                                        В общем резюмируя, я не против тестов. Я против идиотских «пирамид», планок покрытия «не меньше 146%», я за здравый смысл. Если у вас в логике куча алгоритмов или математики — то тут юнит тесты как раз то, что вам нужно. Если же у вас веб приложение с классическим CRUD — то возможно вам больше подойдут e2e. Если архитектура быстро меняется, код часто переписывается, то e2e — ваш вариант. Если вы энтерпрайз, который существует с 10 лет, то юнит тесты скорее всего ваш бро. Если у вас преимущественно синьоры, то возможно юнит тестов можно писать меньше. Если джуны — лучше больше — потому что юнит тесты еще и форсят single responsibility.
                                          0
                                          В общем резюмируя, я не против тестов. Я против идиотских «пирамид», планок покрытия «не меньше 146%», я за здравый смысл. Если у вас в логике куча алгоритмов или математики — то тут юнит тесты как раз то, что вам нужно. Если же у вас веб приложение с классическим CRUD — то возможно вам больше подойдут e2e. Если архитектура быстро меняется, код часто переписывается, то e2e — ваш вариант. Если вы энтерпрайз, который существует с 10 лет, то юнит тесты скорее всего ваш бро. Если у вас преимущественно синьоры, то возможно юнит тестов можно писать меньше. Если джуны — лучше больше — потому что юнит тесты еще и форсят single responsibility


                                          по моему опыту покрытия 60-70% unit-тестами вполне хватает для того, чтобы почти исключить регресса, вообще разные типы автотестов — они не для разного, они для того же самого. Паттерн «пирамида тестирования» и автор не утверждают, что e2e не нужны… в статье просто показывается, что экономически целесообразно использовать соотношение

                                          По-хорошему, Google предлагает разделение 70/20/10: 70% модульных тестов, 20% интеграционных тестов и 10% end-2-end тестов. Точное соотношение будет отличаться для каждой команды, но в целом она должна сохранять форму пирамиды.
                                            0
                                            Если у вас в логике куча алгоритмов или математики — то тут юнит тесты как раз то, что вам нужно.

                                            Самое то тут продвинутые системы типов, на самом деле.

                                              0
                                              Все вы правильно делаете. Называйте такие тесты как хочется — e2e, интеграционные или как-то еще. Самое главное — тестировать реальную систему, а не то, как кто-то настроил моки.

                                              Когда вся эти истерика с XP и TDD я был в восторге, это было круто! Я использовал лучшие коммерческие и бесплатные инструменты для тестирования и создания моков, перечитал все книги всех авторитетов, убил уйму рабочего времени чтобы понять как это должно работать. Итог — за 3 года я научился идеально писать юнит тесты и код, под них заточенный. Была только одна проблема — тесты не ловили багов и стоили в поддержке дороже основного кода.

                                              А потом я понял в чем прикол. TDD описывали с системы, которую делали на Smalltalk. А теперь пойдите и посмотрите что такое Smalltalk. Это когда любой объект и класс можно менять, IDE встроена в систему, нет даже такого понятия как компиляция или запуск. То есть в Smalltalk система всегда запущена, модификации делаются и вставляются прямо в рабочую программу. В таких условиях не нужны моки, а тесты могут, если нужно, и UI окно открыть и кнопку ткнуть и к БД подключиться и т.п.

                                              Итог — мои тесты работают с живой БД, дергают АПИ по HTTP, в них никогда не бывает моков, но редко бывают самописные заглушки. Большая плюшка — уже 3 раза переписали все внутренности одного сервиса, тесты остались как есть, только добавляли новые по мере появления новых фич. Другой бонус — десяток тестов, 500 строк кода дают покрытие в 90% для подсистемы в 5000 строк кода.

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

                                              И из-за них итоговая система в сборе в итоге не работает, хотя все компоненты по-отдельности могут быть OK, т.е. соответствовать своей [неправильной] спецификации.

                                              Так что без e2e тестирования никуда.
                                              Ну как вариант: предоставить эту честь конечным пользователям, если они супер-лояльны, терпеливы, и вообще перебьются.
                                                +1
                                                Написали море юнит тестов. К коду теперь не подойти. Чуть что пачку тестов переписывать надо. Читаемость у тестов обычно никакая. Код ревью тестов обычно спустя рукава делается. Любой рефакторинг превращается в ужас.
                                                Ладно, зато весь код точно работает. Запускаем пользователей. И джейсон перекладывается неверно. Бага в продакшене. И все юниты зеленые. Ошибка где-то между микросервисами. Вот на стыке всего того что мы замокали.

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

                                                Да. Придется нанимать разработчиков выше уровнем. Этими тестами баги не половить. Долго. Зато есть плюс. Люди которые пишут плохой код и правят его пока все тесты не позеленеют у нас не задержатся.
                                                  +1

                                                  Для какого публичного метода? e2e тесты это, прежде всего, тестирование через реальный UI, у которого обычно нет методов в принципе, а есть какие-то страницы/экраны, контролы на них и т. п.

                                                    0
                                                    Для типового бекенла это его апи. В которое уже ходит фронт и пользователи.
                                                      0

                                                      Это уже (или ещё?) не e2e. А так интересная дискуссия была на прошлом проекте: кто должен писать api тесты.

                                                        0
                                                        Так не надо все доводить до абсолюта.
                                                        Тестирование бекенда через нажимание кнопочек на фронте будет работать плохо и ненадежно.
                                                        Юнит тесты часто не тестируют ничего. И не гарантируют вообще ничего. Моки — зло.

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

                                                        Как такие тесты называть это вопрос. К е2е они точно ближе чем к юнитам. Границу я бы провел по мокам. Все что с моками юниты, все что без них е2е.
                                                          0

                                                          e2e это обычно не тестирование бэкенда или фронтенда, это тестирование всей системы в сборе. Толку от ваших тестов "публичных методов", если фронт написан так, что шлёт запросы на бэк, которые возвращают 422? Разве это ожидает пользователь?


                                                          Если не это то, то что ваши тесты гарантируют? Что если фронт отправит запрос так, как бэк его ожидает, то бэк ответит как бэк ожидает, правильно? Да, хорошие тесты для бэкенда. Вот только пользователю без разницы, что там бэкенд отвечает на запросы, которые ему фронт не посылает. Вы же сами пишите, что нужны гарантии того, что в протестированных случаях пользователь получит то, что ожидает. А ожидает он, например, что нажатие кнопки "добавить в корзину" увеличит счётчик и сумму товаров в корзине и именно этот товар ему придёт, когда оплатит заказ.

                                                            0
                                                            Я бек пишу. И соответвенно за него отвечаю. Вот json. Он правильный и согласованный. Остальное сами как-нибудь. Кроме фронта есть публичное АПИ. В которое ходят прямо живые пользовали.

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

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

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


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

                                                                0

                                                                На любом более-менее большом проекте фронт и бек делают разные люди.
                                                                Разделение ответвенности это нормально.


                                                                Есть определенная логика в раздельном тестировании. Бек катит версию. Тесты зеленые. Все по спецификации. Фронт катит свою. Тесты фронта опираются на то что тесты бека уже зеленые и можно смело вызывать методы бека, они ответят корректно.
                                                                И в итоге все работает правильно. Место где оно может сломаться я с трудом представляю.

                                                                  0

                                                                  Не на любом, есть проекты, принципиально набирающие только фуллстэков.


                                                                  Да логику где угодно можно найти. По вашему описанию похоже, что e2e тесты вы называете тестами фронта.


                                                                  Но пока это не закреплено, тесты фронта могут рассчитывать не на бэк, а на свои моки бэка. И сломаться может на несоотвествии бэка и его моков.

                                                                    0
                                                                    Не на любом, есть проекты, принципиально набирающие только фуллстэков.

                                                                    Не надо идти в такие проекты. У них менеджмент не очень. Стартап где 2 человека делают все это понятное исключение.

                                                                    Да логику где угодно можно найти. По вашему описанию похоже, что e2e тесты вы называете тестами фронта.

                                                                    Нет. Фронт отвечает что все отрисовалось как надо во всех нужных браузерах. Что все джейсоны правильно уходят в бек и что все ответы бека правильно показываются. Что там на беке их не волнует. Черный ящик. Есть только вход и выход. И правила связи входа с выходом. Правила связи входа с выходом подверждены тестами бека.

                                                                    Но пока это не закреплено, тесты фронта могут рассчитывать не на бэк, а на свои моки бэка. И сломаться может на несоотвествии бэка и его моков

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

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

                                                                    Лучше всего когда в начале пишется бек, а потом по готовым и протестированным методам фронт. Так не всегда выходит, но к такому стоит стремиться.
                                                  –1
                                                  А мб лучше скажем е2е тестам — .NET? ;))
                                                    +2
                                                    Т.е. у вас нет настроенного CI/CD процесса с автоматическим билдом, запуском модульных тестов, созданием контейнера, деалойментом и звпуском интеграционных и end 2 end тестов?
                                                    >>Если два блока не интегрируются должным образом, зачем писать сквозной тест, когда вы можете написать гораздо меньший, более сфокусированный интеграционный тест, который обнаруживает ту же ошибку?
                                                    отвечу на вопрос — затем что интеграция двкх модулей может пройти гладко и результат будет попадать в ожидаемые, но включение в эту цепочку третьего модуля приведет к ошибке.
                                                    Ну и если у вас есть интеграционные тесты — то end 2 end должны собираться с очень маленькими трудозатратами

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

                                                    Самое читаемое