За последние несколько лет я запилил десятки контроллеров. По итогу пришел как раз к примерно такой схеме - сервис, который обслуживает контроллер, всегда возвращает Either. Может, конечно и исключение бросить, но это всегда 500.
Сначала были исключения на все случаи, но потом оказалось, что нет надежного способа заставить в юнит тестах контроллеров из моков сервиса кидать те же исключения, что кидаются из настоящих.
Неудобно на этапе прототипа процесса пытаться писать покрывающие тесты.
Смотря как процесс тестирования организован. В моем мире с пони и бабочками процесс как маршрут тестируется отдельно, задачи - отдельно.
Проверять полноту тестов тоже не просто и не быстро.
Я даже не знаю, что ответить. А что быстро?
Может у вас другой опыт...
Мой опыт таков, что если тест можно написать - я пишу. Дешевле выйдет.
...но удобен способ обмена информацией между людьми, а не только между роботами
Вы так говорите, будто тест человек не сможет прочитать. Конечно, такие тесты бывают, но тут дело не в тесте, а в том, кто его написал. ИМХО, критерии качества кода теста не должны быть ниже, чем у продкода.
На моем текущем проекте пишем бизнес-процессы на DSL (Kotlin), правда, только для тестов. Мне нравится.
Для прода процессы пишут аналитики в своем отдельном приложении.
Предложение писать процессы на том же DSL и для прода у менеджмента восторга не вызвало. Это ж надо программистов нанимать, а они дорогие. А то, что аналитик, не будучи разработчиком, все равно делает работу разработчика, но хуже - это никого не волнует.
Чистый код — красивая архитектура. А работает ли это?
Да, работает, если на проекте трудятся люди, которые знают, что это такое и зачем оно нужно.
Если на проекте есть и другие люди - то их зону ответственности нужно изолировать таким образом, чтоб у них не было шансов нарушить общую архитектуру, чтоб их нечистый код был только их проблемой.
Хочется верить, дедлайны - это основная причина говнокода, но у меня на проекте это точно не так.
Проект начинался в режиме стартапа с очень ограниченными временными и трудовыми ресурсами. Мы работали быстро и делали много. Оценка задачам давалась с квантованием в 30 минут. Как уж тут без говнокода...
Прошло 11 лет. Народу на проекте стало больше. Начальство сменилось на разных уровнях более чем по 3 раза. Никто уже не требует былых темпов, да и не осталось никого из тех, кто помнит, как тут было принято работать раньше. Квантование оценки задачи - день. Ничего с нуля придумывать почти никогда не надо. Еще одна кнопка, еще одна форма, еще один HTTP API. Работа - не бей лежачего. Думаете, стало говнокода меньше? Нет. Только через code review и спасаемся.
79% респондентов указали, что основным барьером является нехватка времени из-за жёстких дедлайнов
Если бы опрос провели на моем проекте, я бы таким результатам не поверил. Люди пишут говнокод потому что или не могут отрефлексировать, или надеются, что code review будет выполнять не очень бдительный коллега.
С тех пор, как я стал зарабатывать больше, чем трачу, моя система такова: я знаю, какой у меня регулярный доход, знаю, сколько мне нужно денег на "обычную жизнь", т.е. на траты, которые у меня случаются каждый месяц, знаю, сколько у меня денег на счёте, что позволяет мне довольно точно прогнозировать состояние моего счета на месяцы вперёд.
Если подразумевалось, что тестировать стали не каждую функцию, а набор функций вместе, которые скрываются за той или иной формой интерфейса.
Наоборот. Декомпозировали, протестировали каждый новый компонент, плюс исходный компонент, который превратился в композицию из новых компонентов со радикально меньшей цикломатической и комбинаторной сложностью.
А вот были бы тест на контракт (рест эндпоинта, интерфейс, модуль), можно внутри сколь угодно менять модель.
Да, но чем дальше тестируемая абстракция от компонента, давшего сбой, тем больше шанс ввалить кучу времени на поиск причины сбоя.
Конечно, если само приложение компактное, условно - пара тысяч строк кода - оно и запустится быстро, и тестов много не будет - тогда можно вообще без юнит тестов обойтись, пока приложение не распухнет выше некого порога.
Еще бывает и так, что модель хорошая была и с хорошими тестами, но требования так поменялись, что большую часть переписывать нужно. И тут много маленьких тестов опять мешать будут.
Если колбасить нужно быстро, а требования нестабильны - то это совсем другое дело. Нужен не кристальный код, а одноразовое дендрофекальное поделие, единственное назначение которого - валидация требований, проверка гипотез, получение обратной связи и т.д.
Если тест тяжело писать - тестируемый код, скорее всего, не очень. Неоднократно наблюдал, как пишущего тесты страдальца спасает декомпозиция тестируемого класса. Последний реальный пример - уменьшение количества тестов с 118 до 9.
Еще частенько тесты получаются отвратными, если модель неудачная. Иногда модель нужно другую спроектировать, а иногда и специальный DSL для теста сделать, чтоб стало проще и выразительней.
Обобщая свой опыт проведения технических собеседований: задание должно быть сформулировано так, чтобы для решения требовалась не очень сложная композиция из базовых элементов и приемов, которые неизбежно закрепляются на уровне рефлексов при регулярном использовании.
Поэтому у меня на собеседовании (Java) кандидат пишет код в IDE по своему выбору, имеет право смотреть в документацию и искать в интернете, а чтоб закодить решение ему нужны только базовые компоненты JDK, а так же JUnit.
Следующим уровнем может стать обсуждение решения. Ожидается, что кандидат видит границы его применимости, рассуждает о плюсах и минусах, предлагает улучшения, альтернативу, или даже обоснованно защищает свое решение.
Я до сих пор не перестаю удивляться, насколько хорошо итоги собеседования в таком формате коррелируют с трудовыми успехами.
Уровень ложно отрицательных ошибок оценить не могу.
Ну вот. ) Хотел поделиться аналогичным опытом, но смысла уже нет - вы меня опередили. И это хорошо. Тот самый код я не имею возможности опубликовать ни по техническим, ни по юридическим причинам, мне бы пришлось его пересочинить.
Десять лет назад я создал очень похожий инструмент. Javers тогда уже существовал, но его версия была меньше чем 1.0.0, то есть не production ready.
Изначально назначение у инструмента было другое - обеспечение конкурентной работы.
Объект не сохранялся в БД напрямую. Вместо этого под распределенной блокировкой вычислялся дифф между исходной и измененной версией объекта, и далее дифф применялся к актуальной версии объекта, которая и сохранялась в БД. Сохранялись в БД и диффы, которые в дальнейшем можно было использовать при расследовании разного рода инцидентов, а так же для восстановления исторических версий объекта, которые могли быть нужны для разного рода миграций.
Таким образом, несколько юзеров могли одновременно отредактировать разные поля, одновременно сохранить объект, и ничьи изменения не терялись в результате гонки.
Опытный разработчик может возразить, что правильный способ обеспечения конкурентной работы - это команды, а не вот это вот всё поверх CRUD'а, и я с ним соглашусь.
За последние несколько лет я запилил десятки контроллеров. По итогу пришел как раз к примерно такой схеме - сервис, который обслуживает контроллер, всегда возвращает Either. Может, конечно и исключение бросить, но это всегда 500.
Сначала были исключения на все случаи, но потом оказалось, что нет надежного способа заставить в юнит тестах контроллеров из моков сервиса кидать те же исключения, что кидаются из настоящих.
Слышал, что Россия продала много нефти Индии, причем за рупии. Индийская рупия не является СКВ. То есть потратить ее можно только в Индии.
Если это правда, то другого объяснения и не нужно.
Рабство отменили. Люди увольняются потому что могут.
инвестиция в слабое звено
Смотря как процесс тестирования организован. В моем мире с пони и бабочками процесс как маршрут тестируется отдельно, задачи - отдельно.
Я даже не знаю, что ответить. А что быстро?
Мой опыт таков, что если тест можно написать - я пишу. Дешевле выйдет.
Вы так говорите, будто тест человек не сможет прочитать. Конечно, такие тесты бывают, но тут дело не в тесте, а в том, кто его написал. ИМХО, критерии качества кода теста не должны быть ниже, чем у продкода.
Это должно отлавливаться тестами.
На моем текущем проекте пишем бизнес-процессы на DSL (Kotlin), правда, только для тестов. Мне нравится.
Для прода процессы пишут аналитики в своем отдельном приложении.
Предложение писать процессы на том же DSL и для прода у менеджмента восторга не вызвало. Это ж надо программистов нанимать, а они дорогие. А то, что аналитик, не будучи разработчиком, все равно делает работу разработчика, но хуже - это никого не волнует.
Да, работает, если на проекте трудятся люди, которые знают, что это такое и зачем оно нужно.
Если на проекте есть и другие люди - то их зону ответственности нужно изолировать таким образом, чтоб у них не было шансов нарушить общую архитектуру, чтоб их нечистый код был только их проблемой.
Хочется верить, дедлайны - это основная причина говнокода, но у меня на проекте это точно не так.
Проект начинался в режиме стартапа с очень ограниченными временными и трудовыми ресурсами. Мы работали быстро и делали много. Оценка задачам давалась с квантованием в 30 минут. Как уж тут без говнокода...
Прошло 11 лет. Народу на проекте стало больше. Начальство сменилось на разных уровнях более чем по 3 раза. Никто уже не требует былых темпов, да и не осталось никого из тех, кто помнит, как тут было принято работать раньше. Квантование оценки задачи - день. Ничего с нуля придумывать почти никогда не надо. Еще одна кнопка, еще одна форма, еще один HTTP API. Работа - не бей лежачего. Думаете, стало говнокода меньше? Нет. Только через code review и спасаемся.
Если бы опрос провели на моем проекте, я бы таким результатам не поверил. Люди пишут говнокод потому что или не могут отрефлексировать, или надеются, что code review будет выполнять не очень бдительный коллега.
С тех пор, как я стал зарабатывать больше, чем трачу, моя система такова: я знаю, какой у меня регулярный доход, знаю, сколько мне нужно денег на "обычную жизнь", т.е. на траты, которые у меня случаются каждый месяц, знаю, сколько у меня денег на счёте, что позволяет мне довольно точно прогнозировать состояние моего счета на месяцы вперёд.
Наоборот. Декомпозировали, протестировали каждый новый компонент, плюс исходный компонент, который превратился в композицию из новых компонентов со радикально меньшей цикломатической и комбинаторной сложностью.
Да, но чем дальше тестируемая абстракция от компонента, давшего сбой, тем больше шанс ввалить кучу времени на поиск причины сбоя.
Конечно, если само приложение компактное, условно - пара тысяч строк кода - оно и запустится быстро, и тестов много не будет - тогда можно вообще без юнит тестов обойтись, пока приложение не распухнет выше некого порога.
Если колбасить нужно быстро, а требования нестабильны - то это совсем другое дело. Нужен не кристальный код, а одноразовое дендрофекальное поделие, единственное назначение которого - валидация требований, проверка гипотез, получение обратной связи и т.д.
Хочется вступиться за юнит-тесты.
Хороший тест - это еще и документация.
Если тест тяжело писать - тестируемый код, скорее всего, не очень. Неоднократно наблюдал, как пишущего тесты страдальца спасает декомпозиция тестируемого класса. Последний реальный пример - уменьшение количества тестов с 118 до 9.
Еще частенько тесты получаются отвратными, если модель неудачная. Иногда модель нужно другую спроектировать, а иногда и специальный DSL для теста сделать, чтоб стало проще и выразительней.
Не "искусственный интеллект", а противоестественный идиот. Зато быстрый.
Спасибо, хорошо сформулировали. )
Провожу технически интервью с лайвкодингом.
Кандидаты с ChatGPT отличаются от прочих.
Во-первых, они подтормаживают. Не сильно, но заметно.
Во-вторых, они набирают код как текст.
Обобщая свой опыт проведения технических собеседований: задание должно быть сформулировано так, чтобы для решения требовалась не очень сложная композиция из базовых элементов и приемов, которые неизбежно закрепляются на уровне рефлексов при регулярном использовании.
Поэтому у меня на собеседовании (Java) кандидат пишет код в IDE по своему выбору, имеет право смотреть в документацию и искать в интернете, а чтоб закодить решение ему нужны только базовые компоненты JDK, а так же JUnit.
Следующим уровнем может стать обсуждение решения. Ожидается, что кандидат видит границы его применимости, рассуждает о плюсах и минусах, предлагает улучшения, альтернативу, или даже обоснованно защищает свое решение.
Я до сих пор не перестаю удивляться, насколько хорошо итоги собеседования в таком формате коррелируют с трудовыми успехами.
Уровень ложно отрицательных ошибок оценить не могу.
Купил бы, если б девайс был совмещен со считывателем отпечатка пальца.
Не ложусь раньше, чем начинаю отчетливо хотеть спать.
Засыпаю хорошо, но график получается сильно плавающий. )
"Женщину вынули, автомат засунули."
Ну вот. ) Хотел поделиться аналогичным опытом, но смысла уже нет - вы меня опередили. И это хорошо. Тот самый код я не имею возможности опубликовать ни по техническим, ни по юридическим причинам, мне бы пришлось его пересочинить.
Десять лет назад я создал очень похожий инструмент. Javers тогда уже существовал, но его версия была меньше чем 1.0.0, то есть не production ready.
Изначально назначение у инструмента было другое - обеспечение конкурентной работы.
Объект не сохранялся в БД напрямую. Вместо этого под распределенной блокировкой вычислялся дифф между исходной и измененной версией объекта, и далее дифф применялся к актуальной версии объекта, которая и сохранялась в БД. Сохранялись в БД и диффы, которые в дальнейшем можно было использовать при расследовании разного рода инцидентов, а так же для восстановления исторических версий объекта, которые могли быть нужны для разного рода миграций.
Таким образом, несколько юзеров могли одновременно отредактировать разные поля, одновременно сохранить объект, и ничьи изменения не терялись в результате гонки.
Опытный разработчик может возразить, что правильный способ обеспечения конкурентной работы - это команды, а не вот это вот всё поверх CRUD'а, и я с ним соглашусь.