Обновить
14
Антон Беляев@Avvero

Software Developer

8
Подписчики
Отправить сообщение

Эх кабы выдумать так, чтобы виноватыми выставить других. Вот эта была бы не сила, а силища!

А почему спрашиваете, вы - сениор?

эти тесты не проверяют внутреннюю логику и взаимодействие разных модулей

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

По моему опыту, акцент на интеграционные тесты снижал количество багов и уменьшал time to market. В итоге мы пришли к тому, что сервисы даже не запускались локально для финальной проверки через условный Postman — хватало глубоких интеграционных тестов.

ps: я не утверждаю, что юнит тесты не нужны. Отличное применение им - это проверка маперов, сложной бизнес логики, race condition проверок.

Интеграционные тесты никак не могут помешать рефакторингу, так как они не привязаны ни к дизайну кода, ни к контрактам методов и классов — в отличие от юнит-тестов. То есть интеграционный тест веб-сервиса — это отправить JSON в HTTP-эндпоинт и проверить ответ. У вас полная свобода для рефакторинга: можно даже заменить Java на Kotlin, и грамотно написанный тест вам не помешает, а наоборот — поможет, проверив контракт сервиса.

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

Теперь о фидбэке от тестов. Уточню, что речь идёт о разработке сервисов в продуктовой разработке, где фичи скорее сквозные — проходят через все слои. Есть два варианта:

  1. Если вы не используете TDD, то обратная связь от тестов игнорируется на большей части разработки. То есть это уже не та обратная связь, о которой идёт речь.

  2. Если вы используете TDD, то до этапа рефакторинга код по определению не имеет устоявшегося дизайна и структуры. Значит, юнит-тесты либо будут мешать — «цементируя» драфтовый код, либо будут фактически превращены в интеграционные.

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

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

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

Ошибочно ставить во главу угла только скорость выполнения тестов — не менее важна и глубина обратной связи. Интеграционный тест дает полноценное представление о работе приложения. Юнит-тест же сообщает лишь о корректности одного из сотен или тысяч классов и ничего не говорит о работоспособности фичи в целом.

Сильный упор на юнит-тесты ведет к цементированию кода: значимый рефакторинг становится дорогим, потому что изменение дизайна тянет за собой переписывание множества тестов. А если тесты меняются следом за кодом, можно ли им доверять? О хрупкости кода при чрезмерном использовании юнит-тестов много пишет Владимир Хориков в книге Принципы юнит-тестирования.

На мой взгляд, при тестировании микросервисов в продуктовой разработке приоритет следует отдавать интеграционным тестам. Вот хорошая статья на эту тему: https://engineering.atspotify.com/2018/01/testing-of-microservices/

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

Я предлагаю не путать уборку с перекладыванием мусора из угла в угол.

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

повторю: верная или неверная декомпозиция кода - это зависит от решаемой задачи, от контекста.

Это не так, я вполне четко указал, почему декомпозиция была не верной и чем лучше чистая функция. Чистая функция дешевле в поддержке чем нечистая, это факт.

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

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

Если бы на это было указано в статье, моих возражений бы не было. Но было ли это указано?

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

Избыточна ли эта сложность или нет - это зависит от конкретной задачи. 

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

Выбор нужного уровня абстракции - это вопрос искусства автора программы

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

хорошего работающего всегда способа ("серебяной пули") нет. 

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

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

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

Тесты - уже следующая линия обороны против ошибок, выявление и исправление ошибок тестами обходится дороже

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

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

Такой проблемы не существует, код который не несет пользы - лишний. Например предложенные вами абстракции.

И решать ее можно только творчески, для каждого конкретного случая отдельно.

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

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

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

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

Касательно ваших воображаемых ситуаций.

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

Формат сообщения в примере не специфичен для транспорта.

поскольку производный класс выступит абстрактной фабрикой

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

может несколько сгладить проблему

Подобным образом слой свежей шпатлёвки сглаживает неровности кузова машины.

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

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

она тоже вполне может абстрагироваться от обработки ошибок на нижележащих уровнях

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

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

Если уж мы начали говорить на языке эмпирических принципов, то невозможно пройти мимо старых добрых KISS и YAGNI. И вот тут хочется задать вам вопрос: а на чем основана ваша уверенность, что предложенное решение действительно необходимо? Это что, принцип ради принципа? Или, может, дизайн ради дизайна? Звучит как попытка украсить ёлку гирляндами там, где нужно просто подключить лампочку.

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

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

>Надо будет - выкинете кафку, поставите рэббита.

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

А вы опровергаете или подтверждаете тезис?

Интересно, смогут ли работодатели использовать это в своих интересах?

Идентификация и аутентификация - разные вещи.

Информация

В рейтинге
Не участвует
Откуда
Барнаул, Алтайский край, Россия
Работает в
Дата рождения
Зарегистрирован
Активность