10 октября 2021 г.

Тестирование конфигурации: aftermath через 5 лет

Пару лет назад я увлекался темой тестирования конфигурации – проверку конфигурации приложений оффлайн, перед выкладкой на рабочие сервера, с помощью юнит-тестов. Эту идею к нам в проект принес Андрей Сатарин, позже я применил ее более масштабно в другом проекте, и рассказывал об этом опыте на Гейзенбаге 2018.

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

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

Aftermath у меня получается такой: даже через 3-5 лет после внедрения, даже в не очень динамично развивающихся проектах – тесты конфигурации остаются полезными. В CI довольно регулярно видны ошибки, находимые этими тестами – то есть даже хорошо знающие проект разработчики все еще нередко ошибаются в каких-то деталях конфигурирования, и тесты эти ошибки подсвечивают до развертывания.

Я и сам перед уходом конфигурировал ряд новых инстансов приложения, и обучал других конфигурировать новые инстансы – в обоих случаях я сильно опирался на мной же написанные тесты конфигурации. Инструкция конфигурирования новых инстансов, которой я пользовался, и которую советовал другим, по-сути звучит как "сделайте начальные шаги 1-2-3, а потом запустите тесты конфигурации, и исправляйте обнаруженные ошибки" – и конфигурация, которая прошла тесты, в большинстве случаев заводилась на рабочих серверах без проблем.

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

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

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

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

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

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

…с другой стороны: то же самое можно сказать про добрые 30%-50% кода, который я встречал в жизни. Так что, может быть, это еще и довольно неплохой результат :)

2 комментария:

  1. 1. Битая ссылка в первом абзаце
    2. Не совсем понятно, почему собственно сообщения assert тестов с ходу не проинтерпретировать, может просто информативные ошибки со ссылками на документацию упростили бы процесс.
    Хотя, скорее всего, это уже все сделано и просто контекста не хватает для понимания сложности.
    Почему это сложно поддерживать тоже непонятно, ну еще пачка специфических тестов, а-ля очередной контекстный dsl просто чтобы меньше наступать в runtime.
    3. Теоретически, можно наверное и config as a code какой-нибудь написать, чтобы просто компиляцию ломать в попытке написать что-то явно не то, а конктанты и convention тривиальными модульными проверками закрыть (но это просто мысль в первую минуту).
    4. может проблема не столько с тестами сколько с самим проектом, если конфиг сложно писать, который скорее всего явно не ракету в космос запустить.

    ОтветитьУдалить
    Ответы
    1. 1. Спасибо, поправил -- потерялась l в .html

      2. Сообщения в assert конечно дают подсказки. Но эти подсказки для человека со стороны все равно оставляют много вопросов. Ссылки на документацию конечно упростили бы дело -- только подробной справочной документации по конфигам нет, есть только операционные инструкции (HowTo).

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

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

      3. Да, конфиги в виде DSL поверх компилируемого языка -- уже способны отсечь многое из того, что сейчас проверяется тестами. Плюс обычные тесты полученного DOM способны проверить остальное.

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

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

      Так-то да: тесты конфигурации в том виде, в котором я их описывал в своей презентации -- это костыль. Способ заткнуть дырку, возникшую из-за того, что оригинальный автор/архитектор системы не продумал масштабирование/валидацию конфигурации. Но такое очень часто случается, поэтому костыль актуален.

      4. О, мне кажется, с любым проектом, который живет дольше пары лет -- есть масса проблем :)

      Удалить