All streams
Search
Write a publication
Pull to refresh
10
0

Пользователь

Send message

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

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

В концепциях вроде "The Twelve-Factor App" про это есть даже явный пункт - Disposability. Т.е, надёжность строится на том, что процесс можно убить в любой момент, состояние вынесено наружу, старт быстрый, деградация плавная.

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

Типизацией вообще многие виды простых тестов закрыть можно.

Наверное, ревьюеры просто не поняли величия гениального подхода “пиши как нравится, а остальные потерпят”.

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

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

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

Потому что понятно, откуда ноги растут, какая там текучка и т.п.

Отличный индикатор, который экономит время соискателей.

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

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

Хотя, гораздо правильнее (и эффективнее) делать так, чтобы имена методов и интерфейсов ясно описывали поведение и намерения с целью НЕ заглядывать каждый раз внутрь реализации :)

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

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

Т.е. или есть информация что точно пригодится

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

Вот такая аналогия была бы полной.

Если у вас нет прицепа, и не планируется - это лишний вес, лишняя деталь, итд.

Лишний вес 10-20 кг для машины весом в несколько тонн? Нет, ну серьезно? :)

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

Приваренный фаркоп - это уже реализация интерфейса IФаркоп! И в вашем примере если надо что-то буксировать Вам посреди ночи придется заменить реализацию авто без фаркопа на реализацию с фаркопом

Интересное у вас восприятие :)

Фаркоп это когда к авто можно прицепить хоть прицеп, хоть трейлер через контракт IПрицеп.

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

Тестировать можно и моками

Можно и руками все тестировать :) Только зачем? Только для того чтобы не создавать интерфейс?

Если что-то удобнее тестировать и экспозировать с интерфейсами - вот в этих местах, в этот момент их и создавать

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

Какая-то не очень удачная аналогия с мостом в плане соотношения затрат времени и ресурсов :)

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

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

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

Ну, и БД и другие инфраструктурные зависимости не так уж редко имеют свойство менять лицензию или импортозамещаться :)

Если кратко, staff-инженер — это сеньорный сеньор, работающий индивидуально

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

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

Почему роль Staff инженера лидерская, хорошо описано в книге The Staff Engineer's Path за авторством Tanya Reilly.

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

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

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

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

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

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

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

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

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

А если мы не тестируем БД в юнит-тесте - тогда объясните, зачем ее мокать ?!

Мне кажется, вы обманываете сами себя. Хотите вы этого или не хотите, но каждый тест явно или неявно тестирует все зависимости, которые создаются при его инициализации. Поменялась версия драйвера БД, обновилась версия СУБД, поменялась реализация ORM библиотеки для работы с БД - все это потенциально может привести потом к падению любого теста, в котором есть даже глубоко вложенная зависимость на реальную БД.

И вот с такой логикой как у вас потом возникают проекты с десятками и сотнями тестов, которые явно или неявно тестируют ВООБЩЕ ВСЕ - реальную БД, реальные HTTP вызовы, реальные вызовы к брокерам сообщений. И авторы таких проектов гордо называют все это юнит-тестами, хотя никакие это не юнит тесты, а интеграционные. Я уже имел печальный шанс переписывать такие проекты - вносить какие-либо изменения с такими тестами это то еще "удовольствие".

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

Так что если у вас обращение к БД (HTTP/Kafka, подставить нужное) не вынесено в отдельный слой, а пронизывает весь код так, что его невозможно нормально протестировать без использования реальной БД, так это вопросы к качеству кода, а не "моки это вредно". Обратитесь к истокам, вспомните, что такое "D" в SOLID, что такое тестируемый код, и все встанет на свои места.

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

Возвращаясь к первоначальной процитированной фразе, перефразирую ее с точностью до наоборот - если мы явно не тестируем в юнит тесте БД - зачем нам там зависимость на реальную БД?

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

А проецируя пример с собакой на подходы лондонской и классической школ - лондонская школа гласит, что если мы тестируем собаку, мы тестируем только ее, в идеальных окружающих условиях. Мы не тестируем в этом же тесте хозяина, который стоит рядом, мы не тестируем в этом же тесте дорогу, на которой стоит собака - мы тестируем только собаку. То есть, мы "мокаем" все, что вокруг. И если тест сломается, мы будем знать, что проблема только в самой собаке. С классической школой мы бы вполне могли тестировать собаку со всем, что ее огружает, если это окружение не использует еще одна собака, и тест мог бы сломаться по множеству разных причин - испортилось настроение у хозяина, дорога стала скользкой, пошел дождь и т.п.

Хоть мне не нравится лондонская школа в её категоричном чистом виде, но вот у этого правила классической школы тестирования есть один огромный минус:

Тесты должны проверять единицы поведения, а не единицы кода

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

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

роль техлида зачастую не оформляется формально — сотрудник технического отдела просто берет на себя дополнительные интересные ему задачи.

...

тимлиды и техлиды в ПСБ — скорее неформальные лидеры, которые могут быть назначены на кураторство определенных факультативных задач

...

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

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

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

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity