Re[48]: Что такое Dependency Rejection
От: · Великобритания  
Дата: 22.01.24 12:04
Оценка:
Здравствуйте, Pauel, Вы писали:

P>>>Это дополнительные издержки по сравнению с простыми функциями. Вы это сами показали на тестах календаря.

P>·>Ты просто пытаешься ввести в заблуждение. Да, у меня в тестах добавляется одна строчка кода и собственно всё. Зато в твоём решении добавляется N-строчек в _прод_ коде и требуется больше тестов. Иными словами, ты "убираешь" код, но стесняешься говорить _куда_ этот код убирается.
P>Чего стесняться — я вам прямо говорю. Переносим код связывания из размытого dependency injection в контроллер
Именно. И по итогу получается, что издержек у тебя больше, строчек кода добавляется огромная куча.

P>Это дает более простые тесты, более гибкий код, проще мейнтейнить — все что надо у вас перед носом.

Это уже вилами писано. Судя по коду который ты показывал, это не соответсвует реальности.

P>>>И у вас вполне вероятно не будет ни одной функции в джаве "удалить пользователя". А будет например "дропнуть док по хешкоду", "дропнуть записи по номеру телефона", "дропнуть сообщения по емейлу", "отозвать сертификат", "пометить спейс юзера к удалению через месяц", "подготовить выгрузку всех данных юзера", "закинуть зип на aws s3 c ttl 1 месяц"

P>·>Ну будет же где-то какой-то код, который отвечает за бизнес-действие "удалить пользователя", который в итоге сделает всё вот это перечисленное.
P>Какой то код — будет. Только с т.з. пользователя эта фича уже работает два релиза. А изменения, как пример, нужны по той причине, что удаление ресурсоемко и можно облегчить основной сервер, передав работу вспомогательному инстанцу. С т.з. пользователя изменений в функциональности нет, ни единой. А вот нефункциональные требования изменились.
P>Это я вам пример привожу, что функциональность приложения и функции в джаве это две большие разницы.
А теперь тебе осталось продемонстировать, что я когда либо утверждал что это одно и то же, или опять софистикой занимаешься? Я лишь говорил, что функциональность можно выражать в виде функций, в т.ч. и ЧПФ. Вот в твоём привёдённом "контрпримере" для "удалить пользователя", что плохого или невозможного в наличии соответствующей функции в яп и покрытии её тестами?

P>>>·>Помогать в чём? Ещё раз — инлайнинг и т.п. — это средство, а не цель. С какой целью что инлайнить-то?

P>>>Рефакторинг, очевидно. Его не раз в год нужно делать, а непрерывно — требования меняются постоянно.
P>·>Опять путаешь цель и средство. Рефакторинг — это средство.
P>Именно что средство.
Дядя Петя... на какой вопрос ты сейчас ответил? Напомню вопрос который я задал: "инлайнинг и т.п. — это средство, а не цель. С какой целью что инлайнить-то?"

P>>>Элементарно — замена вызова на константу. Это работает, т.к. str у вас иммутабельная. А вот текущее время такой особенностью не обладает.

P>·>На какую константу? Значение length() зависит от того, что лежит в данном конкретном экземляре str:
P>Length это интринсик,
Это где и с какого бодуна?

P>его сам компилятор заинлайнит, вам не надо заботиться

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

P>·> Кешированию чего? Куда прикручивается кеш — надо смотреть на полное решение, а не на данную конкретнную строчку кода. В твоём решении проблема с кешем будет в другом месте, и её решать будет гораздо сложнее. Точнее ты вообще не сможешь кеш прикрутить, т.к. аргумент now — это текущее время, ВНЕЗАПНО. Ты ключoм в кеше будешь делать текущее время??

P>·>А у меня всё круто, т.к. реализация nextFriday() знает, что это отностися к следующей пятнице, то может кешировать одно и то же значение в течение недели и обновлять его по таймеру, например.
P>Другими, вы здесь предложили наивную реализацию LRU кеша c контролем ттл по таймеру.
Угу. С нулевым изменением дизайна.

P>>>Дизайн меняется по простой причине — требования меняются непрерывно. Вот появилось нефункциональное требование "перформанс" и мы видим, что CalendarLogic сидит в hotpath и вызывается сто раз с одним и теми же значениями. Опаньки — меняем дизайн.

P>·> Не меняем дизайн, а оптимизируем внутреннюю реализацию одного метода, ну того конкретного nextFriday(). Менять дизайн на каждый чих — признак полной профессиональной некомпетенции дизайнера решения. Разуй глаза — в сигнатуре "LocalDate nextFriday()" — совершенно не говорится что откуда должно браться — считаться на лету, из кеша, запрашиваться у пользователя или рандомом генериться от погоды на марсе.
P>Запрос из кеша это изменение того самого дизайна.
Твоего дизайна — да, моего — нет.

P>Кеш, как минимум, надо инвалидировать, может и ттл прикрутить, а может и следить, что именно кешировать, а что — нет. Для этого вам нужно будет добавить кеш, настройки к нему, да еще связать правильно и тестами покрыть — что в ваш компонент приходит тот самый кеш а не просто какой то.

Кеш — это отдельный компонент.

P>>>Как это сделать в вашем случае — не ясно. Разве что прокинуть к вашему CalendarLogic еще и MRU, LRU кеш с конфигом "вот такие значения хранить пять минут". Вот уж простор для моков — теперь можно мокать не одно время, а целых три, а можно MRU, LRU обмокать.

P>·>Толи ты вообще в дизайн не умеешь, толи нарочно какую-то дичь сочиняешь, чтобы мне приписать для strawman fallacy.
P>Смотрите выше — вы сами, безо всякой моей подсказки предложили "может кешировать одно и то же значение в течение недели и обновлять его по таймеру, например" что есть тот самый кеш.
Именно. А вот ты даже это не смог предложить какого-либо работающего решения, кешировать с ключом по now — это полный бред. И вот тебе придётся для введения кеша в твоём "более гибком коде" перелопатить весь дизайн и тесты, т.к. связывание now и nextFriday у тебя происходит во многих местах и везде надо будет проталкивать этот кеш и его настройки.

P>>>Что бы просто так, без контекста — это слишком сильное утверждение. Но в целом оно отражает ваш подход к тестированию

P>·>Моки — это ещё один дополнительный инструмент в копилку. Больше инструментов — больще возможностей решить задачу более эффективно.
P>Моки в большинстве случаев морозят код, т.е. фиксируют код, бетонируют на времена. Вообще всё что вы пишете в тестах, обладает таким свойством
P>Хотите гибкости — в тесты нужно выносить самый минимум. Как правило это параметры и возвращаемое значение. Вы почему то в этот минимум добавляете все зависимости с их собственным апи.
Я не вижу в этом проблему. Ничего не бетонируется. Всё так же рефакторится. Ещё раз напоминаю, что класс с зависимостями это технически та же функция "параметры и возвращаемое значение", но с ЧПФ. Просто некоторые параметры идут через первое "применение": f(p1, p2) <=> new F(p1).apply(p2).

P>·>апи диктуется требованиями клиентского кода, а не тестами. А зависимости — это уже как мы обеспечиваем работу этого апи.

P>Если вы в юнит-тестах прокидываете мок в конструктор, то вы делаете выбор дизайна — инжекция зависимостей.
В каком-то смысле да, я некоторые "параметры" функции делаю более равными, т.к. подразумеваю по дизайну что они изменяются реже. Впрочем, оно рефакторится туда-сюда.

P>Вариантов, как обеспечить работу апи — множество. Но если вы вписали моки, то после этого варианты закончились — дизайн отлит в граните

Не отлит, всегда можно рефакторить.

P>>>Лишняя строчка

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

P>>>Вот-вот. Статься от 2011го, ссылается на книгу, которую начали писать в 00х на основе опыта накопленного тогда же.

P>·>И? Поэтому я и не понимаю как эта терминология мимо тебя прошла.
P>Я освоил тот метод именно в нулевых, задолго до той самой статьи. С тех пор много чего эволюционировало. Потому я и пишу вам, что вы продолжаете вещать из нулевых, как будто с тех пор ничего и не было.
Теперь определись — толи ты сейчас привираешь, что это тебе всё давно знакомо, толи ты просто словоблудил, выразив непонимание что я имею в виду под wiring.

P>>>Мы только что выяснили, кто же из нас двоих вещает из нулевых

P>·>Вот от твоего любимого фаулера, свежачок: https://martinfowler.com/articles/dependency-composition.html
P>Именно что свежачок. Можете заглянуть сразу в Summary
P>

