Антипаттерны тестирования

Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ

Перевод статьи «The Worst Test Suite—Testing Anti Patterns Experienced In Real Life».

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

Весь набор тестов состоял примерно из 10 файлов. 9 из них были «более-менее», десятый же был настоящим кошмаром: в нём было примерно 3000 строк кода, которые объединяли в себе ~80 тестовых случаев. Около 95% всего набора тестов приходилось на этот один файл.
Помимо самих тестов, все вспомогательные утилиты, которые использовались в тестах, были разбросаны по этому же файлу.

Смешение типов тестов

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

Почему тесты пронумерованы?

Все названия тестов были пронумерованы! Все тесты имели вид TestXX_что-проверяет-тест.

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

Я узнал это на собственной шкуре, когда попробовал переставить тесты, чтобы хоть как-то почистить файл.

Если я хотел добавить новый тест, его нужно было правильно вписать в порядок. Иначе он не запускался как надо. Приходилось подбирать имя так, чтобы оно влезло в нужное место. Например, если тест должен идти между Test34_XXX и Test34_YYY, то я обязан был назвать его Test341_ZZZ, чтобы сработала лексикографическая сортировка 🤯

Анонимные тесты

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

  • test19_requirement_59_passes
  • или любимый всеми test87_process_works.

О том, что именно они проверяют, я узнавал только после того, как мои изменения ломали их. Тогда приходилось заниматься «расследованием».

Утверждения (Assertions)? Всего лишь рекомендации

В некоторых тестах не было assert’ов!
Вы спросите: что делает тест без assert’а?

А вот что: сверху в комментарии было написано что-то вроде «посмотри в лог и проверь, что там есть сообщение формата X-Y-Z».

Где искать лог, что делать при ротации логов — не уточнялось. Иногда инструкции устарели, и сообщение в логах уже давно поменялось.

Естественно, такие тесты всегда «проходили». Про них мне никто не сказал при передаче проекта, я случайно наткнулся на один из них, когда добавлял новую функциональность. Тест с гордым именем проверял уже неактуальное поведение, но, разумеется, проходил (без assert’а).

Я удалил их все и больше никогда не вспоминал.

Сложные и непонятные входные данные

Тестовые данные были весьма запутанными. Почти все тесты основывались на одном входном файле. Что в нём было — никто толком не помнил. Главное, что «этого хватает, чтобы тесты проходили».

Чтобы довести тест до нужного состояния, по коду на 3000 строк были раскиданы вспомогательные методы, которые этот input модифицировали. Они назывались вроде prepare_for_test78, и было непонятно, что именно они делают.

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

Разделяемое состояние, тянущееся между тестами

Тесты были не только взаимозависимыми, но и сама система тащила внутреннее состояние между тестами.

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

Неясная точка входа

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

Заключительные мысли

Да, это правдивая история.
Да, она немного преувеличена, но совсем чуть-чуть.

Проект долгое время находился на стадии POC (Proof of Concept, доказательство концепции), и никто не уделял ему особого внимания и приоритета до позднего этапа.

К счастью, тестируемая система была относительно простой. За исключением сложных входных данных, сама логика системы не была слишком сложной для понимания и осмысления. Это позволило работать в таких условиях.
Будь система чуть сложнее — всё могло бы быть ещё хуже.
Может, именно простота системы и позволила тестам оставаться в таком состоянии?

Мы старались исправить ситуацию, но более всего — не усугублять её. Всё новое писалось уже по высоким стандартам, а в «файл-кошмар» мы добавляли как можно меньше.

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

🔥 Какой была ваша первая зарплата в QA и как вы искали первую работу? 

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Читать в телеграм

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *