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

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

    1. Тестировщики не знают язык программирования, поэтому автор тестов дополняет шаги теста комментариями. Как это выглядит:

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

    2. Правильное решение какой-то задачи откладывается на потом, алгоритм пишется в лоб. Как правило, код теста от этого становится непонятным и появляется жгучее желание объяснить, почему не дописано нормально сделано так. Самодокументируемый код? Не, не слышали, это же просто тесты. На практике может выглядеть примерно так: 

  1. Сильно упрощенный код, отсутствие паттернов. Причины часто такие же – отсутствие навыков и/или спешка. Это ж тестировщики, печатать код умеют – уже молодцы. Да? Нет.

    1. Удивительно, но не все применяют Page object в UI тестах, даже когда прям напрашивается. Вместо этого пишутся стандартные портянки кода с локаторами, ожиданиями и т.д.

    2. Нарушается принцип Single responsibility. Вместо маленьких специализированных классов для работы с базой, драйвером и т.д. появляются монстры с общим названием TestHelper. Найти там что-то довольно затруднительно, поэтому часто в таких монстрах методы почти (или не почти) дублируют друг друга.

    3. Игнорируется принцип DRY – пишутся одинаковые действия в тестах или идентичные на 99% методы. Например, два метода RaisePriceBy10Dollards() и RaisePriceBy20Dollars() вместо метода RaisePriceBy(int countOfDollars).

  1. Невнимательное ревью тестов. Здесь примеры разные:

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

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

    3. Для экономии времени часто проверяется правильность конструкций, а не логики. В итоге получаются тесты, которые не проверяют то, что заявляют. Или проверяют не так, как надо. Один из классических примеров – когда в UI тестах проверяется только сообщение об успехе на тестируемой странице, и упускаются проверки изменений на сервере.

Вместо заключения

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

Чем в итоге плохо такое отношение? Ну тесты ведь и правда не продуктовый код, что плохого случится?

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

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

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

Комментарии (4)


  1. NeoNN
    24.01.2025 07:55

    Вообще в тестах принято прописать стандартный комментарий AAA - arrange, act, assert, чтобы разделить секции с разными операциями. Ну и часто тесты действительно могут копипаститься и писаться гораздо менее продуманно, чем основной код, но у них чисто утилитарная цель, непонятны цели инвестиций в код, кроме тех, где они реально оправданы.


    1. Scarethebear Автор
      24.01.2025 07:55

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

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


  1. egusinets
    24.01.2025 07:55

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

    Хочу добавить несколько мыслей:

    1. Комментарии в тестах: Вы правы, что комментарии часто маскируют проблемы, вместо того чтобы их решать. Однако, если комментарии используются для объяснения сложной бизнес-логики или неочевидных решений, они могут быть полезны. Главное — не злоупотреблять ими и не заменять ими качественный код.

    2. Самодокументируемый код: Это идеал, к которому стоит стремиться. Если тестовый код написан чисто и понятно, он не только упрощает поддержку, но и становится частью документации. Это особенно важно для новых членов команды.

    3. Page Object и DRY: Полностью согласен, что пренебрежение этими принципами приводит к хрупким и трудно поддерживаемым тестам. Page Object — это must-have для UI-тестов, а DRY — это основа любого качественного кода, будь то продукт или тесты.

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

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

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

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


    1. Scarethebear Автор
      24.01.2025 07:55

      Спасибо за поддерживающий комментарий!

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

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