P>By choosing to fulfill dependency contracts with functions rather than classes

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

P>В 00х Фаулер сотоварищи топили за тот подход, за который вы топите 20 лет спустя.

Потому что тогда он показывал это на языках 00х, а сейчас ровно то же самое показывает на typescript. Та же ж, вид в профиль. Неужели ты до сих пор не въехал в ЧПФ?!

P>>>Вы уже много раз задавали этот вопрос, и я вам много раз на него отвечал. Отмотайте да посмотрите.

P>·>Я код прошу показать, но ты упорно скрываешь.
P>Не валяйте дурака — я вам еще на прошлом заходе давал два варианта
P>1. из реквеста
P>2. руками вкидываете
P>С тех пор ничего не изменилось.
Именно. Кода как не было, так и нет. Так как если появится код, так сразу станет очевидно, что лишних строчек у тебя гораздо больше, да ещё и фреймворки какие-то требуются.

P>Собственно, вам ни один из них не нравится, потому вы здесь и выступаете. А щас вот пишете, что ничего не видели.

Именно, кода не видел, т.к. не было.

P>>>Самое важное сразу в коде метода, а не раскидано абы где по всеей иерархии dependency injection.

P>·>Субъективщина какая-то.
P>Это никакая не субъективщина. Все что функционально влияет на контроллер, должно связываться прямо в нем. А вот разная хрень пусть проходит через зависимости, ну вот сериализатор тот же.
P>Т.е. четкое разделение — функциональные вещи и технологические, а у вас в dependency injection всё подряд — "тут я шью, тут я пью, тут селедку заворачиваю"
У тебя проблема даже чётко отделить функциональные вещи от технологических... и не только у тебя. Поэтому более вменяемым и _измеримым_ критерием будет именно разделение по ресурсам — треды/файлы/сеть/etc — отделяем.

P>>>Нет, не может быть. Это вам нужно делать явно в самом контроллере, который зафейлится сразу же, на первом тесте который его вызовет.

P>·>Дык я об этом и талдычу, притом не в абы каком тесте, а конкретно в тесте который тестирует этот конкретную функцию этого конкретного контроллера. А вот в моём случае это придётся делать тоже явно в коде связывания зависимостей и зафейлится если не компилятором, то во время старта, ещё до того как дело дойдёт до запуска каких-либо тестов.
P>У вас там написание кода начинается с деплоя на прод?
Это где я такое написал? Как вообще такое возможно?!

P>Вы узнаете о проблеме во время самого деплоя!

Во время деплоя вылазят проблемы окружения куда деплоится.

P>А надо во время написания кода которые идут вперемешку с прогном быстрых тестов, и это все за день-неделю-месяц до самого деплоя!

Ну чтобы какой-либо тест прогнать — надо стартовать некий код... не? Вот до выполнения первого попавшегося @Test-метода оно и грохнется, где-нибудь в @SetUp.

P>·>Они не "нужны". Есть другие подходы, которые покрывают эти же кейсы (по крайней мере, подавляющее большинство), но не требуют прогона тестов.

P>Я и вижу — тестируете деплоем на прод.
Не знаю где ты это увидел, имеется в виду мы тестируем прод окружение пытаясь деплоить на прод. Вы, кстати, тестируете уже после деплоя на прод.

P>>>Согласно бл. А вы как собираетесь отличать два разных вызова, клиентский от серверного? Вам для этого придется намастырить кучу кода с инжекцией в конструктор, только всё важное будет "где то там"

P>·>Я уже раза три рассказал. Клиентский и серверный будут иметь разный ожидаемый результат.
P>Ну вот вам и ответ.
Напомню вопрос: А как ты будешь такой и-тест писать, если у тебя будет Time.Now? Что ассертить-то будешь? Как отличать два разных вызова Time.Now — клиентский от серверного?
Вот пришло тебе в ответе в неком поле значение "2024-01-23". как ты в и-тесте отличишь, что это вычислилось от вызова Time.Now на серверной стороне, а не на клиентской?

P>>>Теоретически — можно. Практически — первый интеграционный тест сваливается, когда вызывает этот контроллер.

P>·>Если этот тест не забудут написать, конечно. Покрытие-то ты анализировать отказываешься...
P>Вы совсем недавно делали вид, что понимаете как покрытие работает. А сейчас делаете вид, что уже нет. Покрытие говорит что код вызвался во время теста. Но никак не говорит, какие фичи пройдены.
P>Нам нужны именно фичи, кейсы, сценарии. В строчках кода это не измеряется. Смотрите, как это делают QA.
Как ты убедишься, что некая фича покрыта тестами? Или что все фичи и разные corner cases описаны в бизнес-требованиях? Покрытие хоть и ничего не гарантирует, но часто помогает обнаружить пробелы.

P>·>И как это проверишь в тесте?

Ты в очередной раз проигнорировал неудобный вопрос.

P>·>И я написал почему в твоём коде это неочевидно на ревью.

P>Это вам неочевидно, т.к. вы топите за другой дизайн. Комбинирование функции в общем случае проще композиции классов. Классы никуда не денутся — одно другому помогает.
Неочевидно потому что у тебя код так выглядит, а дизайн какой — пофиг.

P>>>Через параметры функции. Дизайн то плоский, а не глубокий, как у вас.

P>·>Через параметры значения передаются. Откуда они возьмутся-то?
P>А вы не видите? Весь код перед глазами.
Ты показывал код, нет, там этого не видно.

P>·>У тебя точек привязки — в каждом месте использования nextFriday и никак не тестируется вообще.

P>Еще раз — точки привязки это часть интеграции, которая тестируется интеграционным тестом. Интеграционные тесты не тестируют кусочки "время прокинуто метод класса куда прокинута бд куда прокинут репозиторий".
P>Вместо этого интеграция проверяет последовательность, которая вытекает из требований:
P>- зарезервировать столик на трех человек на имя Коля Петров на следующую пятницу 21.00
Этот пример совершенно никак не отностися к обсуждаемому нами методу nextFriday. Или у тебя в твоём дизайне будет семь методов nextMonday...nextSunday?

P>·>У меня "дешевые" в том смысле, что они выполняются очень быстро. Так вот даже "полу-интеграционные на моках" — выполняются очень быстро, за минуты всё. А у тебя "дешевые" — выполняются полтора часа, но называешь их "дешевыми" так просто, потому что тебе так их нравится называть, без объективных на то причин.

P>Вы, похоже, без телепатии жить не можете. Вы спросили, сколько времени идут тесты. Я вам ответил, еще и добавил, это все тесты, всего-всего, всех видов. Но вам всё равно телепатия ближе.
P>Юнит тесты — пару минут от силы. Их до 15тыс ориентировочно.
С учётом того, что они у вас тестируют имена функций и буквальный текст запросов, то толку от них — не больше нуля.

P>Остальных — от 1000 до 5000 и они занимают 99% времени.

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

P>>>Рефакторинг, оптимизации.

P>·>Рефакторинг это тоже не задача. А инлайнить для оптимизаций только самые ленивые компиляторы в режиме дебага не умеют.
P>Большинство компиляторов умеют инлайнить только тривиальные вещи. Расчищать hot path это по прежнему ваша забота
Так ведь и большинство IDE умеют инлайнить только тривиальные вещи. И на практике обычно получается так, что компилятор может заинлайнить больше, чем IDE. Если в твоём nextFriday будет много кода, с вспомогательными приватными функциями, несколькими точками return, etc, — то IDE тебе скажет: "упс!".

P>>>Эта кучка называется data complexity. Я, например, билдером могу гарантировать, что данные будут запрашиваться постранично. Или что всегда будет фильтр по времени, где период не более трех месяцев.

P>·>Не очень понял, как гарантировать и что именно? И почему то же самое нельзя гарантировать другими способами? И вообще это всё больше похоже на бизнес-требования, чем на проверки каких-то кейсов в тестах.
P>Это и есть тот, другой способ, основаный на метапрограммировании. Главное, что тесты основаные на проверке выборки из бд этот вопрос принципиально не решают, т.к. мы не знаем, что даст ваш запрос на каких других данных, которых у вас нет.
P>Не нравится метапрограммирование — можете придумать что угодно.
И что? Причём тут тесты-то?

P>>>Соответсвено тестами можно проверить что структура запроса та, что нам надо

P>·>Ой. Очень интересно увидеть код как ты проверишь тестами по структуре запроса, что у тебя билдер что-то гарантирует.
P>Я ж вам показал идею. Или вы ждёте тьюринг-полного выхлопа, который умеет еще и мысли читать по вашей методике?
Идея вида "мышки станьше ёжиками", "за всё хорошее против всего плохого". А конкретный код _теста_ — осилить не можешь.

P>·>Я не знаю на какой вопрос ты ответил, но я напомню что я спрашивал: "Как запрос может что-то сказать?". Контекст выделил жирным выше.

P>Вы там ногой читаете? Запрос не человек, сказать не может. А вот ревьюер может сказать "у нас такого индекса нет, тут будет фуллскан по таблице из десятков миллионов записей с выполнением регекспа и время работы на проде надо ждать десятки минут"
Или у вас неимоверно крутые ревьюверы, помнят наизусть сотни таблиц и тысячи индексов, или у вас хоумпейдж. Не все могут себе такое позволить.

P>>>Я вам выше рассказал. Нужна гарантия, что не вернется вдруг чего нибудь не то. Вариантов "не того" у вас по скромной оценке близко к бесконечности.

P>·>Как ты это предлагаешь _гарантировать_? И причём тут тесты?
P>Это ж вы сунете тесты туда, где они не работают.
Это ты словоблудием занимаешься. Мы обсуждаем именно тесты, а ты тут в сторону доказательного программирования и мета уходишь.

P>Как гарантировать — см пример номер 100500 чуть выше

Где чуть выше?

P>>>Вы топите за косвенные проверки запросов, тестируя связку репозиторий+бд. Вот этого оно и есть.

P>·>Я топлю за то как надо писать тесты, чтобы от них была хоть какая-то польза и поменьше вреда. А не абстрактные "проверки" которые что-то должны "гарантировать" посредством говорящей рыбы запроса.
P>Ага, за всё хорошее против всего плохого
Я пальчиком в конкретные места твоего кода тыкнул где плохо и как сделать хорошо. Про "всё" — это твои фантазии опять.

P>>>Пользователи ожидают, что на их данных, которых в ваших тестах нет, будет нужный результат.

P>·>Если ожидания есть, то какая проблема их добавить в тесты?
P>У вас данных нет. Или вы щас скажете, что у вас уже есть все данные всех юзеров на будущее тысячелетие?
И как тобой предложенное "in: [fn1]" решает эту проблему? Или ты опять в сторону разговор уводишь?

P>>>Вашими тестами эта задача не решается

P>·>Я показал как решение этой задачи можно тестировать моими тестами. Ты так и не рассказал как она решается вашими тестами.
P>Я сказал, что тестами эта задача не решается.
Напомню контекст. Мы сравниваем ваши тесты с моими. Я показал проблемы в ваших тестах, и показал как эти проблемы решить моими. И ты тут заявил, что моих теста есть проблемы, т.к. они не решают задачи, которые не решаются тестами. Вау!

P>Собственно, вы раз за разом утверждаете, что с разработкой алгоритмов не знакомы. Мало накидать реализацию и тесты — нужно обосновать и доказать корректность.

strawman fallacy это называется, господин словоблуд.

P>>>Не нужно сводить всё к бл напряму. У вас технологического кода в приложении примерно 99%. Он к бл относится крайне опосредовано — через связывание. А тестировать эти 99% тоже нужно.

P>·>Именно. Ты меня обвинил в том, что у меня тесты тестируют детали реализации, а на самом деле ты просто с больной головы на здоровую. Но зато у тебя дизайн самый модный!
P>Наоборот.
Ваша цитата: Ага, тесты "как написано" Вам придется написать много больше, чем один тест — как минимум, пространство входов более-менее покрыть. Моками вы вспотеете это покрывать.

P>Это вы пишете что я тестирую те самые детали, которые тестировать, по вашему, не надо.

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

P>·>Зато есть возможность покрыть известные данные и комбинации тестами. Вы и этого не делаете, а просто имена приватных функций ассертите и буковки сравниваете (тоже, кстати известные). Вот и приходится часами билдить и в проде тесты гонять чтобы хоть что-то как-то обнаружилось.

P>Зачем вам собеседник, если у вас отличный дуэт с вашей телепатией?
В каком месте тут телепатия? Билд занимающий часы — это твои слова. И тесты в проде — тоже.

P>>>Вот оптимизацию такой вещи закрыть тестами, что бы первый же фикс не сломал всю цивилизацию

P>·>Это всё круто. Каким образом твоё "in: [fn1]" обеспечивает тебя всем множеством данных которое может приходить от юзеров?
P>Такой тест гарантирует, что всё множество данных будет проходить именно через эту функцию.
Не гарантирует. В коде может быть написано "if(thursdayAfterRain())return {...in: [fn42]...}" и тест это не может обнаружить. Ещё раз — тесты ничего не могут гарантировать.

P>И если я знаю, что у неё нужные мне свойства(тестами не решается), то результат будет обладать нужными мне свойствами. Например, если функция никогда не возвращает null, то вы можете и не бояться "а вдруг там всё таки null" и сократить hot path

Наивный юноша.

P>>>В интеграционном тесте можно сделать то же самое.

P>·>Как? Код в студию. Вот в куче кода кучи контроллеров где-то у тебя написано Time.Now. Как ты это проверишь в интеграционном тесте что некий результат содержит именно что-то вычисленное от Now, а не что-то другое?
P>Я вам привел пример про Колю Петрова. Надеюсь, справитесь
Опять врёшь. Это не код.

P>·>Не это, а то что вначале мы использовали серверное время, а потом вдруг стали использовать клиентское — это изменение функциональное, т.к. источники времени — принципиально разные и влияют на наблюдаемый результат. Если бы было время клиентское изначально, то никаке функциональные тесты не пострадают.

P>Нет, это не функциональное изменение. Мы просто перенесли процессинг в очередь. С точки зрения пользователя ничего не изменилось.
Я это и сказал. Если тут всё равно серверное время, то да, не функциональное, и тесты не пострадают. Тесты сломаются и должны сломаться если ты заменишь источник серверного времени на источник клиентского времени.

P>·>А ещё я кофе моими тестами сварить не смогу. Что сказать-то хотел?

P>·>Напомню, мы сравниваем тестирование ожиданий бизнес-требований твоими тестами с "in: [fn1]" vs моими тестами c "save/find". Так причём тут метапрограммирование?
P>Я вам объяснил уже много раз. Вы точно понимаете, что такое метапрограммирование?
Я не понимаю какое отношение метапрограммирование имеет к бизнес-требованиям и к тому как писать тесты.

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

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

P>>>Тогда можно сравнить выхлоп, тот или не тот.

P>·>Так я тебя и спрашиваю как ты будешь сравнивать выхлоп зависящий от Time.Now — тот он или не тот?
P>Смотрите пример про Колю Петрова
Не нужен мне пример. Мне нужен код.

P>>>Этим протаскиванием вы бетонируете весь дизайн. Смена дизайна = переписывание тестов.

P>·>Нет.
P>Вы прибили контролер к тестам на моках. А тут надо процессинг вытеснить в очередь. Приплыли.
Ну выплывайте.

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

P>·>Обычные тесты не могут тестировать перф. А детали реализации лучше не тестировать.
P>Детали реализации нужно покрывать тестами, что бы первый залётный дятел не разрушил всю цивилизацию:
P>- оптимизации
Это перф-тесты.

P>- трудноуловимые баги

P>- секюрити
P>- всякие другие -ility
P>- любой сложный код, где data complexity превышает ваше капасити
Это "за всё хорошее, против всего плохого". А секьюрити — это бизнес-требование и обязано быть покрыто фукнциональными тестами.

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

P>·>Ты не понял. Надо тестировать не метапрограммирование, а ожидания.
P>Вы снова решили в слова поиграть.
"Метапрограммирование тестируется" — зачем? Если я какую-то реализацию какого-то метода захочу изменить с/без метапрограммирования — с какго бодуна я должен переписывать тесты? В этом и суть — меняем _реализацию_ логики с/без меты — тесты остаются ровно те же и должны остаться зелёными.

P>>>Неэффективно. Для многих приложений час невалидной работы может стоит любых денег. Дешевле запустить тесты на проде — час-два и у вас информация по всем функциям.

P>·>Ну никто нам не позволит делать "тестовые" сделки на прод системах. Каждая сделка — это реальные деньги и реальная отчётность перед регуляторами. Так что "информацию по всем функциям" нам приходится выдавать ещё до аппрува релиза.
P>Вы не просто утверждаете это, а идете дальше — утверждаете, что тесты прода это признак наличия багов, не той квалификации и тд.
Признак более позднего обнаружения багов.

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

Ок, для хоумпейджей можно хоть левой пяткой писать, неважно.

P>>>Вы снова включили телепатию. Сертификат может обновиться не у вашего приложения, а у какого нибудь из внешних сервисов. Мониторинг вам скажет, когда N юзеров напорются на это и у вас начнет расти соответсвующая метрика.

P>·>Нет, мониторинг нам скажет, что сессия с таким-то сервисом сломалась и свистайте всех на верх.
P>А у вас один юзер в день что ли? Пошел трафик, а потом вжик — идут фейлы.
На это и придумали healthchecks (а конкретно liveness probe), проверка, что сервис — operational, явно проверяет себя и свои зависимости, что может отрабатывать трафик без фейлов ещё до того как пошли реальные запросы.

P>·>Такое — major incident и соответствующий разбор полётов с пересмотром всех процессов — как такое допустили и определение действий, чтобы такое больше не произошло.

P>Какой процесс вас застрахует от фейла на другой стороне которую вы не контролируте?
Большая тема. Начни отсюда: https://en.wikipedia.org/wiki/High_availability

P>>>У вас есть иллюзия, что ваши тесты гарантируют отсутствие лишнего выхлопа на данных, которые у вас отсутсвуют.

P>·>У меня такой иллюзии нет, ты опять насочинял, я такое нигде не писал. О гарантиях в тестах фантазировать любишь только ты.
P>Вы же топите за тесты и утверждаете, что они чего то там решают. Ниже пример этого
Решают проблемы в _твоих тестах_.

P>>>

P>·>Угу, вот так вот просто.
P>Вот этот самый пример — вы здесь утверждаете, что тестами решите проблему с data complexity. Или пишете тесты непонятно для чего, или же не в курсе data complexity
Где здесь? Цитату, или опять соврамши.

P>·>Ну я хотя бы могу начать допиливать этот самый swagger, чтобы генератор таки стал понимать.

P>·>А у тебя всё гораздо хуже. Ты пишешь аннотации, конфиги, тенантов, реализацию, веб-сервер, потом у тебя наконец-то http-запрос выдаётся этот же самый swagger по этим аннотациям, который ВНЕЗАПНО ни один генератор кода не понимает. И это реальная ситуация, которую помнится уже обсуждали пару лет назад и твоим решением было "ну пусть клиенты пишут всё ручками", т.к. перепилить свои аннотации и http-запрос ты уже не сможешь, ибо проще пристрелить.
P>Вы наверное с кем то меня путаете. Я ни призывал писать всё руками. С аннотациями похоже снова дело в вашей телепатии. Я ж вам сказал — они для конкретных кейсов. Кодогенерация дает медленный цикл разработки. В некоторых кейсах это можно сократить на недели и месяца. Я привел вам примеры но вы как обычно прошли мимо
Кодогенерация сама по себе медленный цикл разаработки не даёт. Любой кодогенератор работает от силы порядка минут.

P>>>Вы похоже не читаете. Какой смысл вам что либо рассказывать?

P>>>1. когда стартуем проект, где центральная часть это АПИ. Идем через design-first, формат файла и расширение — любое, см. выше
P>>>2. готовый проект — уже поздно топить за design-first, просто генерим артефакты
P>>>3. переписываем проект на rust — снова, нам design-first не нужен, это вариация предыдущего кейса
P>·>Не понял, как из 1 получилось 2?
P>Никак — это разные кейсы.
Ну я за 1 и не люблю 2, а 3 это следствие 2, т.к. "прыгают, а не думают". Об чём спор-то?

P>·>Ага, верно, проще прыгать чем думать. Не спорю.

P>У нас кейс "переписать апи на rust" был 0 раз за 10 лет. Смена технологий от балды — тоже 0 раз. А у вас иначе, каждый месяц всё с нуля на rust переписываете?
C++, kotlin, java, groovy, scala (может ещё что забыл)... И таки да, спеки всё-таки есть в виде FIX или хотя бы avro/protobuf. А когда копадаются другие команды/внешине сервисы с подходом "нагенерим из аннотаций" — вечная головная боль интегрироваться с такими.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.